Download Algorithms

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Fundamentals of Algorithmic
Problem Solving
 Algorithms are not answers to problems
 They are specific instructions for getting answers
 This emphasis on defining precise constructive
procedures is what makes computer science
distinct from other many other disciplines
 The design of algorithms typically has several
steps
 Understanding the problem
 Ascertaining the capabilities of a computational
device
 Choosing between exact and approximate problem
solving
 Deciding on appropriate data structures
© Ronaldo Menezes, Florida Tech
Connectivity Problem
 Let's consider the following problem:
 Given a sequence of pairs of integers of the form (pq) write an algorithm that would input a sequence of
pairs and tell whether a pair is redundant.
 (p-q) means that p is connected to q, and vice-versa (the
connection relation is transitive)
 A pair (p-q) is said to be redundant iff p is connected
to q via some N number of other integers, N>=0
 The algorithm must therefore remember the
pairs it has seen (or information related to the
pairs) so that it can answer if a given pair is
redundant.
© Ronaldo Menezes, Florida Tech
Sample Output
© Ronaldo Menezes, Florida Tech
Connectivity Applications
 Networks
 Integers may represent machines and our problem
is to find whether two machines need to be
connected
 Same applies to other kids of networks such as Social
Networks.
 Integers may represent points in a electric network
grid and we want to find out whether the pairs
(wires) are sufficient to connect all points in the
network
 VLSI
 In the design of integrated circuits integers may
represent components and we want to avoid the
use of redundant connection between the
components.
© Ronaldo Menezes, Florida Tech
Connectivity Applications
 Programming Languages
 Some languages have the concept of
aliases. Integers may represent the variable
names and the pairs represent the fact the
two variable names are equivalent.
 Graph Theory
 Pairs represent edges and integers
represent nodes. We might want to find out
the degree of connectivity of the graph.
© Ronaldo Menezes, Florida Tech
Large Connectivity Example
(from Sedgewick’s book)
© Ronaldo Menezes, Florida Tech
Expressing a Algorithm
 Our first task is to think about what is required from
the problem statement.
 That is, we need to know what the algorithm needs to
answer.
 It is normally the case that the complexity of the
problem is directly proportional to the complexity of
the algorithm.
 Although complex problems may have a very simple
algorithm
 In the connectivity case, one needs to answer only a
binary question: given a pair of integers, are they
connected already (yes/no)?
 Note that the problem does not require us to demonstrate
the path in the case of a positive answer.
 In fact the addition of this requirement would make the
problem much more© Ronaldo
complex.
Menezes, Florida Tech
Expressing a Algorithm
 One could also ask for “less” information:
 Are M connections sufficient to fully connect
N objects together?
 Note that we're are not asking anything about
specific pairs.
© Ronaldo Menezes, Florida Tech
Fundamental Operations
 When designing an algorithm it is worth spending
some time thinking about the fundamental operations
that the algorithm needs to perform.
 For the connectivity problem we could have that for every
given pair
 One has to find whether the pair represents a new connection
between the two objects
 If it does, then we need to incorporate the information about the
new connection (in a data structure) so that future searches can
be answered correctly
 The above can be abstractly represented using a set.
 The input represents elements in a set. The problem then is
to:
 Find whether a set contains a given items in the pair.
 Replace the sets containing the two given items with their union
set.
© Ronaldo Menezes, Florida Tech
Self-test Exercise
 Exercise 1
How can we solve the connectivity problem using the
abstract operations described in the previous slide?
Sketch an algorithm based on the following
description:
 We can use a set S to represent the connected elements
 When we read a pair (p-q) we check whether they (both)
are elements of the set
 If they are, we don't print the pair (they are already connected).
 If they are not we then make: S U {p,q}.
© Ronaldo Menezes, Florida Tech
How good is good enough?
 As a rule of thumb we strive for finding efficient
