Design and Analysis of Algorithms-1
Design and Analysis of Algorithms-1
1.0 Introduction 1
1.1 Objectives 2
1.2 Example of an Algorithm 3
1.3 Basics Building Blocks of Algorithms 4
1.3.1 Sequencing, Selection and Iteration 5
1.3.2 Procedure and Recursion 6
1.4 A Survey of Common Running Times 8
1.5 Analysis & Complexity of Algorithms 14
1.6 Types of Computational Problems 17
1.7 Problem Solving Techniques 20
1.8 Deterministic and Stochastic Algorithms 22
1.9 Summary 23
1.10 Solution to Check Your Progress 24
1.11 Further Readings 26
1.0 Introduction
1
Introduction to Algorithm 4. Effectiveness: Every step of the algorithm should be basic and
essential.
In this unit, the basics of the algorithms and its designing process will be
discussed. Section 1.3 will define the algorithm and its uses with suitable
example. An algorithm is designed with three basic building blocks, namely
sequencing, selection, and iteration. A detailed discussion about these building
blocks of an algorithm is presented in Section 1.4.
1.1 Objectives
2
Differentiate between deterministic and stochastic algorithms. Basic of An Algorithm
{
while b ≠ 0 do
{
r ← a mod b;
a ←b;
b← r;
} [end of while loop]
return (b)
// a and b are two positive numbers where a is dividend and b is a divisor
} [end of algorithm]
1. If b=0, return a and exit
2. else go to step 3
3. Divide a by b and assign remainder to r
4. Assign the value of b to a and the value of r to b and go back to step 1
The above algorithm has two inputs and one output. The algorithm is finite as
it terminates in finite steps and produces the desired result. To observe the
same, let us find the GCD of a = 1071 and b = 462 using Euclid’s algorithm.
Iteration 1:
3
Introduction to Algorithm Here, r is not zero, so we will go to Step 3.
3. The integer will get the current value of integer b and the new value of
integer b will be the current value of r.
Here, a=462 and b=147
4. Go back to Step 1.
Iteration 2:
4
1.3.1 Sequencing, Selection and Iteration Basic of An Algorithm
Let’s consider the example of finding GCD of (a, b) with Euclidian method to
understand the basic building blocks of an algorithm(Algorithm 1)
Sequencing: A problem can be solved by performing some actions in a
sequence [called algorithm], and the order of execution of those actions is
important to ensure the correctness of an algorithm.
If the order of steps of algorithm changes and does not follow the steps as
specified, it will not produce the correct output as expected.
Line 5: r ← a mod b;
Line 6: a ←b;
Line 7: b← r;
Line 8: } [end of while loop]
Line 9: return (b)
5
Introduction to Algorithm Line 10: } [end of algorithm]
In above algorithm line 5, line 6 and line 7 are example of sequencing, as these
statements are always executed in sequence as written the text.
Line 3 also acts as iteration or the looping statements. Based on the while loop
condition, the Line 4 to line 8 are executed in repeatedly manner.
(i) Procedure
(ii) Recursion
Procedure
Among a number of terms that are used in stead of procedure are: subprogram
and even function. These terms may have shades of differences in their usage
in different programming languages. However, the basic idea behind these
terms is the same, and is explained next.
It may happen that a sequence of statements frequently occur either in the
same algorithm repeatedly in different parts of the algorithm or may occur in
different algorithms. In such cases, writing repeatedly the same sequence of
statements is a wasteful activity. Procedure is a mechanism to avoid it. For
example we can define GCD(a,b) as a procedure/function only once and can
call it a number of times in a main function with different values of a and b
The general format for defining a procedure might look like this:
Procedure <Name> (<parameter-list>) [: < type>]
<declarations>
<sequence of instructions expected to be occurred repeatedly>
end;
In cases of procedures which pass a value to the calling program another basic
construct (in addition to assignment, read and write) viz., return (x) is used,
where x is a variable used for the value to be passed by the procedure.
Recursion
factorial (1) = 1
6
For those who are familiar with recursive definitions like the one given above Basic of An Algorithm
for factorial, it is easy to understand how the value of (n!) is obtained from the
above definition of factorial of a natural number. However, for those who are
not familiar with recursive definitions, let us compute factorial (4) using the
above definition.
By definition
factorial (4) = 4 * factorial (3).
Again by the definition
factorial (3) = 3 * factorial (2)
Similarly
factorial (2) = 2* factorial (1)
And by definition
factorial (1) = 1
Substituting back values of factorial (1), factorial (2) etc., we get factorial (4) =
4.3.2.1=24, as desired.
In the following procedure factorial (n), let fact be the variable which is used
to pass the value by the procedure factorial to a calling program. The variable
fact is initially assigned value 1, which is the value of factorial (1).
fact: integer;
begin
fact 1
else begin
fact n * factorial (n ─ 1)
return (fact)
end;
end;
7
Introduction to Algorithm (i) There must be in-built mechanism in the computer system that
supports the calling of a procedure by itself, e.g, there may be in-built
stack operations on a set of stack registers.
(ii) There must be conditions within the definition of a recursive procedure
under which, after finite number of calls, the procedure is terminated.
(iii) The arguments in successive calls should be simpler in the sense that
each succeeding argument takes us towards the conditions mentioned in
(ii).
Recursion is an important construct which will be used extensively to solve
sorting algorithms, searching algorithm, matrix multiplications, etc.
For a given problem, more than one algorithm can be designed. However, one
algorithm may be better than the other. To compare two algorithms for a
problem, running time is generally used which is defined as the time taken by
an algorithm in generating the output. An algorithm is better if it takes less
running time. However, this measure should be invariant to any hardware used.
Therefore, the running time of an algorithm can be represented in terms of the
number of operations executed for a given input. More the number of
operations, the larger the running time of an algorithm. So, if we can find the
number of operations required for a given input in an algorithm then we can
measure the running time. This running time of an algorithm for producing the
output is also known as time complexity.
Following are the generalized form of running time for the algorithms:
1. Constant Time (O(k)): If the running time does not depend on the
input size (n) then it is known as constant running time. It can be
represented as
8
where k is a constant Basic of An Algorithm
T(n)=k
k
minimum = a[1]
for ί = 2 to n
if a[ί] < minimum
minimum = a[ί]
end
end if
T(n)=kn
k
T(n)=kn
9
Introduction to Algorithm of input remains half of that of previous iteration, then it is known as
logarithmic time complexity and depicted as O(log n) time. For
example running time of binary search algorithm is O(log n). O(n log
n) is a very common running time for many algorithms which are
solved through divide and conquer technique such as Merge sort ,
Quick sort algorithms, etc., The common operations among all these
problems are in splitting of the array in equal sized sub-arrays and then
solve it recursively.
T(n)=log(n)
T(n)=log(n)
Figure (c) T(n) = log(n)
Quadratic Time: (T(n)= O(n)2)- It occurs when the algorithm is having a pair
of nested loops. The outer loop iterates O(n) time and for each iteration the
inner loop takes O(n) time so we get O(n2) by multiplying these two factors of
n. Practically this is useful for problem for small input size or elementary
sorting algorithms. The worst case time complexity for Bubble sort, Insertion
sort, Selection sort and insertion sort running time complexities are O(n2)
T(n)=n2
10
is n (ie each set is having n elements). The problem is to find whether Basic of An Algorithm
some pairs of these sets are disjoint, i.e there are no common elements
in these pairs and what is the time complexity ?
T(n)=
Time Complexity- The innermost loop takes O(n) time because of n elements.
The second inner loop over 𝑆𝑗 also takes O(n) iterations around the innermost
loop and finally O(n) over 𝑆𝑖 around 𝑆𝑗 iterations. Multiplying all the three
iterations we obtain O(𝑛3 ) time complexity.
11
Introduction to Algorithm example let us consider a problem to find an independent set in a graph
which can be defined as a set of nodes which are not joined by any
edge. Let us formulate the independent set problem in the following
way: given a constant k and a graph G having n nodes (vertices) find
out an independent set of a size k.
The brute force method to solve this problem would require searching
for all subsets of k nodes and for each subset it would examine whether
there is an edge connecting any two nodes for each subset s of a size k .
Below is a pseudo-code for finding an independent set.
Pseudo-code
for each subset s of a size k in a graph G
check whether s is an independent set
if yes, print “ s is an independent set
else stop
In this case the outer loop will iterate O(nk) times and it selects all k-
node subsets of n node of the graph. In the inner loop within each
subset it loops for each pair of nodes to find out whether there is an
edge between the pair which will require O( 2 out of k)
pairs of search i.e.O(k2 ) search. Therefore the total time now is O(k2
nk). Since k is a constant, it can be dropped, finally it is O(nk).
T(n)=nk
12
Pseudo-code : Basic of An Algorithm
Input G(V,E)
{
for each subset s of n number of nodes
verify whether s is an independent set
if s is the largest among all the subsets examined so for
print “s is the largest independent set ”
end if
end for
}end of code fragment
Verification of all pairs of subsets i.e. (2n) whether these subsets are
having edges or not and then selecting the maximum will be O(n2) i.e
the total number of pair of subsets. The total running time would be
O(n2*2n) or O(2n ) .O(2n) running time complexity arises when a search
algorithm considers all subsets of n elements.
The second boy will be left with (n-1) choices among girls for comparison.
There will be only (n-2) options for matching for the third boy, and so forth.
13
Introduction to Algorithm after array girls Multiplying all these options for n boys we obtain n! ie. n(n-
1) (n-2) .......(2) (1)
(ii) O(n!) also occurs where the problem requires arranging n elements into
a particular order (i.e. a permutation of n numbers). A classic example
is travelling salesman problem. Given a n number of cities with
distance between all pairs of cities with the following conditions (i) the
salesman can start the tour with any city but must conclude the tour
with the starting city only (ii) all cities must be visited only once
except the one where from the tour starts. The problem is to find out
the shortest tour covering all n cities. Applying a brute force approach
to find out the solution, a salesman has to explore n! searches which
will take O(n!). Note that a salesman can pick up any city among n
cities to start the tour. Next it will have (n-1) cities to pickup the second
city on the tour. There will be (n-2) cities to pick up the third city at the
next stage and so forth. Multiplying all these choices we get n! i.e. n (n-
1) (n-2) ....(2) (1)
Suppose M is an algorithm with n the input data size. The time and space used
by the algorithm M are the two main measures for the efficiency of M. The
time is measured by counting the number of key operations, for example, in
case of sorting and searching algorithms, the number of comparisons is the
number of key operations. That is because key operations are so defined that
the time for the other operations is much less than or at most proportional to
the time for the key operations. The space is measured by counting the
maximum of memory needed by the algorithm.
The complexity of an algorithm M is the function f(n), which give the running
time and/or storage space requirement of the algorithm in terms of the size n of
the input data. Frequently, the storage space required by an algorithm is simply
a multiple of the data size n. In general the term “complexity” given anywhere
simply refers to the running time of the algorithm. There are 3 cases, in
general, to find the complexity function f(n):
Worst-case − The maximum number of steps taken on any instance of
size a.
Best-case − The minimum number of steps taken on any instance of
size a.
Average case − An average number of steps taken on any instance of
size a.
14
Basic of An Algorithm
Average case: The value of which is in between maximum and minimum
for any possible input. Generally the Average case implies the expected value
of
The analysis of the average case assumes a certain probabilistic distribution
for the input data; one such assumption might be that all possible
permutations of an input data set are equally likely. The Average case also
uses the concept of probability theory. Suppose the numbers ……
occur with respective probabilities 𝑝1 , 𝑝2 , … … 𝑝𝑘, Then the expectation or
average value of E is given by
Best case: Clearly the best case occurs when x is the first element in the array
A. That is . In this case
Worst case: Clearly the worst case occurs when x is the last element in the
array A or is not present in given array A (to ensure this we have to search
15
Introduction to Algorithm entire array A till last element). In this case, we have
.
Average case: Here we assume that searched element appear array A, and it
is equally likely to occur at any position in the array. Here the number of
comparisons can be any of numbers 1,2,3,…,n, and each
Asymptotic notation gives the rate of growth, i.e. performance, of the run time
for “sufficiently large input sizes” and is not a measure of the
particular run time for a specific input size (which should be done
empirically). O-notation is used to express the Upper bound (worst case); Ω-
notation is used to express the Lower bound (Best case) and Θ- Notations is
used to express both upper and lower bound (i.e. Average case) on a function.
We generally want to find either or both an asymptotic lower bound and upper
bound for the growth of our function. The lower bound represents the best
case growth of the algorithm while the upper bound represents the worst case
growth of the algorithm.
16
Basic of An Algorithm
1.6 Types of Computational Problems
Sorting
The sorting is the process to arrange the given set of items in a certain order,
assuming that the nature of the items allow such an ordering. For example,
sorting a set of numbers in increasing or decreasing order and sorting the
character strings, like names, in an alphabetical order.
1. Stability
2. In-place.
A sorting algorithm is called stable if it does not change the relative positions
of any two equal items of input list. Say, in an input list, there are two equal
items at positions i and j where i< j, then the final position of these items in the
sorted list should also be k and l respectively, such that k<l. That is there
should not be any swapping among these equal items and should not
interchange their position with each other.
17
Introduction to Algorithm A sorting algorithm needs extra memory space to store elements during the
swapping process. For small set of items in a list, this constraint is not
observable but, for an input list of large elements the required storage space is
considerable large. An algorithm is said to be in-place if the required extra
memory is not markable.
Searching
Searching is finding an element, referred as search key, in a given set of items
(may have the redundant value). Searching is one of the most important and
frequently performed operation on any dataset/database.
String Processing
Exponential increase in the textual data due to the various applications over
social media and blogs, string-handling algorithms become a current area of
research . Another reason for blooming strings rather text processing is the
kind of data available and the use of the data. Most of the text data is used to
predict the interest of people involving direct or indirect monetary benefits for
commercial organizations specially e-commerce sectors. One of the most
widely used search engine (Google) is also based on string processing.
Graph Problems
It is always favourable for researchers to map a computational problem to a
graph problem. Many computational problems can be solved using graph.
Most of the computer network problems can be solved using graph Algorithms
efficiently. Problems like: visiting all the nodes of a graph (broadcasting in
network), routing in networks (finding the minimum cost path, i.e. the shortest
path, path with minimum delay etc. can be solved efficiently with graph
algorithms.
At the same time some of the graph problems are computationally not easy,
like the travelling salesman and the graph-coloring problems. The Travelling
Salesman Problem (TSP) is used to cover n cities by taking the shortest path
and not visiting any of the city more than once. The graph-coloring
problem seeks to color all the vertices of a graph with minimum number colors
such that, no two adjacent vertices having the same color. While solving TSP
cities can be considered as the vertices of the graph. Event scheduling could be
18
one of the problems which can be solved using graph coloring algorithm. Basic of An Algorithm
Considering events to be represented by the vertices, there exists an edge
between two events only if the corresponding events cannot be scheduled at
the same time.
Combinatorial Problems
These types of problems have a combination of solutions i.e. more than one
solution are possible. The aim of the combinatorial problems is to find
permutations, combinations, or subsets, satisfying the given conditions. The
travelling salesman problem, independent set and the graph-coloring problems
can be categorized as examples of combinatorial problems . From both
theoretical as well as practical point of view, the combinatorial problems are
considered to be one of the most difficult problems in computing. Due to the
combinatorial type of solutions, it becomes very difficult to handle the
problems with big size inputs sets. The number of combinatorial objects (the
output solution) grows rapidly with the problem’s size.
Another problem is the lack of the known algorithms to solve this type of
problems within considerable amount of time. Moreover, it is believed by the
most computer scientists that such algorithms do not exist.
Even though there exist solutions to some combinatorial problems, but these
are considered as fortunate exceptions to the rule. The problem of finding
shortest-path in a network is one of such exceptions.
Geometric Problems
Some of the applications of Geometric algorithms are computer graphics,
robotics and tomography. These algorithms are based upon geometric objects
such as points, lines, and polygons. The geometry procedures are developed to
solve various geometric problems, like construction shapes of geometric
objects, triangles, circles, etc., using ruler and compass.
The closest-pair problem is to find the closest pair out of a given set of points
in the plane.
Numerical Problems
Problems of numerical computing nature are simultaneous linear equations
(linear algebra), differential equations, definite integration, and statistics.
Most of the numerical problems could be solved approximately.
19
Introduction to Algorithm The biggest drawback of numerical algorithms is the accumulation of errors
over the multiple iterations, due to rounding off the approximated result at
each iteration.
Brute force and exhaustive search algorithms are known as blind algorithms.
These algorithms create and evaluate every possible solution and take
exponential and factorial running time. In the previous section we discussed
three such problems: independent set, bipartite matching and travelling
salesman problem. It can be understood by a simple example of finding the
correct four letters word using Brute Force and Exhaustive Search Algorithms.
When the problem size increases, its possible outcomes increases
exponentially which is practically impossible to find.
Step 1. Divide the problem (top level) into a set of sub-problems (lower
level).
Step 2. Solve every sub-problem individually by recursive approach.
Step 3. Merge the solution of the sub-problems into a complete solution of
the problem.
Following are the examples of the problems that can efficiently be solved
using divide and conquer approach.
Binary Search.
Quick Sort.
Merge Sort.
Strassen's Matrix Multiplication.
Closest Pair of Points.
20
Greedy Technique Basic of An Algorithm
Greedy algorithm always picks the best choice (greedy approach) out of
many at a particular moment to optimize a given objective.
The greedy method chooses the local optimum at each step and this
decision may result in overall non-optimum or optimum solution.
The greedy approach doesn't always produce the optimal solution rather
produces very nearby solution to the optimal solution.
Consequently, Greedy algorithms are often very easy to design for the
optimisation problems. Following are some of the examples of the greedy
approach.
Dynamic Programming
21
Introduction to Algorithm Branch and Bound
Branch and bound algorithm efficiently solves the discrete and combinatorial
optimization problems. In branch-and-bound algorithm, a rooted tree is formed
with the full solution set at the root. The algorithm explores the branches of
this tree, representing the subsets of the solution set. A candidate solution of a
root node is considered as a branch only if it is better than the already explored
solution, and is discarded if it cannot produce a better solution than the best
one found so far by the algorithm. Branch and Bound algorithm are methods
for solving global optimization problems. However, it is much slower. Indeed,
it often leads to exponential time complexities in the worst case. On the other
hand, if applied carefully, it can lead to algorithms that run reasonably fast on
average. The general idea of B&B is a BFS-like search for the optimal
solution, but not all nodes get expanded (i.e., their children generated).
Randomized Algorithms
Backtracking Algorithm
S.
Set A S.N. Set B
N.
Geometric
2 B Finding an item in set items.
Problem
1.9 Summary
23
Introduction to Algorithm Problems generally fall into any one of the commonly known categories,
namely sorting, searching, string processing, graph problems, combinatorial
problems, geometric problems, numerical problems, but may be overlapping
also. Many graph theoretic problems can be also combinatorial problems
Similar type of problems can be solved with similar approach. Some of the
commonly used problems solving techniques are Brute Force and Exhaustive
search approach, Divide and Conquer approach, Greedy technique, Dynamic
Programming, Branch and Bound, Randomized algorithms, and Backtracking
algorithm.
24
Ans. Independent set problem can be defined as a set of nodes which are not Basic of An Algorithm
joined by any edge. One way to formulate this problem is that given a constant
k and a graph G having n nodes (vertices) find out an independent set of a size
k.
S.
Set A S.N. Set B
N.
Geometric
2 B Finding an item in set items.
Problem
1 – A, 2 – F, 3 – C, D, 4 – E, 5 – B, 6 – G.
25
Introduction to Algorithm Eight queen puzzle
Map coloring
Sudoku
Following problems can be solved using dynamic programming approach:
26