AA Overview

Download as pdf or txt
Download as pdf or txt
You are on page 1of 22

Algorithmic Analysis Overview:

Running Time Analysis,


Correctness, Exhaustive Search
CMPSC 463 Design and Analysis of Algorithms
Dr. Truong X. Tran (Ph.D.)
Topics
• Reasoning about Algorithms
• Time and Space Complexity
• Exhaustive Search
What is an Algorithm
• Definition: An algorithm is a finite set of precise instructions for performing a
computation or for solving a problem.
• Take some value as input and produces some values as output.
• Input: An algorithm has input values from a specified set.
• Output: From the input values, the algorithm produces the output values from a
specified set. The output values are the solution.
• Correctness: An algorithm should produce the correct output values for each set
of input values.
• Finiteness: An algorithm should produce the output after a finite number of steps
for any input.
• Effectiveness: It must be possible to perform each step of the algorithm correctly
and in a finite amount of time.
• Generality: The algorithm should work for all problems of the desired form.
Designing and Analyzing Algorithms
• Designing: Multiple techniques to design an algorithm:
• Increment (induction)
• Divide-and-Conquer (recursion)
• Analyzing: resources that the algorithm requires
• Properties of algorithms
• Time and space complexities.
Data Structures: a Review
All running times are worst case (WCRT), unless otherwise specified
Linked List
• Prepend: O(1)
• Search: O(n)
• Access the kth element of the list: O(k)
Array
• Search: O(n)
• Access the kth element of the array: O(1)
Sorted Array
• Search: O(log n)
Dynamic array: where we double the size of the array every time it fills up
• Append: O(n) WCRT, O(1) amortized running time
Data Structures: a Review
Binary Search Tree
• Search: O(n) WCRT, O(log n) average case running time (assuming that items are inserted in a random order)
• Insert: same as search
• Delete: same as search
Balanced Search Tree (e.g. 2-3 tree)
• Search, Add, Delete: O(log n)
Min-Heap
• Min: O(1)
• Add: O(log n), Delete: O(log n)
• MakeHeap (Create a heap from an array of n elements): O(n)
Hash Table
• Search: O(1) average case running time, if the load factor is bounded above by a constant, O(n) WCRT
• Add: O(1), Delete: same as search
Space and Time Complexity
Performance measure of algorithms
• Space: Memory requirement
• Time: Running Time
This course focus mainly on: Running time complexity
• Worse case running time
• Average case running time
• Best case running time
All running times are worst case (WCRT), unless otherwise specified
Analyze time complexity:
• Determine the number of operations with respected to the input’s size
• Number of the operations as a function, f(n), of the size,n, of the input
• How fast f(n) grows as the size of input grows
• To compare the efficiency of two algorithms when solving the same problem.
• The faster grows of f(n), the slower the algorithm can solve a problem
Growth of Functions: O-notation

8
Growth of Functions: ꭥ-notation

9
Growth of Functions: Θ-notation

10
Display of Growth of Functions

Note the difference in behavior of functions as n gets


larger
Useful Big-O Estimates Involving Logarithms, Powers, and
Exponents
If d > c > 1, then
nc is O(nd), but nd is not O(nc).
If b > 1 and c and d are positive, then
(logb n)c is O(nd), but nd is not O((logb n)c).
If b > 1 and d is positive, then
nd is O(bn), but bn is not O(nd).
If c > b > 1, then
bn is O(cn), but cn is not O(bn).
Exhaustive Search
• A brute-force algorithm
• Examining all possible paths for a valid solution.
• Suitable for small and well-defined search space.
Problem: Traveling salesman
• Given n cities with known distances between each pair, find the
shortest tour that passes through all the cities exactly once before
returning to the starting city.
• Example:
Exhaustive Search Model
• Choosing
• We generally iterate over decisions. What are we iterating over here? The iteration
will be done by recursion.
• What are the choices for each decision? Do we need a for loop?
• Exploring
• How can we represent that choice? How should we modify the parameters?
• Do we need to use a wrapper due to extra parameters?
• Un-Choosing
• How do we un-modify the parameters from step 3? Do we need to explicitly un-
modify, or are they copied? Are they un-modified at the same level as they were
modified?
• Base Case
• What should we do in the base case when we're out of decisions?
Problem: print all binary
• Input: A positive integer n.
• Return: print all binary number of n bits
• Exhaustive Search: Examining all binary of n bits
void printBinary(int n) {
helper(n, " ");
}
void helper(int n, string bits) {
if (n == 0) {
cout << bits<< endl;
} else {
helper(digits - 1, bits + "0");
helper(digits - 1, bits + "1");
}
}
printBinary(2)
Problem: Subset Sum
• Input: An array with n integers and k.
• Return: whether there is a subset of integers that adds up to k
• Exhaustive Search: Examining all Subsets
static boolean subsetSum(int[] values, int k) {
return helper(values, 0, k);
}

static boolean helper(int[] values, int nextNdx, int sum) {


if (nextNdx == values.length) {
return (sum == 0);
}
return helper(values, nextNdx + 1, sum - values[nextNdx]) ||
helper(values, nextNdx + 1, sum);
}
Subset sum example
Output all subsets with sum k
static void subsetSum(int[] values, int k) {
boolean[] included = new boolean[values.length];
helper(values, 0, subset, k);}
static void helper(int[] values, int nextNdx, boolean[] included, int sum) {
if (nextNdx == values.length) {
if (sum == 0) {
for (int i = 0; i < values.length; i++) {
if (included[i])
System.out.print(" " + values[i]);
}
System.out.println();
}
return;
}
included[nextNdx] = true;
helper(values, nextNdx + 1, included, sum - values[nextNdx]);
included[nextNdx] = false;
helper(values, nextNdx + 1, included, sum);}
Problem: Generating all Strings
• Input: A string containing an alphabet, and an integer n
• Return: A dynamic array with all of the strings of length n using symbols from the alphabet
static ArrayList<String> generateStrings(String alphabet, int n) {
ArrayList<String> result = new ArrayList<>();
helper(result, alphabet, "", n);
return result;}
static void helper(ArrayList<String> strings, String alphabet, String prefix,
int charsRemaining) {
if (charsRemaining == 0) {
strings.add(prefix);
return; }
for (int i = 0; i < alphabet.length(); i++) {
helper(strings, alphabet, prefix + alphabet.charAt(i), charsRemaining - 1);
// charsRemaining--?
}
}
Computational Intractability
Problems that cannot be solved in polynomial time I.e. not constant k
for which the running time of the solution is in O(n^k)
• Can only solve small instances of the problem
• Seen exhaustive search approaches for this
• ONE OF CENTRAL IDEAS IS HOW TO IMPROVE ON EXHAUSTIVE
SEARCH…
• Find polynomial time algorithms
• If not, squeeze performance out of super-polynomial algorithms
• Accept “good enough” solutions to problems