Академический Документы
Профессиональный Документы
Культура Документы
INTRODUCTION
An algorithm, named after the ninth century scholar Abu Jafar Muhammad Ibn Musu Al-Khowarizmi, is defined as
follows: Roughly speaking:
An algorithm is a set of rules for carrying out calculation either by hand or on a machine.
An algorithm is a finite step-by-step procedure to achieve a required result.
An algorithm is a sequence of computational steps that transform the input into the output.
An algorithm is a sequence of operations performed on data that have to be organized in data structures.
An algorithm is an abstraction of a program to be executed on a physical machine (model of Computation).
Algorithmic is a branch of computer science that consists of designing and analyzing computer algorithms
Algorithm's Performance
Two important ways to characterize the effectiveness of an algorithm:
Space complexity - a measure of the amount of working storage an algorithm needs
Time complexity - an algorithm concerns determining an expression of the number of steps needed
as a function of the problem size
The performance evaluation of an algorithm is obtained by totaling the number of occurrences of each operation
when running the algorithm. The performance of an algorithm is evaluated as a function of the input size n and is to
be considered modulo a multiplicative constant.
Asymptotic Notations
These are commonly use notations in performance analysis and used to characterize the complexity of an
algorithm.
1. O (Big Oh) notation
2. (Big Omega)
3. (Big Theta)
1. GREEDY ALGORITHMS
Greedy algorithms are simple and straightforward. They are shortsighted in their approach in the sense that
they take decisions on the basis of information at hand without worrying about the effect these decisions
may have in the future. They are easy to invent, easy to implement and most of the time quite efficient.
Many problems cannot be solved correctly by greedy approach. Greedy algorithms are used to solve
optimization problems
Greedy Approach
Greedy Algorithm works by making the decision that seems most promising at any moment; it never
reconsiders this decision, whatever situation may arise later.
Characteristics and Features of Problems solved by Greedy Algorithms
To construct the solution in an optimal way. Algorithm maintains two sets. One contains chosen items and
the other contains rejected items.
The greedy algorithm consists of four (4) function.
o A function that checks whether chosen set of items provide a solution.
o A function that checks the feasibility of a set.
o The selection function tells which of the candidates is the most promising.
o An objective function, which does not appear explicitly, gives the value of a solution.
Structure Greedy Algorithm
Initially the set of chosen items is empty i.e., solution set.
At each step
o item will be added in a solution set by using selection function.
o IF the set would no longer be feasible
reject items under consideration (and is never consider again).
o ELSE IF set is still feasible THEN
add the current item.
Definitions of feasibility
A feasible set (of candidates) is promising if it can be extended to produce not merely a solution, but an
optimal solution to the problem. In particular, the empty set is always promising why? (because an optimal
solution always exists)
Unlike Dynamic Programming, which solves the subproblems bottom-up, a greedy strategy usually
progresses in a top-down fashion, making one greedy choice after another, reducing each problem to a
smaller one.
Greedy-Choice Property
The "greedy-choice property" and "optimal substructure" are two ingredients in the problem that lend to a
greedy strategy.
It says that a globally optimal solution can be arrived at by making a locally optimal choice.
A. Knapsack Problem
There are two versions of problem
o Fractional knapsack problem
The setup is same, but the thief can take fractions of items, meaning that the items can be
broken into smaller pieces so that thief may decide to carry only a fraction of xi of item i,
where 0 xi 1.
Exhibit greedy choice property.
Greedy algorithm exists.
Exhibit optimal substructure property.
o 0-1 knapsack problem
The setup is the same, but the items may not be broken into smaller pieces, so thief may
decide either to take an item or to leave it (binary choice), but may not take a fraction of an
item.
Exhibit No greedy choice property.
No greedy algorithm exists.
Exhibit optimal substructure property.
Only dynamic programming algorithm exists.
B. Huffmans Codes
Huffman code is a technique for compressing data.
Huffman's greedy algorithm look at the occurrence of each character and it as a binary string in an optimal
way.
Based on lengths of assigned codes based on frequencies
Variable Length Codes are known as Prefix Codes
How to generate a Prefix Codes?
o The Huffman coding algorithm does this by constructing a binary tree
o By strategically assigning bits string to symbols based on their frequency, we generate a prefix code
that also bring about compression
Constructing a Huffman code
A greedy algorithm that constructs an optimal prefix code called a Huffman code. The algorithm builds the
tree T corresponding to the optimal code in a bottom-up manner. It begins with a set of |c| leaves and
perform |c|-1 "merging" operations to create the final tree.
D. Kruskals Algorithm
In kruskal's algorithm the selection function chooses edges in increasing order of length without worrying
too much about their connection to previously chosen edges, except that never to form a cycle
The result is a forest of trees that grows until all the trees in a forest (all the components) merge in a single
tree.
E. Prims Algorithm
This algorithm was first propsed by Jarnik, but typically attributed to Prim.
It starts from an arbitrary vertex (root) and at each stage, add a new branch (edge) to the tree already
constructed; the algorithm halts when all the vertices in the graph have been reached. This strategy is
greedy in the sense that at each step the partial spanning tree is augmented with an edge that is the
smallest among all possible adjacent edges.
MST-PRIM
Input: A weighted, undirected graph G=(V, E, w)
Output: A minimum spanning tree T.
T={}
Let r be an arbitrarily chosen vertex from V.
U = {r}
WHILE | U| < n
DO
Find u in U and v in V-U such that the edge (u, v) is a smallest edge between U-V.
T = TU{(u, v)}
U= UU{v}
Analysis
The algorithm spends most of its time in finding the smallest edge. So, time of the algorithm basically
depends on how do we search this edge.
Straightforward method
Just find the smallest edge by searching the adjacency list of the vertices in V. In this case, each iteration
costs O(m) time, yielding a total running time of O(mn).
Binary heap
By using binary heaps, the algorithm runs in O(m log n).
Fibonacci heap
By using Fibonacci heaps, the algorithm runs in O(m + n log n) time.
The algorithm maintains two sets of vertices, S and C. At every stage the set S contains those vertices that have
already been selected and set C contains all the other vertices. Hence we have the invariant property V=S U C. When
algorithm starts Delta contains only the source vertex and when the algorithm halts, Delta contains all the vertices of
the graph and problem is solved. At each step algorithm choose the vertex in C whose distance to the source is least
and add it to S.
3. DYNAMIC PROGRAMMING
Dynamic programming is a fancy name for using divide-and-conquer technique with a table.
2 Big ideas of Dynamic Program
Recursive substructure
o T(n) = T(n-1) + T(n-2)
o The optimization problem that were trying to solve has some sort of a recursive substructure. The
solution of the problem of size n can be expressed as some function of the solution of smaller
problems.
Memoization
o Keep track of intermediate results, and going 1 step further, we solve the intermediate problems in a
specific order to maximize efficiency
The dynamic programming is a paradigm of algorithm design in which an optimization problem is solved by a
combination of caching subproblem solutions and appealing to the "principle of optimality.
Optimal Substructure simply means solving larger problems given the solutions to its smaller sub problems
There are three basic elements that characterize a dynamic programming algorithm:
1. Substructure
Decompose the given problem into smaller (and hopefully simpler) subproblems. Express the solution of the
original problem in terms of solutions for smaller problems. Note that unlike divide-and-conquer problems,
it is not usually sufficient to consider one decomposition, but many different ones.
2. Table-Structure
After solving the subproblems, store the answers (results) to the subproblems in a table. This is done
because (typically) subproblem solutions are reused many times, and we do not want to repeatedly solve
the same problem over and over again.
3. Bottom-up Computation
Using table (or something), combine solutions of smaller subproblems to solve larger subproblems, and
eventually arrive at a solution to the complete problem. The idea of bottom-up computation is as follow:
Bottom-up means
Start with the smallest subproblems.
Combining theirs solutions obtain the solutions to subproblems of increasing size.
Until arrive at the solution of the original problem.
A. Matrix-Chain Multiplication
The chain matrix multiplication problem is perhaps the most popular example of dynamic programming used
in the upper undergraduate course (or review basic issues of dynamic programming in advanced algorithm's
class).
The chain matrix multiplication problem involves the question of determining the optimal sequence for
performing a series of operations. This general class of problem is important in complier design for code
optimization and in databases for query optimization.
Dynamic Programming Approach
Step 1: Check if the problem has Optimal Substructure
If we have an optimal solution for Ai.j
Assume the solution has the following parentheses: (Aik)(Ak+1j)
If there is a better way to multiply (Aik), then we would have a more optimal solution.
This would be a contradiction, as we already stated that we have the optimal solution for Ai.j
Therefore this problem has optimal substructure
Recursive Formula
M[i,j] = 0 if i=j
mini<k<j { M[i,j] =M[i,k] + M[k+1,j] + pi-1pkpj }
Matrix-Chain DP Algorithm
Matrix-Chain(array p[1 .. n], int n) {
Array s[1 .. n 1, 2 .. n];
FOR i = 1 TO n DO m[i, i] = 0; // initialize
FOR L = 2 TO n DO { // L=length of subchain
FOR i = 1 TO n L + 1 do {
j = i + L 1;
m[i, j] = infinity;
FOR k = i TO j 1 DO { // check all splits
q = m[i, k] + m[k + 1, j] + p[i 1] p[k] p[j];
IF (q < m[i, j]) {
m[i, j] = q;
s[i, j] = k;
}
}
}
}
return m[1, n](final cost) and s (splitting markers);
}
Source:
http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/