Lecture2 Algorithms-Complexity REV
Lecture2 Algorithms-Complexity REV
Lecture 2
Algorithms & Algorithm Complexity
References:
Sait & Youssef Appendix A
1
Part 1: Algorithms (Searching, Sorting) and Algorithm Complexity
An algorithm is a set of well-defined steps to accomplish a given task.
used to accomplish a task. Often we can minimize one of these only at the expense of
the others. Usually time is the most important resource to minimize. We will focus on
time here.
We will consider the worst case time for a given algorithm over all possible inputs (for
example, for all possible sets of N integers). We will describe the worst case time by
using the order of or big O notation
2
Definition: big-O notation. A theoretical measure of the execution of
an algorithm, usually the time or memory needed, given the problem
size n, which is usually the number of items. Informally, saying some
equation f(n) = O(g(n)) means it is less than some constant multiple of
g(n) for all n. https://xlinux.nist.gov/dads/HTML/ bigOnotation.html
a. 17n + n3
b. 56n5logn
c. 54n1/2
d. 4n
e. n3 + 3n4log10n
For a given algorithm, we want to find how many time units it takes for the
algorithm to execute on a set of a specific size. This can depend on how
the data is stored. (most pseudocode below is from Wikipedia, sometimes
slightly modified)
5
Task 1. Searching. Given a set of N integers and an integer X, is X a member of the set?
Example: recall array A: items are stored in consecutive memory locations, 1 st array item is at A[0]
(hw OR sw)
PO 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
S
VA 1 2 11 4 5 6 19 10 21 3 13 14 8 17 7
L
We can implement this as a for loop, with a few extra statements before and after the loop. In the worst
case, the for loop will execute N times. So this is an O(N) algorithm.
6
Task 1. Searching. Given a set of N integers and an integer X, is X a
member of the set?
Recursive version:
LinearSearch(value, array)
if the array size is 0, return -1;
else
if the first item of the array has the desired value, return its location;
else return LinearSearch(value, remainder of the array)
7
Task 1. Searching. Given a set of N integers and an integer X, is X a member of the set?
Case 2. Given a SORTED array of integers, is there an algorithm to search for X that has complexity less than O(N)?
Answer: YESbinary search (an example of a divide and conquer algorithm):
Exercise 4. How many steps will this algorithm take for N a power of 2? In general, what is f(N) so that binary search is O(f(N) )?
(aside if you like math: we say an algorithm has time complexity T(n) which is o(n), if for all c > 0 there exists some k > 0 such that 0 f(n) < cg(n)
for all n k.
https://xlinux.nist.gov/dads/HTML/littleOnotation.html) 8
Task 2. Sorting. We assume we have an array A of N integers. We want to sort the array so that is in
ascending order. (Complexity will be the same if we choose descending order). We will look at 3
algorithms.
Exercise 5. Show the steps if the original array looks like: 7,6,5,4,3.
Exercise 6. Based on the results of Exercise 5, explain why the (worst case) time complexity of this algorithm for an
array of N elements is O(N2).
9
Task 2. Sorting. We assume we have an array A of N integers. We want to sort the array so that is in ascending order.
(Complexity will be the same if we choose descending order). We will look at 3 algorithms.
Algorithm 2. Bubble sort
procedure bubbleSort( A : list of sortable items )
N = length(A)
repeat
swapped = false
for i = 1 to N-1 inclusive do
/* if this pair is out of order */
if A[i-1] > A[i] then
/* swap them and remember something changed */
swap( A[i-1], A[i] )
swapped = true
end if
end for
until not swapped
end procedure
Exercise 8. Based on the result of Exercise 7, explain why the (worst case) time complexity for this algorithm is O(N 2).
Exercise 9. How ling does the algorithm take to run for the array 7,3,4,5,6?
10
Remark. Bubble sort is actually a very efficient algorithm if an array is already mostly in order . In that case, it will take time O(N).
Task 2. Sorting. We assume we have an array A of N integers. We want to sort the array so that is is in ascending order.
(Complexity will be the same if we choose descending order). We will look at 3 algorithms.
Algorithm 3. Quicksort.
Quicksort is a good general-purpose sorting algorithm for an array. It is usually described recursively. It has worst case time complexity O(N 2) but
AVERAGE time complexity O(NlogN). So in general it will be quicker than the other sorts we have looked at here.
algorithm quicksort(A, lo, hi) is
if lo < hi then
p := partition(A, lo, hi)
quicksort(A, lo, p 1)
quicksort(A, p + 1, hi)
algorithm partition(A, lo, hi) is
pivot := A[hi]
i := lo // place for swapping
for j := lo to hi 1 do
if A[j] pivot then
swap A[i] with A[j]
i := i + 1
swap A[i] with A[hi]
return i
Exercise 10. Demonstrate the steps in quicksort for the array 7,3,6,4,8,5,9,1
Exercise 11. To get a feel for the advantage of using quicksort over insertion sort or bubble sort, make a table of the values of N and NlogN for N =
1,2,,10
Remark. It can be proved mathematically that for a an array sorting algorithm that uses comparisons to sort, the best (worst case) time complexity
we can achieve is O(NlogN). There are sorting algorithms, heapsort, and mergesort, which can achieve this time, but the constant for heapsort is
bigger than that for quicksort and mergesort takes more memory, so quicksort is generally the preferred sort for an array that is not known to be
mostly sorted already. 11
NOTE: this slide is corrected
Part 2: Computational complexity
Classes of problems:
P: Polynomial time--problems that can be solved in time polynomial in the problem size on a
(deterministic) Turing machine
examples: search an array of size N: O(N)
sort an array of size N: O(N2)
12
Why is this distinction important?
Example: comparison of values for a problem of size N (source: http://bigocheatsheet.com/ )
N Nlog2N N2 2N N!
4 8 16 16 24
Examples:
8 24 64 256 40320
16 64 256 65536 20922789888000
32 160 1024 4294967296 ???
64 384 4092 18446744073709551616 ???
12 896 16384 3402823669209384634633746074317682 ??? 13
8 11456
Most problems we encounter in VLSI Design Automation are constrained optimization problems which are in the NP-hard
class.
Example: how many ways are there to partition a set of 2N vertices into 2 subsets of equal size?
Choose N vertices from 2N vertices: special case of choose k elements from a set of n elements,
So, for example. If n = 220 and k = n/2 or 219, then there are 524288 possible choices for the two sets.
If we add the condition that the n points are vertices in a graph and we want the number of edges between the two sets to be minimal, we have an
example of a partitioning problem of the type we need our design automation tools to solve.
14
In practical terms, we cannot find a polynomial-time algorithm to solve such a
problem.
NOTE: please read SY appendix A to find out more about NP-hard and NP-
complete problems.
Problem statement: Given a Boolean circuit written as a product of sums for Boolean variables X 1, X2,, ,
Xn, decide whether there is an assignment of values {0,1} to X 1, X2, , Xn such that the output from the
circuit is 1.
There is no known polynomial-time algorithm that will solve this problem (i.e., give an answer in time
proportional to nk for a fixed k for ANY possible input).
What we can do in polynomial time: if we are given specific values for X 1, X2, , Xn, we can determine in
polynomial time IF these specific values give an output of 1.
Satisfiability is also NP-complete, i.e., if we could find a polynomial-time algorithm to solve the
satisfiability problem, we would be able to find a polynomial-time algorithm for any other NP-complete
problem.
NP-hard: These are at least as hard as NP problems. They do NOT have to be in NP.
Since the problems we will look at are NP-hard, we will need benchmark sets to test the quality of the
16
solutions we come up with.