Unit-I - Introduction
Unit-I - Introduction
UNIT – 1
INTRODUCTION
Dr.P.GaneshKumar
Dept. of Information Technology
Anna University Regional Campus, Coimbatore
Notion of an Algorithm
• An algorithm is a sequence of unambiguous
instructions for solving a problem.
– i.e., for obtaining a required output for any
legitimate input in a finite amount of time.
Key points about an Algorithm
• The non-ambiguity requirement for each step of an
algorithm cannot be compromised.
• The range of inputs for which an algorithm works has to
be specified carefully.
• The same algorithm can be represented in several
different ways.
• There may exist several algorithms for solving the same
problem.
• Algorithms for the same problem can be based on very
different ideas and can solve the problem with
dramatically different speeds.
Computing the Greatest
Common Divisor of Two Integers
• The greatest common divisor of two nonnegative,
not-both-zero integers m and n, denoted gcd(m,
n), is defined as the largest integer that divides
both m and n evenly, i.e., with a remainder of zero.
– Euclid’s algorithm
– Consecutive integer checking algorithm
– Middle-school procedure
– Incorporation of sieve of Eratosthenes into the middle-
school procedure
Fundamentals of Algorithmic Problem Solving
• Understanding the Problem
• Ascertaining the Capabilities of the Computational
Device
• Choosing between Exact and Approximate Problem
Solving
• Algorithm Design Techniques
• Designing an Algorithm and Data Structures
• Methods of Specifying an Algorithm
• Proving an Algorithm’s Correctness
• Analyzing an Algorithm
• Coding an Algorithm
Algorithm design and analysis process
Understanding the Problem
• Read the problem’s description carefully and ask questions if you
have any doubts about the problem.
• Do a few small examples by hand, think about special cases, and ask
questions again if needed.
• An input to an algorithm specifies an instance of the problem the
algorithm solves. It is very important to specify exactly the set of
instances the algorithm needs to handle.
• If you fail to do this, your algorithm may work correctly for a
majority of inputs but crash on some “boundary” value. Remember
that a correct algorithm is not one that works most of the time, but
one that works correctly for all legitimate inputs.
Ascertaining the Capabilities of the
Computational Device
• The vast majority of algorithms in use today are still destined to be
programmed for a computer closely resembling the von Neumann
machine.
• The essence of this architecture is captured by the so-called random-
access machine (RAM).Its central assumption is that instructions are
executed one after another, one operation at a time. Accordingly,
algorithms designed to be executed on such machines are called
sequential algorithms.
• The central assumption of the RAM model does not hold for some newer
computers that can execute operations concurrently, i.e., in parallel.
Algorithms that take advantage of this capability are called parallel
algorithms.
• There are important problems, however, that are very complex by their
nature, or have to process huge volumes of data, or deal with applications
where the time is critical. In such situations, it is imperative to be aware
of the speed and memory available on a particular computer system.
Choosing between Exact and Approximate
Problem Solving
• Principal decision while designing an algorithm is to choose between
solving the problem exactly or solving it approximately. In the former case,
an algorithm is called an exact algorithm; in the latter case, an algorithm is
called an approximation algorithm.
• First, there are important problems that simply cannot be solved exactly
for most of their instances; examples include extracting square roots,
solving nonlinear equations, and evaluating definite integrals.
• Second, available algorithms for solving a problem exactly can be
unacceptably slow because of the problem’s intrinsic complexity. This
happens, in particular, for many problems involving a very large number of
choices; you will see examples of such difficult problems
• Third, an approximation algorithm can be a part of a more sophisticated
algorithm that solves a problem exactly.
Algorithm Design Techniques
• An algorithm design technique (or “strategy” or “paradigm”) is a general
approach to solving problems algorithmically that is applicable to a variety of
problems from different areas of computing.
– Brute force
– Exhaustive search
– Decrease and Conquer
– Divide and Conquer
– Transform and Conquer
– Hashing
– Backtracking
– Dynamic Programming
– Greedy Technique
– Iterative Improvement
– Branch and Bound
• Algorithm design techniques make it possible to classify algorithms according to
an underlying design idea; therefore, they can serve as a natural way to both
categorize and study algorithms.
Designing an Algorithm and Data Structures
• While the algorithm design techniques do provide a powerful set
of general approaches to algorithmic problem solving, designing
an algorithm for a particular problem may still be a challenging
task.
• Some design techniques can be simply inapplicable to the
problem in question.
• Sometimes, several techniques need to be combined, and there
are algorithms that are hard to pinpoint as applications of the
known design techniques.
• Even when a particular design technique is applicable, getting an
algorithm often requires a nontrivial ingenuity on the part of the
algorithm designer.
• With practice, both tasks—choosing among the general
techniques and applying them—get easier, but they are rarely
easy.
Designing an Algorithm and Data Structures
• In the earlier days of computing, the dominant vehicle for specifying algorithms
was a flowchart, a method of expressing an algorithm by a collection of
connected geometric shapes containing descriptions of the algorithm’s steps.
• This representation technique has proved to be inconvenient for all but very
simple algorithms; nowadays, it can be found only in old algorithm books.
• The state of the art of computing has not yet reached a point where an
algorithm’s description—be it in a natural language or pseudocode—can be fed
into an electronic computer directly. Instead, it needs to be converted into a
computer program written in a particular computer language.
Proving an Algorithm’s Correctness
• Once an algorithm has been specified, you have to
prove its correctness, i.e., prove that the algorithm
yields a required result for every legitimate input in
a finite amount of time.
• For some algorithms, a proof of correctness is
quite easy; for others, it can be quite complex.
• A common technique for proving correctness is to
use mathematical induction because an
algorithm’s iterations provide a natural sequence
of steps needed for such proofs.
Analyzing an Algorithm
• There are two kinds of algorithm efficiency: time efficiency,
indicating how fast the algorithm runs, and space efficiency,
indicating how much extra memory it uses.
• Another desirable characteristic of an algorithm is simplicity.
Unlike efficiency, which can be precisely defined and investigated
with mathematical rigor, simplicity, like beauty, is to a
considerable degree in the eye of the beholder.
• Simpler algorithms are easier to understand and easier to
program; consequently, the resulting programs usually contain
fewer bugs.
• Yet another desirable characteristic of an algorithm is generality.
There are, in fact, two issues here: generality of the problem the
algorithm solves and the set of inputs it accepts.
• If you are not satisfied with the algorithm’s efficiency, simplicity,
or generality, you must return to the drawing board and redesign
the algorithm.
Coding an Algorithm
• Most algorithms are destined to be ultimately implemented
as computer programs. Programming an algorithm presents
both a peril and an opportunity. The peril lies in the
possibility of making the transition from an algorithm to a
program either incorrectly or very inefficiently.
• Orders of growth.
Measuring an Input’s Size
• Any algorithm run longer on larger inputs.
– e.g. Sort larger arrays, Multiply larger
matrices and so on.
• Investigate an algorithm’s efficiency as a
function of some parameter ‘n’ indicating
the algorithm’s input size.
• Straightforward to select such parameter.
– Size of the list
• Sorting, Searching, finding smallest element
Measuring an Input’s Size
• Polynomial evaluation
p( x) an x n ... a0
– Polynomial degree or number of its coefficients.
• Matrix Operation
– Order of matrix ‘n’
– Total number of elements in the matrix ‘N’
• Graph Operation
– Requires more than one parameter to indicate the
size of their inputs.
• Number of vertices, number of edges
Measuring an Input’s Size
• Size metric
– Influenced by the operation of the algorithm
– e.g. Spell-check Algorithm
• Algorithm checking
– Individual character
– Individual word
C worst (n) n
Best-Case Efficiency
Cbest (n) 1
Average-Case Efficiency
• neither the worst-case analysis nor its best-
case counterpart yields the necessary
information about an algorithm’s behavior on
a “typical” or “random” input.
• Standard assumptions
– the probability of a successful search is equal to p
(0 ≤ p ≤ 1).
– the probability of the first match occurring in the ith
position of the list is the same for every i.
Average-Case Efficiency
• Successful Search
– the probability of the first match occurring in
the ith position of the list is p/n for every i.
– the number of comparisons made by the
algorithm in such a situation is obviously i
• Unsuccessful Search
– the number of comparisons will be n with the
probability of such a search being (1 − p)
Average-Case Efficiency
• Successful search
– if p = 1 the average number of key comparisons made by
sequential search is (n + 1)/2.
• Unsuccessful search
– If p = 0 the average number of key comparisons will be n because
the algorithm will inspect all n elements on all such inputs
Amortized Efficiency
• American computer scientist Robert Tarjan.