algorithms. But there various are factors you should
consider:
 Very important factors:
 How often are you going to need the algorithm?
 What is the typical problem size you're trying to solve?
 Less important factors that should also be considered:
 What language are you going use to implement your algorithm?
 What is the cost-benefit of an efficient algorithm?
 One of the best quotes I know about design (in
general) is from Antoine de Saint-Exupéry:
 “A designer knows he has arrived at perfection not when
there is no longer anything to add, but when there is no
longer anything to take away”
© Ronaldo Menezes, Florida Tech
Simplicity is Very Desirable
 Independently of how good your algorithm
needs to be, you should always try to fully
understand the problem
 A good understanding exercise is the design of a
very simple algorithm that does the job.
 A simple (and correct) algorithm may also be
useful as the basis for testing a more sophisticated
algorithm.
 A simple approach (that some of you may
have tried for the connectivity problem) could
be:
 Use a data structure to store all (needed) pairs.
 For any new pair (p-q), search the data structure
and try to build a path from p to q.
© Ronaldo Menezes, Florida Tech
Brute Force
 Brute force is a straightforward approach to solving a
problem usually directly based on the problem's
statement and on the definitions of the concepts
involved
[Levitin 2003]
 It is considered a design strategy although the strategy
is simply: just do something that works!
 As an example consider the exponentiation problem


Compute an for a given number a and a nonnegative integer n.
The brute force approach consists of:

Can you calculate an using less then (n-1) multiplications?
© Ronaldo Menezes, Florida Tech
Uses of Brute Force
 The brute force design technique rarely yields
efficient algorithms.
 But it does have a few advantages:
 Brute force algorithms are normally more general.
 In fact it is normally difficult to point out problems that a bruteforce approach cannot tackle.
 Most elementary algorithmic tasks use brute force
solutions.
 e.g. Calculating the sum of a list of numbers; finding the max
element in a list.
 The solutions are normally reasonable for practical instances
sizes.
 A simple (correct) solution may serve as
 the basis for testing more sophisticated solutions.
 as a yardstick with which to judge more efficient alternatives for
solving the problem – a benchmark.
© Ronaldo Menezes, Florida Tech
The Brute-force Approach to The
Connectivity Problem
 Let’s go back to the brute force approach
to the connectivity problem we mentioned
earlier
 It may not be considered an algorithm
because:
 How big does the data structure to save all
pairs need to be?
 No obvious solution for building the path
comes to mind.
© Ronaldo Menezes, Florida Tech
Union-Find Algorithm
 If we want to solve the connectivity problem
based on union-find operations we must:
 Define a data structure to represent the set(s)
 The quick-find solution (as defined by Sedgewick's) uses
an array of size N where N is the number of objects in the
connectivity problem. Let's called it id
 The value of the id[i] object is initialized with the value
i.
 Define the union operation
 Two objects (p and q) are said to belong to the same set
(therefore connected) iff
id[p] == id[q]
 Union is defined by changing all entries in the array with
value equal to id[p] to id[q]
© Ronaldo Menezes, Florida Tech
View of Quick-Find
id
© Ronaldo Menezes, Florida Tech
Quick-find solution to the
connectivity problem
public class QuickF {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
int id[] = new int[N];
for (int i = 0; i < N ; i++)
id[i] = i;
for( In.init(); !In.empty(); ) {
int p = In.getInt(), q = In.getInt();
int t = id[p];
if (t == id[q]) continue;
for (int i = 0; i < N; i++)
if (id[i] == t) id[i] = id[q];
Out.println(" " + p + " " + q);
}
}
}
© Ronaldo Menezes, Florida Tech
How good is Quick-Find?
 Property 1.1
The quick-find algorithm executes at least MN
instructions, where N is the number of objects and M
is the number of unions.
For each union operation the internal for-loop has to
traverse the entire array
 This seems a reasonable algorithm but if M and N
are large, the algorithm does not perform that well.
 Can we do better?
 The algorithm we saw earlier is a union-find algorithm
where the find operation is fast but the union is slower.
 Let's look at a solution that uses the same abstraction but
with a different interpretation for the values stored in the
array.
© Ronaldo Menezes, Florida Tech