1 - To - 5 - Lecture Notes
1 - To - 5 - Lecture Notes
INTRODUCTION
1.1 ALGORITHM
Algorithm originates from the name of Latin translation of a book written by
al-khwarizmi a Persian mathematician. The book was entitled: “Algoritmi de
numero Indorum”. The term “Algoritmi” in the title of the book led to the
term “Algorithm”. In mathematics and computer science, an algorithm is a
step-by-step procedure for calculations.
An algorithm is an effective method for finding out the solution for a
given problem. It is a sequence of instructions that conveys the method to
address a problem. Algorithm is the basis for any program in computer
science. Algorithm helps in the organization of the program. Every program
is structured and follows the specified guidelines and algorithm gives steps
for the program. A problem can be solved by means of logical induction but
in order to implement it in the form of a program, we require an appropriate
algorithm.
Formal Definitions
Definition 1: Step by step procedure to solve a problem is called Algorithm.
Definition 2: A countable set of instructions followed to complete the
required task is called an algorithm.
Definition 3: An algorithm is a finite set of instructions to do a particular
task.
Various criteria are considered to evaluate an algorithm among which the
essential ones are as follows:
1. Input: The algorithm should be given zero (or) more inputs
explicitly. (≥ 0)
1
2 Design and Analysis of Algorithms
The solution can be expressed as a set of assertions about the input and
output variables and also as expression in predicate calculus. If these two
forms are proved to be equivalent, then it is a correct solution. Once the
algorithm is built, next we have to prove its correctness. Usually validation
is used for proving correctness of the algorithm i.e., it should be tested by
proving all possible combinations of the inputs. Some of the techniques used
for generating the inputs are:
1. Boundary Value Technique: In Boundary Value Technique, if the
correct value of a Variable is 10, it is tested by giving values in and
around 10. (ex. 9,9.5, 10.5,11 etc.,)
2. Equivalence Partitioning: In Equivalence Partitioning, the i/p is
divided into different groups and tests the algorithm to work
satisfactorily by giving values from these groups.
3. Random Generation: Random Generation will test the algorithm by
generating set of input values in random.
Analysis of an algorithm: Analyzing an algorithm involves study of data
storage and processing of data which are performed by a computer. It
measures the evaluation time of an algorithm and space required by it.
Analysis is required to compare the performance of algorithms.
Algorithm analysis involves synthesizing a formula or guessing the
fastness of algorithm depending upon the size of the problem it operates.
Size of the problem can be
(a) Number of inputs/outputs in an algorithm.
E.g., For a multiplication algorithm, the numbers to be multiplied
are the inputs and the product of the numbers is the output.
(b) Total number of operations involved in algorithm:
E.g., To find the minimum of all the elements in an array the number
of comparisons made among the elements is the total number of
operations.
Algorithm testing: Testing of an algorithm involves debugging and
profiling. Debugging refers to finding out errors in the results and correcting
the problem. Profiling refers to the measurement of performance of a correct
program when executed on a data set. This includes calculation of time and
space required for computation.
Coding an algorithm: After successful completion of all the phases, then an
algorithm is converted into program by identifying a suitable computer
language.
Introduction 5
repeat-until:
repeat
<statement-1>
.
.
.
<statement-n>
until<condition>
8. A conditional statement has the following forms.
If <condition> then <statement>
If <condition> then <statement-1>
Else <statement-2>
Case statement:
case
{
: <condition-1> : <statement-1>
.
.
.
: <condition-n> : <statement-n>
: else : <statement-n+1>
}
9. Input and output are done using the instructions read and write.
10. A single procedure exists which is of the form: Algorithm.
the heading takes the form,
Algorithm Name ___ of __ Algorithm (List of Parameter)
As an example, the following algorithm calculates first ‘n’ natural
numbers and returns the result:
Algorithm
1: Algorithm Sum(n) // n is number of natural numbers
2: {
3: NumSum:=0
4: for i:= 1 to n do
5: NumSum:= Numsum + i
6: return NumSum;
7: }
Algorithm
1: For i := 1 to n do
2: {
3: Examine x[i] to x[n] and suppose the smallest
element is x[min];
4: swap x[i] and x[min];
5: }
Algorithm
1: Algorithm selection sort (x, n)
2: // Sort the array x[1:n] into non-decreasing
//order.
3: {
4: for i:=1 to n do
5: {
6: min:=i;
7: for k:=i+1 to n do
8: if (x[k]<x[min]) then min:=k;
9: temp:=x[i];
10: x[i]:=x[min];
11: x[min]:=temp;
12: }
13: }
Algorithm
1: Algorithm TOH(n, s, d, a)
2: {
3: If (n>=1) then
4: {
5: TOH(n-1,s,a,d);
6: Write(“move top disk from tower”, s, “to top of
tower”, d);
7: TOH(n-1,a,d,s);
8: }
9: }
Thus, the destination consists of three disks satisfying the above rule.
Analysis:
Number of disks = 3
Number of times disk 1 moved = 22 = 4
Number of times disk 2 moved = 21 = 2
Number of times disk 3 moved = 20 = 1
Total number of moves = 23 – 1 = 7
Note: Number of movements of each disk is in power of 2
moves=(pow(2,disk)-1);
printf(“Number of moves needed are : %d\n”,moves);
Towers(disk,’s’,’d’,’a’); getch();
}
Algorithm
1: Algorithm perm(a,k,n)
2: {
3: if(k=n) then write (a[1:n]); // output permutation
4: else //a[k:n] ahs more than one permutation
5: // Generate this recursively.
6: for i:=k to n do
7: {
8: t:=a[k];
9: a[k]:=a[i];
10: a[i]:=t;
11: perm(a,k+1,n);
12: //all permutation of a[k+1:n]
13: t:=a[k];
14: a[k]:=a[i];
15: a[i]:=t;
16: }
17: }
14 Design and Analysis of Algorithms
1.5.1 Efficiency
Efficiency of an algorithm depends upon the amount of resources utilized by
the algorithm. A maximum efficient algorithm will exhibit the property of
minimal resource utilization and vice versa. Though two algorithms are
designed to solve same problem, they may have different efficiencies.
For example, consider a problem of sorting ‘n’ elements. If an Insertion
sort technique is adopted to solve this problem, it takes an approximate time
equal to C1n2 (C1 is constant). If the same problem is solved using Merge
sort technique, it takes C2 n log2 n units of time (C2 is constant). For small
inputs Insertion sort is better than merge sort. But for larger inputs Merge
sort is better than Insertion sort because its running time grows more slowly
with increase in input size compared to that of Insertion sort (i.e., n log n
grows more slowly than n2)
Analysis of algorithm is the study of algorithm i.e., calculating the time
and space complexity. Analysis of algorithms is of two types Priori analysis
and posteriori analysis.
1.5.4 Complexity
Complexity is the time taken and the space required for an algorithm for its
completion. It is a measurement through which one can judge the quality of
an algorithm and can be used for finding and sorting out better algorithms.
Complexity can be classified into two types. Normally:
1. Space complexity 2. Time complexity
16 Design and Analysis of Algorithms
1 2 3 4 5 6 7 8 9
10 20 15 08 20 30 50 40 25
Let us assume in above program, there are ‘k’ statements enclosed in the
for loop and statement taken one unit of time for execution. Hence the
execution of ‘k’ statements requires ‘k’ units of time. If these ‘k’ statements
are executed ‘n’ times, then execution time is n*k units.
Hence order of magnitude of above algorithm = n*k units.
Introduction 19
1. Few examples for finding out number of steps using step count method:
Example:
Algorithm Sum()
{
read (a,b,c,d); ← 1 unit
x=a+b+c+d; ← 1 unit
write(c) ← 1 unit
} -------------
3 units
-------------
The above algorithm has Four inputs, output and number of steps are
three.
Step count =3;
2. Finding the sum of n numbers stored in the array a “n” is known as
instance characteristics (input size):
Algorithm Sum(a,n)
{
sum:=0.0; ← 1 unit
for i:=1 to n do ← n+1 unit
sum:=sum + a[i]; ← n unit
write(sum); ← 1 unit
} -------------
2n+3 units
-------------
Step count = 2n + 3
3. Read n values from keyboard find their sum and average:
Algorithm Avg( )
{
sum:=0.0; ← 1 unit
Read n; ← 1 unit
for i:=1 to n do ← n+1 unit
{
Read num; ← n unit
Sum=sum + num; ← n unit
}
Avg=sum/n ← 1 unit
Write(sum, avg); ← 1 unit
}
-------------
3n+5 units
-------------
Step count = 3n + 5
20 Design and Analysis of Algorithms
Solution: T(n) = 1 n = 0
T(n) = T(n – 1) + b n>0
Step count method for C programs:
1. main( )
{
int a,b,c;
scanf(“%d%d”,&a,&b); ← 1 unit
c=a+b; ← 1 unit
printf(“%d”,c) ← 1 unit
} ------------
3 units
------------
Step count = 3;
2. main( )
{
int n;
printf(“enter a number”); ← 1 unit
scanf(“%d”, &n); ← 1 unit
for(int i=0;i≤n;i++) ← 2n+2 unit
printf(”shyam”); ← n unit
} --------------
3n+4 units
-------------
Step count = 3n + 4;
consider only the leading term of the formula (eg. an2) since the lower order
terms are relatively insignificant for large n.
We also ignore the coefficient of the leading term, Since they are less
significant then the rate of growth.
This study of growth functions are called Asymptotic analysis of
algorithm, and they are denoted by Asymptotic notations.
This asymptotic notation contains five types they are as follows.
1. Big-Oh Notation(O-Notation)
2. Omega Notation(Ω-Notation)
3. Theta Notation (Θ Notation)
4. Little –oh Notation(o-Notation)
5. Little omega Notation (ω-Notation)
1.5.5.1 Big‐Oh Notation (O‐ Notation)
Big –Oh notation denoted by ‘O’ is a method of representing the upper
bound or worst case of algorithm’s run time. Using big-oh notation, we can
give longest amount of time taken by the algorithm to complete.
Definition: Let f(n) and g(n) are two non-negative functions. The function
f(n) = O(g(n)) if there exist positive constants n0 and c such that
f(n) ≤ c*g(n) for all n, n>n0.
→ Means order at most
→ Used to measure the worst case time complexity.
Find Big oh for the following functions:
1. f(n)=2n2 + 3n + 1
f(n) = O(g(n))
f(n) <= cg(n) n>=n0
2n2 + 3n + 1 <= 1 false
2n2 + 3n + 1 <= 3n false
2 2
2n + 3n + 1 <= n false
2n2 + 3n + 1 <= 2n2 false
2n2 + 3n + 1 <= 3n2 true for n > = 4
f(n)<=3n2
f(n) = O(n2) where c = 3 and n0= 4
2. f(n) = 5n + 4 n > = n0
5n + 4 < =4 false
5n + 4 < = 5n false
5n + 4 < = 6n true for n > = 4
f(n)= O(n) where c = 6 and n0 = 4
Introduction 23
3. f(n) = 10n3 + 6n2 + 6n + 2
10n3 + 6n2 + 6n + 2 < = 11n3 n > = 7
f(n) = O(n3) where c = 11 n0 = 7
Consider the function f(n) = 2n + 2 and g(n) = n2 we have to find constant
c so that f(n) ≤ g(n), in other words 2n + 2 ≤ n2 then we find that for n = 1 or
2, f(n) is greater than g(n) that means for c = 1 when n = 1, f(n) = 4 and g(n)
= 1, for n = 2, f(n) = 6 and g(n) = 4. When n ≥ 3 we obtain f(n) ≤ g(n).
Hence f(n) = O(g(n))
5n + 2 = Ο(n) as 5n + 2 < = 6n for all n > = 2.
109n + 6 = Ο(n) as 109n + 6 < = 110n for all n > = 6.
13n2 + 6n + 2 = Ο(n2) as 10n2 + 4n + 2 < = 14n2 for all n > = 6.
4*2n + n2 = Ο(2n) as 4*2n + n2 < = 5*2n for n > = 4.
Various meanings associated with Big-Oh are
O(1) - Constant computing time
O(n) – Linear
O(n2) – Quadratic
O(n3) – Cubic
O(2n) – Exponential
O(logn) – Logarithmic
The relationship among those
computing time is 0 (1) < 0
(logn) < 0 (n) < 0 (n2) < 0 (2n)
O(2n) – rate of growth is very
high (algorithm takes slower)
O(log n) – rate of growth is very less (algorithm takes faster)
3n + 2
E.g., The function 3n + 2 = o(n2) since lim =0
n →α n2
f(n) = 3n + 2
f(n) < c g(n)
3n + 2 < n2 n>=4
3n + 2
lim =0
n →α n2
3n + 2 = o(n2)
1.5.5.5 Little Omega Notation (ω‐Notation)
Little omega notation is used to denote proper lower bound that is not
asymptotically tight.
Let f(n) and g(n) are two non-negative functions. The function
f(n) = w(g(n)) if there exist positive constants n0 and c such that
f(n) > c*g(n) for all n, n > n0 .
g(n)
lim =0
n →α f (n)
n
Ex: The function n2 + 6 since lim =0
n →α n +6
2
f(n) = n2 + 6
26 Design and Analysis of Algorithms
n2 + 6 > ω(n)
We say that f(n) is asymptotically smaller than g(n) if f(n) = o(g(n)), and
f(n) is asymptotically larger than g(n) if f(n) = ω(g(n)).
One property of real numbers, however, does not carry over to asymptotic
notation:
Trichotomy: For any two real numbers a and b, exactly one of the following
must hold: a < b, a = b, or a > b, but all functions cannot be asymptotically
comparable.
Any two real numbers can be compared, but not all functions are
asymptotically comparable. Let f(n) and g(n) are two non-negative functions,
a special case may exist for which neither f(n) = O(g(n)) nor f(n) = Ω(g(n))
are satisfied. For example, the functions n and n1+ cos n cannot be compared
using asymptotic notation, since the value of 1 + cos (n) rotates between 0
and 2, taking on all values in between.
if f(n) = O(g(n)) and h(n) = O(g(n)) then f(n) + h(n) = O(max(g(n), d(n)))
if f(n) = O(g(n)) and h(n) = O(g(n)) then f(n) * h(n) = O(g(n) * d(n))
if f(n) = O(g(n)) Then a*f(n) = O(g(n)) where ‘a’ is constant.
1.5.6.1 Time Complexity of Program Segments with Loops
1. for i :=1 to n
s;
complexity: O(n)
2. for i:=1 to n
for j:=1 to n
s;
complexity: O(n2)
3. i=1, k=1;
While(k<=n)
{
i++;
k=k+i;
}
complexity: O( 2 )
4. for (i=1; i*i <=n;++i)
S;
complexity: O( 2 )
5. j=1;
while(j<=n)
{
j =j*2;
}
complexity: O(log n)
28 Design and Analysis of Algorithms
6. for i:=1 to n/2
for j:=1 to n/3
for k:=1 to n/4
s;
complexity: O(n3)
7. for i:=1 to n
for(j=1; j<=n; j=j*2)
s;
complexity: O(n log n)
8. for i:=1 to n
for j:=1 to n
for k:=1 to n
{ s;
break;
}
complexity: O(n2)
f(n) = O(n2)
n = O(n2) It will fall in Case 1. So that
2
T(n) = θ(n )
2. T(n) = 4T(n/2) + n2 n>1
T(n) = 1 n=1
From the above recurrence relation we obtain
a = 4, b = 2, c = 1, d = 1, f(n) = n2
nlogba = n2
f(n) = θ(n2)
n2 = θ(n2)
It will fall in case 2.
T(n) = θ(n2log n)
3. T(n) = 4T(n/2) + n3 n>1
T(n) =1 n=1
From the above recurrence relation we obtain
a = 4, b = 2, c = 1, d = 1, f(n) = n3
nlogba = n3
f(n) = Ω(nlogba + €)
= Ω(n2 + €)
n3 = Ω(n2 + €)
This will fall in case 3.
T(n) = θ(n3)
4. T(n) = 2T(n/2) + n n>1
T(n) =1 n=1
From the above recurrence relation we obtain
a = 2, b = 2, c = 1, d = 1, f(n) = n
nlogba = nlog22 = n
f(n) = θ nlogba)
= θ(n)
It will fall in case 2.
T(n) = θ(n log n)
‘O(n)’. When we implement that clearable table with an array. Note that the
actual running time of operation may be much higher than the amortized
running time.
For example, a particular clear operation may take ‘O(n)’ time.
The advantage of using amortization is that it gives us a way to a robust
average case analysis without using any probability.
Amortized complexity: In amortized complexity we change sum of the
actual cost of an operation to other operation. The amortized cost of each
insertion is no more than 2 and that of each deletion is no more than 6.
The actual cost of any insertion or deletion is no more than ‘2 * I + 6 *
D’.
Amortized means finalizing the average run time per operation over a
worst case sequence of operations.
Note: The only requirement is that the sum of the amortized complexity of
all operations in any sequence of operations be greater than or equal to their
sum of actual complexity.
∑ am ortized (i) ≥ ∑ actual(i)
1 <= i <= n 1<= i <= n
1 2 3 4 5 6 7 8 9
10 20 15 08 20 30 50 40 25
1 2 3 4 5 6 7
10 15 20 21 40 45 70
Solution:
f(n) = 2n
⇒ f(n) = O(2n)
g(n) = n!
⇒ g(n) = O(n!)
h(n) = nlog n
⇒ h(n) = O(nlog n)
The Asymptotic order of the function is as follows 1 < log log n < log n <
ne < nc < nlogn < cn < nn < ccn < n!
Where 0 < ∈ < 1 < c [n < n2 means n grows more slowly than n2]
So nlogn < cn < n!
nlogn < 2n < n!
Assume C = 2
h(n) < f(n) < g(n)
From the above relation we can arrive at h(n) ∈ O(f(n)) and
g(n) = O(f(n))
7. Consider the Quick sort algorithm. Suppose there is a procedure for
finding a pivot element which splits the list into sub-lists each of which
contains at least one-fifth of the elements. Let T(n) be the number of
comparisons required to sort n elements. Then
(a) T(n) ≤ 2T(n/5) + n (b) T(n) ≤ T(n/5) +T(4n/5)+ n
(c) T(n) ≤ 2T(4n/5) + n (d) T(n) ≤ 2T(n/2) + n
Answer: (b)
Solution:
If we want to sort n elements with the help of quick sort algorithm. If
pivot elements which split the lists into two sub lists each in which one
list contains one-fifth element or n/5 and other list contains 4n/5 and
balancing takes n so
T(n) ≤ T(n/5) ≤ T(4n/5) + n
[Note: n – n/5 = 5n – n/5 = 4n/5]
8. The running time of an algorithm is represented by the following
recurrence relation
⎧ n n≥3
⎪
T(n) = ⎨ ⎛ n ⎞
⎪T ⎜ 3 ⎟ + cn otherwise
⎩ ⎝ ⎠
Introduction 41