Cs5002 Lect9 Fall18 Notes
Cs5002 Lect9 Fall18 Notes
1
Lecture 9: November 8, 2018
Instructors: Adrienne Slaughter, Tamara Bonaci
Disclaimer: These notes have not been subjected to the usual scrutiny reserved for formal publications.
They may be distributed outside this class only with the permission of the Instructor.
Introduction to Algorithms
9.1 Overview
1. foo
The goal with asymptotic analysis is to try to find a bound, or an asymptote, of a function. This allows
us to come up with an “ordering” of functions, such that one function is definitely bigger than another,
in order to compare two functions. We do this by considering the value of the functions as n goes to
infinity, so for very large values of n, as opposed to small values of n that may be easy to calculate.
Once we have this ordering, we can introduce some terminology to describe the relationship of two
functions.
9-1
9-2 Lecture 9: November 8, 2018
Growth of Functions
nn
4096
n!
2048
1024
512
2n
256
128
n2
64
32 n log(n)
16
n
8 √
4 n log(n)
2
1
1
2 3 4 5 6 7 8
√
1 log n n n n log(n) n2 2n n! nn (9.1)
Complexity Terminology
Θ(1) Constant
Θ(log n) Logarithmic
Θ(n) Linear
Θ(n log
n) Linearithmic
Θ nb Polynomial
Θ(bn ) (where b > 1) Exponential
Θ(n!) Factorial
Definition 9.1 (Big-O: Upper Bound) f (n) = O(g(n)) means there exists some constant c such
that f (n) ≤ c · g(n), for large enough n (that is, as n → ∞).
We say f (n) = O(g(n))
Example: I claim 3n2 − 100n + 6 = O(n2 ). I can prove this using the definition of big-O:
Lecture 9: November 8, 2018 9-3
Proving 9.7:
We also know this to be true because order is transitive: if f (n) = O(g(n)), and g(n) = O(h(n)), then
f (n) = O(h(n)). Since n2 = O(n3 ), then any f (n) = O(n2 ) is also O(n3 ).
Proving 9.8:
Definition 9.2 (Big-Omega: Lower Bound) f (n) = Ω(g(n)) means there exists some constant c
such that f (n) ≥ c · g(n), for large enough n (that is, as n → ∞).
We say f (n) = Ω(g(n)) or “f of n is Big Omega of g of n”
9-4 Lecture 9: November 8, 2018
Example: I claim 3n2 − 100n + 6 = Ω(n2 ). I can prove this using the definition of big-Omega:
Proving 9.21:
Proving 9.22:
Definition 9.3 (Big-Theta: “Tight” Bound) f (n) = Θ(g(n)) means there exists some constants c1
and c2 such that f (n) ≤ c1 g(n) and f (n) ≥ c2 g(n).
We say f (n) = Θ(g(n)) or “f of n is Big-Theta of g of n”.
Definition 9.4 (Theta and “order of ”) When f (x) = Θ(g(x)), it is the same as saying f (x) is the
order of g(x), or that f (x) and g(x) are the same order.
3n2 − 100n + 6 = Θ(n2 ) Both O and Ω apply
Lecture 9: November 8, 2018 9-5
c c
(logb n) is O nd , but nd is not (O (logb n) )
(9.30)
This tells us that every positive power of the logarithm of n to the base b, where b ¿ 1, is big-O of every
positive power of n, but the reverse relationship never holds. In Example 7, we also showed that n is
O(2n). More generally, whenever d is positive and b ¿ 1, we have
This tells us that every power of n is big-O of every exponential function of n with a base that is greater
than one, but the reverse relationship never holds. Furthermore, we have when c ¿ b ¿ 1,
This tells us that if we have two exponential functions with different bases greater than one, one of these
functions is big-O of the other if and only if its base is smaller or equal.
These statements express the notion that the largest term of the statement is the dominant one. For
example, n3 + 2n2 + 3 = O(n3 ).
Example: Prove that n2 = O(2n ).
9-6 Lecture 9: November 8, 2018
Example: Prove that if f1 (n) = O(g1 (n)) and f2 (n) = O(g2 (n)), then f1 (n) + f( n) = O(g1 (n) + g2 (n)).
Example:
√
Example: If f (n) = n + log n + n, find a simple function g such that f (n) = Θ(g(n)).
Lecture 9: November 8, 2018 9-7
Summary
• f (n) = O(g(n)) means c · g(n) is an upper bound on f (n). Thus there exists some constant c such
that f (n) is always ≤ c · g(n), for large enough n (i.e., n ≥ n0 for some constant n0 ).
• f (n) = Ω(g(n)) means c · g(n) is a lower bound on f (n). Thus there exists some constant c such
that f (n) is always ≥ c · g(n), for all n ≥ n0 .
• f (n) = Θ(g(n)) means c1 · g(n) is an upper bound on f (n) and c2 · g(n) is a lower bound on f (n),
for all n ≥ n0. Thus there exist constants c1 and c2 such that f (n) ≤ c1 · g(n) and f (n) ≥ c2 · g(n).
This means that g(n) provides a nice, tight bound on f (n).
• Correct
• Efficient in time
• Efficient in space
• Example algorithms
– Binary Search
– Selection Sort
• Algorithm Analysis
– Proving Correctness (briefly)
– Run time: How long does it take for an algorithm to run?
– Run space: How much extra memory/storage does an algorithm require?
• Asymptotic Analysis and Growth of Functions
Expressing Algorithms
We need some way to express the sequence of steps in an algorithm.
• English
• Graphically
• Pseudocode
• real programming languages (C, Java, Python, etc)
An algorithm is an idea. If the idea is not clear when you express the algorithm, then you are using a
too low-level way to express it.
Searching
Input: A set of N values: n1 , n2 , n3 , . . . , nn and a target value t
Imagine...
A (sub) roster of athletes on the USA Olympic Ski & Snowboard team for 2018:
Lecture 9: November 8, 2018 9-9
1 Andy Newell
2 Bryan Fletcher
3 Chloe Kim
4 Jessie Diggins
5 Lindsey Vonn
6 Sadie Bjornsen
7 Sophie Caldwell
8 Taylor Fletcher
1 Binary-Search(A, I, 1, numElems)
Quick Review
1. I stated the problem
2. I described a solution in English (using a metaphor)
3. I described the solution with psuedocode
4. I provided a graphical solution
Selection-Sort(A, B)
1 for i = 1 to A. length
2 min ind = 0
3 for j = 1 to A.length
4 if A[j] < A[min ind]
5 min ind = j
6 B[i] = A[min ind]
7 A[min ind] = Inf
The C code
1 void selection_sort(int a[], int b[], int len){
2
3 for (int i=0; i<len; i++){
4 int min_ind = 0;
5 for (int j=0; j<len; j++){
6 if (a[j] < a[min_ind]){
7 min_ind = j;
8 }
9 }
10 b[i] = a[min_ind];
11 a[min_ind] = 10000; //sentinel val
12 }
13 }
9.4 Analysis
What is Algorithm Analysis?
When we analyze algorithms, we are analyzing for 3 things:
Lecture 9: November 8, 2018 9-11
1. Correctness
2. Run time
3. Run space
9.4.1 Correctness
Proving Correctness
How to prove that an algorithm is correct?
For any algorithm, we must prove that it always returns the desired output for all legal instances of the
problem.
For sorting, this means even if the input is already sorted or it contains repeated elements.
Proof by:
• Induction
• Counterexample
• Loop Invariant
Proof by Counterexample Searching for counterexamples is the best way to disprove the cor-
rectness of a heuristic.
• Think about small examples
• Think about examples on or around your decision points
• Think about extreme examples (big or small)
Proof by Induction
Failure to find a counterexample to a given algorithm does not mean “it is obvious” that the algorithm
is correct.
Mathematical induction is a very useful method for proving the correctness of recursive algorithms.
1. Prove base case
2. Assume true for arbitrary value n
3. Prove true for case n + 1
Proof by Loop Invariant
Built off proof by induction.
Useful for algorithms that loop.
1. Find p, a loop invariant
2. Show the base case for p
3. Use induction to show the rest.
• Best Case
– Given an optimal input and all the best decisions that can be made, how many steps until the
algorithm terminates?
– In a sort problem, it’s usually a sorted input.
• Worst Case
– Given the worst possible input and all the worst decisions that can be made, how many steps
until the algorithm terminates?
– In a search problem, it’s usually the last item looked at.
• Average Case
– Somewhere between the two; frequently an averaging of best & worst.
Run Time of Selection Sort
Selection-Sort(A, B)
1 for i = 1 to A. length. // n
2 min ind = −1 // 1
3 for j = 1 to A.length // n
4 if A[j] < A[min ind] // 1
5 min ind = j // 1
6 B[i] = A[min ind] // 1
7 A[min ind] = Inf // 1
Actually, for Selection Sort, there’s no difference in run time for Best/Worst/Average case.
In all cases, we still iterate through all the elements.
⇒ O(n2 )
Run Time of Binary Search
Lecture 9: November 8, 2018 9-13
Best case:
Binary-Search({1, 2, 3}, 2, 1, 3)
Worst case:
R(n) = 1 + 1 + 1 + R(n/2)
R(n) = O(lg n)
PrintFoobar(n)
1 for i = 1 to n/2
2 for j = i to n − 1
3 for k = 1 to j
4 Print(’foobar’)
Assume n is even. Let T (n) denote the number of times ‘foobar’ is printed as a function of n.
9-14 Lecture 9: November 8, 2018
Number of Instructions
= Number of Seconds (9.38)
Instructions Per Second
The number of instructions is measured in terms of n, the size of the input to the algorithm. While (for
the most part) the number of instructions is about the same from machine to machine, what varies is
the number of instructions per second that are run. This gives us 3 variables: number of instructions,
instructions per second and number of seconds to run the algorithm. Therefore, if we know 2 we can
calculate the third.
Here’s an example: Let’s say I’ve implemented Selection-Sort on my MacBook Pro. I know Selection-
Sort takes n2 instructions to run. I choose to run it on an input length of 10,000 items. It takes 2 clock
seconds to run (this is a number I’m choosing for illustration purposes; that’s way too long!).
Number of Instructions
= Number of Seconds (9.39)
Instructions per Second
n2
= 2 seconds (9.40)
Instructions Per Second
10, 0002
n = 10, 000 : = 2 seconds (9.41)
x Instructions per Second
10, 0002 instructions
= x = 50 MIPS2 (9.42)
2 seconds
2 Millions of Instructions per Second. For reference, the iPhone 6 was probably around 25,000 MIPS (in 2014).
Lecture 9: November 8, 2018 9-15
Thus, if we know our algorithm has n2 instructions, and we measure that it takes 2 seconds to run on
our machine with an input of 10,000 items, then our machine runs at about 50 MIPS.
Further, now that we know our machine runs at 50 MIPS, we can use that to estimate how long it will
take to run a different algorithm (that is, different run time) or different input size.
Let’s say we have one million items as input to the same algorithm:
Let’s take two relatively recent machines. One is powered by the Intel Core i7 500U which runs at 49,360
(roughly 50K MIPS), and the other is an Intel Core i7 2600K at 117,160 MIPS.
Runtime Size of Input Intel i7 A Intel i7 B
1000 3 1000
n 1,000 50,000 MIPS = 0.02µsec 117,000 MIPS = 0.009µsec linear
10000
10,000 50,000 MIPS = 0.2µsecs
1,000,000 1,000,000
1,000,000 50,000 MIPS = 20µsecs 117,000 MIPS = 8.5µsecs
1000 log 1000 3000 3000
n log n 1000 50,000 MIPS = 50,000 MIPS = 0.06µsec 117,000 MIPS = 0.03µsec logarithmic
10000
1000000 log 1000000 6,000,000 6,000,000
1,000,000 50,000 MIPS = 50,000 MIPS = 120µsec 117,000 MIPS = 51.3µsec
2
2 1000 10002
n 1000 50,000 MIPS = 20µsecs 117,000 MIPS = 8.5µsecs quadratic/
10000
1,000,000
250 1,125,899,906,842,624 250
cn 50 50,000 MIPS = 50,000,000,000 = 22518µsecs 117,000 MIPS = 9623µsecs4 exponentia
10000
1,000,000
Run Time, Summary
• We count up the number of statements that are run.
• Consider whether there’s a difference in how long it takes a function to run given different inputs.
• Selection sort is O(n2 ), pretty much all the time.
• Binary search can be either O(1) or O(lg n), depending on what the input looks like.
Selection sort:
Needs a whole other array! O(n)
Note: this is just how it was implemented here, in this discussion. If we chose not to use that other
array, it wouldn’t be O(n).
time
• A graph G = (V, E) is bipartite if the nodes V can be partitioned into sets X and Y in such a way
that every edge has one end in X and the other in Y .
• It’s just a graph, but we tend to depict bipartite graphs in two columns to emphasize the bipartite-
ness.
1 1
2 2
3
3
4
4
5
5
6
6
Bipartite Matching
• Bipartite Matching is relevant when we want to match one set of things to another set of things.
– Nodes could be Jobs and Machines; Edges indicate that a given machine can do the job.
– Nodes could be men and women; Edges indicate that a given man is married to a given woman.
(Okay, in the real world it’s more complex, but this is a classic “problem” I feel required to
present...)
Solution: use backtracking and augmentation to solve the problem, which contributes to network
flow problems
Independent Set
Independent Set is a very general problem:
• Given a graph G = (V, E), a set of nodes S ⊆ V is independent if no two nodes in S are joined
by an edge.
• Goal: Find an independent set that is as large as possible.
• Applicable to any problem where you are choosing a collection of objects and there are pairwise
conflicts.
1 2
3 4 5
6 7
• Example: Each node is a friend, and each edge indicates a conflict between those two friends. Use
Independent Set to find the largest group of people you can invite to a party with no conflicts.
• Interval Scheduling is a special case of Independent Set:
– Define graph G = (V, E) where V is the set of requests or intervals, and E is the set of edges
that indicate conflicts between two requests.
• Bipartite Matching is a special case of Independent Set:
– A little more complex than I want to explain in class; see the book and we’ll cover it later.
• Solution: No efficient algorithm is known to solve this problem.
• However: If we’re given an independent set for a given graph G, we can easily check that it’s a
correct answer.
Competitive Facility Location
This time, we have a two-player game.
• Dunkin Donuts puts a cafè at one location.
• Then Starbucks does.
• BUT! Cafès can’t be too close (zoning requirement)
• Goal: Make your shops in the most convenient locations as possible.
• Model the problem:
– Consider each location as a zone (rather than a point) that has an estimated value or revenue.
– Model the problem as a graph: G = (V, E) where V is the set zones as noted above, and E
represents whether two zones are adjacent.
– The zoning requirement says that the set of cafès is an independent set in G.
10 1 15 5 1 15
9.7 Logarithms
9.7.1 Definition
What is a logarithm?
bx = y
m
logb (y) = x
log7 (49) =?
⇒ 7? = 49
⇒ 72 = 49
⇒ log7 (49) = 2
9.7.2 Properties
Special Logs
• Base b = 2: binary logarithm, also referred to as lg x
• Base b = e: natural logarithm, also referred to ln x, where e = 2.718.....
– The inverse of ln x is exp(x) = ex
⇒ exp(ln x) = x
• Base b = 10: The common logarithm, also referred to as log x.
• If it’s not one of these, the base is specified.
Restrictions
logb (a) is only defined when b > 1 and a > 0.
Practice: Use what you know about exponents to convince yourself why this is true.
The Product Rule
loga (xy) = loga (x) + loga (y)
Lecture 9: November 8, 2018 9-21
3 + log7 x = 8 − 4 log7 x
5 log7 x = 5
log7 x = 1 (9.45)
x = 71 = 7
k = {7}
(b)
5 + log x
x>0
3 − log x
2= 8
x>0
5+log x
3−log x =3
5 + log x = 9 − 3 log x
4 log x = 4
(9.46)
log x = 1
x = 101 = 10
K = {10}
9-22 Lecture 9: November 8, 2018
(c) log4 x2 − 9 − log4 (x + 3) = 3
x2 − 9
log4 = log4 64
x+3
x2 − 9
= 64
x+3
(x − 3)(x + 3)
= 64
x+3
x = 67 ∈ (3, 00)
x = {67}
Summary
A 2 3 7 9 2 4 8 5 1 6