=t for //q=v); repeat j:=j-1; until(a[j]<=v);
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
76
if(i=j); a[m]:=a[j]; a[j]:=v; return j; } Algorithm interchange (a,i,j) // exchange a[i] with a[j]. { p :=a[i]; a[i] :=a[j]; a[j] :=p; } In quick sort, the division into sub arrays is made so that the sorted sub arrays do not need to be merged later. This is accomplished by rearranging the elements in a[1:n] such that a[i]<=a[j] for all I between 1 and m and all j between m+1 and n for some m,1<=m<=n. Thus the elements in a[1:m] and a[m+1:n] can be independently sorted. No merge is needed. The rearrangement of the element is accomplished by picking some element of a[],say t =a[s],and then reordering the other elements so that all elements appearing before t in a[1:n] are less than or equal to t and all elements appearing after t are greater than or equal to t. This is rearranging is referred to as partitioning. Function Partition of Algorithm accomplishes an in-place partitioning of the elements of a[m:p-1].It is assumed that a[p]>=a[m] and that a[m] is the partitioning elements. If m=1 and p-1=n, then a[n+1] must be defined and must be greater than or equal to all elements in a[1:n]. The assumption that a[m] is the partition element is merely for convenience; other choices for the partitioning element than the first item in the set are better in practice. The function Interchange (a, i, j) exchanges a[i] with a[j]. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
77
Algorithm Quick Sort (p,q) //Sorts the elements a[p],……,a[q] which reside in the global array //a[1:n] into ascending order; a[n+1] is considered to be defined and //must be >= all the elements in a[1:n]. { if (p
Using Hoare‘s clever method of partitioning a set of elements about a chosen element, we can directly devise a divide-and-conquer method for completely sorting n elements. Following a call to the function Partition, two sets S1 and S2 are produced. All elements in S1 are less than or equal to the element in S2. Hence S1 and S2 can be sorted independently. Each set is sorted by reusing the function Partition
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
78
Quicksort
Quicksort
Quicksort in action on a list of numbers. The horizontal lines are pivot values.
Class
Sorting algorithm
Data structure
Varies
Worst case performance
Θ(n2)
Best case performance
Θ(nlogn)
Average case performance
Θ(nlogn) comparisons
Worst case space complexity
Varies by implementation
Optimal
Sometimes
Quicksort is a well-known sorting algorithm developed by C. A. R. Hoare that, on average, makes Θ(nlogn) (big O notation) comparisons to sort n items. However, in the worst case, it makes Θ(n2) comparisons. Typically, quicksort is significantly faster in practice than other Θ(nlogn) algorithms, because its inner loop can be efficiently implemented on most architectures, and in most real-world data, it is possible to make design choices which minimize the probability of requiring quadratic time. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
79
Quicksort is a comparison sort and, in efficient implementations, is not a stable sort.
Algorithm Quicksort sorts by employing a divide and conquer strategy to divide a list into two sub-lists. The steps are: 1. Pick an element, called a pivot, from the list. 2. Reorder the list so that all elements which are less than the pivot come before the pivot and so that all elements greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation. 3. Recursively sort the sub-list of lesser elements and the sub-list of greater elements. The base case of the recursion are lists of size zero or one, which are always sorted. In simple pseudocode, the algorithm might be expressed as this: function quicksort(array) var list less, greater if length(array) ≤ 1 return array select and remove a pivot value pivot from array for each x in array if x ≤ pivot then append x to less else append x to greater return concatenate(quicksort(less), pivot, quicksort(greater))
Notice that we only examine elements by comparing them to other elements. This makes quicksort a comparison sort. This version is also a stable sort (assuming that the "for each" method retrieves elements in original order, and the pivot selected is the last among those of equal value). The correctness of the partition algorithm is based on the following two arguments:
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
80
At each iteration, all the elements processed so far are in the desired position: before the pivot if less than or equal to the pivot's value, after the pivot otherwise (loop invariant). Each iteration leaves one fewer element to be processed (loop variant). The correctness of the overall algorithm follows from inductive reasoning: for zero or one element, the algorithm leaves the data unchanged; for a larger data set it produces the concatenation of two parts, elements less than or equal to the pivot and elements greater than it, themselves sorted by the recursive hypothesis. The disadvantage of the simple version above is that it requires Ω(n) extra storage space, which is as bad as merge sort. The additional memory allocations required can also drastically impact speed and cache performance in practical implementations. There is a more complex version which uses an in-place partition algorithm and can achieve the complete sort using O(nlogn) space use on average (for the call stack): function partition(array, left, right, pivotIndex) pivotValue := array[pivotIndex] swap array[pivotIndex] and array[right] // Move pivot to end storeIndex := left for i from left to right − 1 if array[i] ≤ pivotValue swap array[i] and array[storeIndex] storeIndex := storeIndex + 1 swap array[storeIndex] and array[right] // Move pivot to its final place return storeIndex
In-place partition in action on a small list. The boxed element is the pivot element, blue elements are less or equal, and red elements are larger. This is the in-place partition algorithm. It partitions the portion of the array between indexes left and right, inclusively, by moving all elements less than or equal to a[pivotIndex] to the beginning of the subarray, leaving all the greater elements following them. In the process it also finds the final position for the pivot element, which it returns. It temporarily moves the pivot element to the end of the subarray, so that it doesn't get in the way. Because it only uses exchanges, the final list has the same elements as the original list. Notice that an element may be exchanged multiple times before reaching its final place. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
81
This form of the partition algorithm is not the original form; multiple variations can be found in various textbooks, such as versions not having the storeIndex. However, this form is probably the easiest to understand. Once we have this, writing quicksort itself is easy: procedure quicksort(array, left, right) if right > left select a pivot index (e.g. pivotIndex := left) pivotNewIndex := partition(array, left, right, pivotIndex) quicksort(array, left, pivotNewIndex - 1) quicksort(array, pivotNewIndex + 1, right)
However, since partition reorders elements within a partition, this version of quicksort is not a stable sort.
Formal analysis From the initial description it's not obvious that quicksort takes Θ(nlogn) time on average. It's not hard to see that the partition operation, which simply loops over the elements of the array once, uses Θ(n) time. In versions that perform concatenation, this operation is also Θ(n). In the best case, each time we perform a partition we divide the list into two nearly equal pieces. This means each recursive call processes a list of half the size. Consequently, we can make only logn nested calls before we reach a list of size 1. This means that the depth of the call tree is Θ(logn). But no two calls at the same level of the call tree process the same part of the original list; thus, each level of calls needs only Θ(n) time all together (each call has some constant overhead, but since there are only Θ(n) calls at each level, this is subsumed in the Θ(n) factor). The result is that the algorithm uses only Θ(nlogn) time. An alternate approach is to set up a recurrence relation for the T(n) factor, the time needed to sort a list of size n. Because a single quicksort call involves Θ(n) factor work plus two recursive calls on lists of size n / 2 in the best case, the relation would be: The master theorem tells us that T(n) = Θ(nlogn).
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
82
In fact, it's not necessary to divide the list this precisely; even if each pivot splits the elements with 99% on one side and 1% on the other (or any other fixed fraction), the call depth is still limited to 100logn, so the total running time is still Θ(nlogn). In the worst case, however, the two sublists have size 1 and n − 1 (for example, if the array consists of the same element by value), and the call tree becomes a linear chain of n nested calls. The ith call does Θ(n − i) work, and . The recurrence relation is: T(n) = Θ(n) + T(0) + T(n − 1) = O(n) + T(n − 1) This is the same relation as for insertion sort and selection sort, and it solves to T(n) = Θ(n2). Given knowledge of which comparisons are performed by the sort, there are adaptive algorithms that are effective at generating worst-case input for quicksort on-the-fly, regardless of the pivot selection strategy.
Randomized quicksort expected complexity Randomized quicksort has the desirable property that it requires only Θ(nlogn) expected time, regardless of the input. Suppose we sort the list and then divide it into four parts. The two parts in the middle will contain the best pivots; each of them is larger than at least 25% of the elements and smaller than at least 25% of the elements. If we could consistently choose an element from these two middle parts, we would only have to split the list at most 2log2n times before reaching lists of size 1, yielding an Θ(nlogn) algorithm. A random choice will only choose from these middle parts half the time. However, this is good enough. Imagine that you are flipping a coin over and over until you get k heads. Although this could take a long time, on average only 2k flips are required, and the chance that you won't get k heads after 100k flips is highly improbable. By the same argument, quicksort's recursion will terminate on average at a call depth of only 2(2log2n). But if its average call depth is Θ(logn), and each level of the call tree processes at most n elements, the total amount of work done on average is the product, Θ(nlogn). Note that the algorithm does not have to verify that the pivot is in the middle half - if we hit it any constant fraction of the times, that is enough for the desired complexity.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
83
The outline of a formal proof of the O(nlogn) expected time complexity follows. Assume that there are no duplicates as duplicates could be handled with linear time pre- and postprocessing, or considered cases easier than the analyzed. Choosing a pivot, uniformly at random from 0 to n − 1, is then equivalent to choosing the size of one particular partition, uniformly at random from 0 to n − 1. With this observation, the continuation of the proof is analogous to the one given in the average complexity section.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
84
Average complexity Even if pivots aren't chosen randomly, quicksort still requires only Θ(nlogn) time over all possible permutations of its input. Because this average is simply the sum of the times over all permutations of the input divided by n factorial, it's equivalent to choosing a random permutation of the input. When we do this, the pivot choices are essentially random, leading to an algorithm with the same running time as randomized quicksort. More precisely, the average number of comparisons over all permutations of the input sequence can be estimated accurately by solving the recurrence relation: Here, n − 1 is the number of comparisons the partition uses. Since the pivot is equally likely to fall anywhere in the sorted list order, the sum is averaging over all possible splits. This means that, on average, quicksort performs only about 39% worse than the ideal number of comparisons, which is its best case. In this sense it is closer to the best case than the worst case. This fast average runtime is another reason for quicksort's practical dominance over other sorting algorithms.
Space complexity The space used by quicksort depends on the version used. Quicksort has a space complexity of Θ(logn), even in the worst case, when it is carefully implemented such that in-place partitioning is used. This requires Θ(1). After partitioning, the partition with the fewest elements is (recursively) sorted first, requiring at most Θ(logn) space. Then the other partition is sorted using tail recursion or iteration. The version of quicksort with in-place partitioning uses only constant additional space before making any recursive call. However, if it has made Θ(logn) nested recursive calls, it needs to store a constant amount of information from each of them. Since the best case makes at most Θ(logn) nested recursive calls, it uses Θ(logn) space. The worst case makes Θ(n) nested recursive calls, and so needs Θ(n) space; Sedgewick's improved version using tail recursion requires Θ(logn) space in the worst case. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
85
We are eliding a small detail here, however. If we consider sorting arbitrarily large lists, we have to keep in mind that our variables like left and right can no longer be considered to occupy constant space; it takes Θ(logn) bits to index into a list of n items. Because we have variables like this in every stack frame, in reality quicksort requires Θ((logn)2) bits of space in the best and average case and Θ(nlogn) space in the worst case. This isn't too terrible, though, since if the list contains mostly distinct elements, the list itself will also occupy Θ(nlogn) bits of space. The not-in-place version of quicksort uses Θ(n) space before it even makes any recursive calls. In the best case its space is still limited to Θ(n), because each level of the recursion uses half as much space as the last, and Its worst case is dismal, requiring space, far more than the list itself. If the list elements are not themselves constant size, the problem grows even larger; for example, if most of the list elements are distinct, each would require about ΘO(logn) bits, leading to a best-case Θ(nlogn) and worst-case Θ(n2logn) space requirement.
Variants There are three variants of quicksort that are worth mentioning: Balanced quicksort: choose a pivot likely to represent the middle of the values to be sorted, and then follow the regular quicksort algorithm. External quicksort: The same as regular quicksort except the pivot is replaced by a buffer. First, read the M/2 first and last elements into the buffer and sort them. Read the next element from the beginning or end to balance writing. If the next element is less than the least of the buffer, write it to available space at the beginning. If greater than the greatest, write it to the end. Otherwise write the greatest or least of the buffer, and put the next element in the buffer. Keep the maximum lower and minimum upper keys written to avoid resorting middle elements that are in order. When done, write the buffer. Recursively sort the smaller partition, and loop to sort the remaining partition.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
86
Three-way radix quicksort (also called multikey quicksort): is a combination of radix sort and quicksort. Pick an element from the array (the pivot) and consider the first character (key) of the string (multikey). Partition the remaining elements into three sets: those whose corresponding character is less than, equal to, and greater than the pivot's character. Recursively sort the "less than" and "greater than" partitions on the same character. Recursively sort the "equal to" partition by the next character (key).
Comparison with other sorting algorithms Quicksort is a space-optimized version of the binary tree sort. Instead of inserting items sequentially into an explicit tree, quicksort organizes them concurrently into a tree that is implied by the recursive calls. The algorithms make exactly the same comparisons, but in a different order. The most direct competitor of quicksort is heapsort. Heapsort is typically somewhat slower than quicksort, but the worst-case running time is always Θ(nlogn). Quicksort is usually faster, though there remains the chance of worst case performance except in the introsort variant. If it's known in advance that heapsort is going to be necessary, using it directly will be faster than waiting for introsort to switch to it. Quicksort also competes with mergesort, another recursive sort algorithm but with the benefit of worst-case Θ(nlogn) running time. Mergesort is a stable sort, unlike quicksort and heapsort, and can be easily adapted to operate on linked lists and very large lists stored on slow-to-access media such as disk storage or network attached storage. Although quicksort can be written to operate on linked lists, it will often suffer from poor pivot choices without random access. The main disadvantage of mergesort is that, when operating on arrays, it requires Θ(n) auxiliary space in the best case, whereas the variant of quicksort with in-place partitioning and tail recursion uses only Θ(logn) space. (Note that when operating on linked lists, mergesort only requires a small, constant amount of auxiliary storage.)
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
87
MODULE 3
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
88
THE GREEDY METHOD – CONTROL ABSTRACTION The greedy method suggests that one can devise an algorithm that works in stages, considering one input at a time. At each stage, a decision is made regarding whether a particular input is in an optimal solution. This is done by considering the inputs in an order determined by some selection procedure. If the inclusion of the next input into the partially constructed optimal solution will result in an infeasible solution, then this input is not assed to the partial solution. Otherwise, it is added. The selection procedure itself is based on some optimization measure. The measure may be the objective function. In fact, several different optimization measures may be plausible for a given problem. Most of these, however, will result in algorithms that generate suboptimal solutions. This version of the greedy technique is called the subset paradigm. The function Select selects an input from a[ ] and removes it. The selected input‘s value is assigned to x. Feasible is a Boolean-valued function that determines whether x can be included into the solution vector. The function Union combines x with the solution and updates the objective function. The function Greedy describes the essential way that a greedy algorithm will look, once a particular problem is chosen and the functions Select, Feasible, and Union are properly implemented. Algorithm Greedy (a,n) //a[1 : n] contains the n inputs. {
Solution :=ø;// Initialize the solution.
for i:=1 to n do {
x:=Select(a); if Fesible(solution,x) then solution := Union(solution,x);
} return solution;
} Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
89
GENERAL KAPSACK PROBLEM In the knapsack problem, we have n objects and a knapsack or a bag. Object i has a weight wi and the knapsack has a capacity m. If a fraction xi , 0 ≤ xi ≤ 1, of object i is placed into the knapsack, then a profit of pixi is earned. The objective is to obtain a filling of the knapsack that maximizes the total profit earned. Since the knapsack capacity is m, we require the total weight of all chosen objects to be at most m. Formally, the problem can be stated as maximize
∑
pixi
1≤ i≤n Subject to ∑ wixi ≤ m 1≤i≤ n And 0 ≤ xi ≤ 1,
1≤i≤ n
The profit and weight are positive numbers. This is done by using greedy method.
ALGORITHM ALGORITHM greedyknapsack(m, n ) / / p[ 1.. n] , w[ 1.. n] / / pi/ wi ≥ pi+1/ wi+1 / / x[1 …. n] solution { for i=1 to n do x[1] =0.0 ; u=m ; for i= 1 to n do { If ( w[i] > u) then break ; x[i] = 1.0 ; u = u – w[i] ; } If ( i ≤ n ) then x[i] = u/ w[i] ; } Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
90
If p1 / w1 ≥ p2 /w2 ≥ ……………. ≥ pn / wn , then greedy knapsack generate an Optimum solution to the given instant of knapsack problem. All optimum solutions will fill the knapsack exactly complexity of knapsack algorithm is 0( n).
Greedy algorithms Similarly to dynamic programming, greedy algorithms are used to solve optimization problems. In contrast to dynamic programming, no global optimal solution is computed, but rather locally optimal decisions are taken. That is why the approach is called greedy.
Example: Knapsack Problem I 2 possible greedy-strategies: select the most valuable element in each step that still fits into the knapsack: Knapsack capacity: 15 Object Size Value g1 3 3 g2 4 5 g3 6 8 g4 7 9 choose: g4; value: 9; remaining capacity: 8 choose: g4; value: 9; remaining capacity: 1 y not optimal
Example: Knapsack Problem II select the relatively most valuable element (max( v(gi )s(gi ) ) ) This will lead to the optimal solution in the case described above. However, this need not always be the case! Knapsack capacity: 50 Object Size Value vs g1 30 90 3 g2 40 100 2,5 g3 50 110 2,2 The strategy will choose g1 (value 90). Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
91
However, the optimal would be g3 (value 110) Greedy algorithms do not always provide the optimal solution. In exchange, they are far less expensive than dynamic programming. Complexity of the greedy-knapsack: O(C)
Optimal greedy algorithms There are problems where greedy algorithms produce optimal solutions. Example: resource planning problem. Given: set of activities S = {1, . . . , n} that want to use some resource, for example a lecture hall. The resource can only be used by one activity at a time. Each activity i has a starting time si and a completion time fi with si < fi . The activity takes place in the time interval [si , fi ), i.e., the next activity can start at time fi . Compatibility of activities: compatible(i , j) :, si _ fj _ sj _ fi . Problem: compute the largest possible set of compatible Activitie
OPTIMAL STORAGE ON TAPES
Optimal storage on tapes I Given: n programs P1, . . . , Pn with lengths l1, . . . , ln. The programs are stored on a tape in order Pi1 , . . . , Pin . Time to access Program Pij : T(i1, . . . , in, j) = li1 + · · · + lij . Average access time: T(i1, . . . , in) = 1n Xn j=1
T(i1, . . . , in, j) = 1n Xn j=1
Xj i=1
li j = 1n Xn j=1
(n − j + 1)lij
Optimal storage on tapes II How to store the programs on the tape so that the average access time becomes minimal? Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
92
Let n be fixed; hence 1n can be ignored. Example: Let P1, P2, P3 have lengths 17, 5, 10. order acess time P1P2P3 17 + (17 + 5) + (17 + 5 + 10) = 71 P1P3P2 17 + (17 + 10) + (17 + 10 + 5) = 76 P2P1P3 59 P3P1P2 69 P2P3P1 52 P3P2P1 52
Optimal storage on tapes III Fact: If for the lenghts l1, . . . , ln the relation l1 _ l2 _ · · · _ ln holds, then the average access time is minimized by the order P1 . . . Pn. Hence, a greedy strategy that always selects the shortest program leads to the minimal average access time.
What have we learnt on greedy algorithms? Greedy algorithms treat optimization problems by taking locally optimal decisions. Hence, they may fail to determine the global optimum. Greedy algorithms need less time than, e.g., dynamic programming. There are problems where a greedy strategy leads to an optimal solution.
SPANNING TREES-MINIMUM COST SPANNING TREES Definition: Let G= (V, E) be an undirected connected graph. A graph t= (V, E‘) of G is a spanning tree of G if T is a tree. Spanning trees have many applications. For example, they can be used to obtain independent set of circuit equation for an electric network. Another application of spanning trees arises from the property that a spanning tree is a minimal subgraph G‘ of G such that V(G‘) =V(G) and G‘ is connected. A minimal subgraph is one with fewest numbers of edges. Any connected graph with n vertices must have least n-1 edges and all connected graphs with n-1 edges are trees. If the nodes of G represent cities and the edges represent possible communication links connecting two cities, Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
93
then the minimum number of links needed to connect the cities is n-1. The spanning trees of G represent all feasible
choices.
In practical situations, the edges have weights assigned to them. These weights may represent the cost of construction, the length of the link, and so on. Given such weighted graph, one would then wish to select cities to have minimum total cost or minimum total length. In either case the links selected have to form a tree. If this is not so, then selection of links contain cycle. Removal of any of the links on this cycle results in a link selection of less cost connecting all the cities. So that the minimum cost spanning tree of G can be obtained. The cost of the spanning tree is the sum of all the edges in that tree.
1
28 8 2
10
16
14
7 6
3
24 18 25
12
5
22
4
(a)
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
94
1
2
10
16
14
7
3
6
25
12
5 4
22 (b)
Figure (a) represents a graph and (b) represents the minimum cost spanning tree.
PRIM’S ALGORITHM At first a peak is chosen in random order ,which for simplicity we accept it as V(1).This way two sets of pointers are initialized ,the 0={1} and P={2...n}. The O set (the O is taken from the Greek word Oristiko which means Terminal), will always contain the pointers of those peaks which are terminally attached in the T tree. The V(1) peak has already been attached in the T tree. The P set( P is taken from the Greek word Prosorino which means Temporary) contains the rest of the pointers for the peaks, P={1...n}-O which are those pointers who have not been terminally connected with a node of T, that means they are not attached in the tree. In every execution of the Prim Algorithm a new peak will be connected to the T tree, not always with their numbering order, for example the V(4) peak can be connected to the tree before the V(2) peak. The corresponding pointer of the newly connected peak will be deleted
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
95
from P set and will be inserted to the O set. When all peaks are connected there will be O={1,...n} and P=0.This of course means the end of the algorithm. The new peak every time will be chosen by using greedy method ,among all sides of G which connect peaks already inserted in the T (pointers in the O set ) tree with the rest of the peaks (pointers in the P set ),we choose one with minimum cost. If the chosen one is e(ij) then i belongs in the O set , V(i) peak is already in the T tree, j belongs in the P set , and V(j) peak has not been attached in the T tree yet. We put V(j) in the T tree, we change the O set by putting the j pointer, and we also change the P set by removing the j pointer. This may seem to you extremely complicated but it is easily understood by a set of examples. Pseudocode For The Prim Algorithm. INPUT :n,c[e(ij)],i,j belonging to {1,...,n}. OUTPUT :p(j) j=2,...,n (pointer of peaks j father in the T tree). STEPS 1. :(initializations). O={1} (V(1) root of the T tree). P={2,...,n} For every j belonging to P :e(j):=c[e(j1)] , p(j)=1 ( all peaks connected to the root. By definition of the cost function :e(j)=infinite when V(j) does not connect to V(1).). 2. Choose a k for which e(k)<=e(j) for every j belonging to P In case of tight choose the smaller
one.
Exchange the O set with the set produced by the union of the O set and {k} . Exchange the P set with the set produced by the difference of the P set and {k} .(P<-P-{k}) If P=0 then stop. 3. For every j belonging to P compare e(j) with c[e(kj)]. If e(j) >c[e(kj)] exchange e(j) <-c(e(kj)).Go back to Step 1.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
96
An example for Prim‘s algorithm
shortest paths from v0 to all destinations
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
97
1 2
7
6
3
5 4 (a)
1
2
10
7
3
6
5 4
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
98
1
2
10
7
3
6
12
5 4 (c)
1
2
10 14
7
3
6
12
5 4 (d)
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
99
1
2
10
16
14
7
3
6
12
5 4 (e)
1
2
10
16
14
7
3
6
12
5
22
4
(f)
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
100
Figure (a) shows the current graph with no edges selected. Edge (1, 6) is the first edge considered. It is included in the spanning tree being built. This yields the graph of fig (b). Next edge (3, 4) is selected and included in the tree (fig(c)). The next edge to be considered is (2, 7). Its inclusion in tree is being built does not create a cycle, so we get the graph of fig (d). Edge (2, 3) is considered next and included in the home fig (e). Of the edges not yet considered, (7, 4) has the least cost. It is considered next. Its inclusion in the tree results in a cycle, so this edge is discarded. Edge (5,4) is next edge to be added to the tree being built. This results in the configuration of fig (f). The next edge to be considered is (7, 5). It is discarded as it creates a cycle. Finally, edge (6, 5) is considered and included in the tree being built. This completes the spanning tree. The resulting tree has the cost 99.
KRUSKAL’S ALGORITHM
ALGORITHM ALGORITHM Kruskal ( E, cost, n, t) / / E is the set of edges in G. G has n vertices. Cost [u, v] is the cost of / / edge (u, v). t is the set of edges in the minimum – cost spanning tree. / / the final cost is returned. { Construct a heap out of the edge costs using Heapify ; for i := n do parent [i] := -1 ; / / Each vertex is in a different set. i := 0 ; mincost := 0.0 ; while ( i < n – 1 ) and ( heap not empty )) do { Delete a minimum cost edge (u, v) from the heap and reheapify using Adjust ; j := Find (u) ; k := Find (v) ; if (j ≠ k) then { i := i+1 ; t[ i, 1] := u ; t [i, 2 ] := v ; mincost := mincost + cost [u, v] ; Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
101
Union (j, k) ; } } If ( i ≠ n – 1 ) then write (― no spanning tree‖) ; else return mincost; }
COMPLEXITY The set t is the set of edges to be included in the minimum – cost spanning tree and i is the number of edges in t. The set t can be represented as a sequential list using a two – dimensional array t [ 1: n – 1, 1 : 2]. Edge (u, v) can be added to t by the assignments t[ i, 1] := u ; and y[ i, 2] := v; . In the while loop of line 10, edges are removed from the heap one by one in nondecreasing order of cost. Line 14 determines the sets containing u and v. If j ≠ k then vertices u and v are in different sets and edge (u, v) is included into t. The sets containing u and v are combined in line 20. If u = v the edge (u, v) is discarded as its inclusions into t would create a cycle. Line 23 determines whether a spanning tree was found. It follows that i ≠ n – 1 iff the graph G is not connected. The computing time is O( | E | log |E|), where e is the edge set of G.
JOB SEQUENCING WITH DEADLINES If we are given a set of n jobs. Associated with job i is integer deadline di ≥0 and a profit pi>0. For any job i the profit pi is earned if the job is completed by its deadline. To complete a job one has to process the job on the machine for one unit of time. Only one machine is available for processing jobs. A feasible solution for this problem is a subset J of such that each job in this can be completed by its deadline. The value of a feasible solution J is the sum of the profits of the jobs in J, or ∑i€J pi an optimal solution is a feasible solution with maximum value.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
102
Example:- Let n=4,(p1,p2,p3,p4)=(100,10,15,27) and (d1,d2,d3,d4)=(2,1,2,1). The feasible solutions and their values are: No
Feasible solution
Processing sequence
Value
1.
(1,2)
2,1
110
2.
(1,3)
1,3 or 3,1
115
3.
(1,4)
4,1
127
4.
(2,3)
2,3
25
5.
(3,4)
4,3
42
6.
(1)
1
100
7.
(2)
2
10
8.
(3)
3
15
9.
(4)
4
27
Solution 3 is optimal. In this solution only jobs 1 and 4 are processed and the value is 127. These jobs must be processed in the order job 4 followed by job 1. Thus the processing of job begins at time zero and that of job 1 is completed at time 2. High level description of job sequencing algorithm Algorithm Greedy job(d,J,n) //J is a set of jobs that can be completed by their deadlines. { J:={1}; for i:=2 to n do { if(all jobs in J U {i} can be completed by their headlines) then J:=J U {i}; } }
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
103
Greedy algorithm for sequencing unit time jobs with deadlines and profits Algorithm JS(d,j,n) //d[i]≥1, 1≤i≤n are the deadlines,n≥1. The jobs are ordered such that p[1]≥p[2]≥...≥p[n]. //J[i] is the ith job in the optimal solution,1≤i≤k. //Also at termination d[J][i]]≤d[J[i+1]],1≤i≤k. {
d[0] :=J[0]:=0;//initialize. J[1]:=1;// Include job 1. k:=1; for i:=2 to n do {
//consider jobs in nonincreasing order of p[i]. // Find position for i and check feasibility of insertion. r:=k; while((d[J[r]]>d[i]) and (d[J][r]]≠r)) do r:=r-1; if((d[J[r]]≤d[i]) and (d[i]>r)) then {
//Insert i into J[ ]. for q:=k to (r+1) step-1 do J[q+1]:=J[q]; J[r+1]:=i; k:=k+1;
} } return k; } The fuction JS is a correct implemention of the greedy-based method. Since d[i]≥1,the job with largest pi will always be in the greedy solution. As the jobs are in the nonincreasing Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
104
order of pi‘s,line 6 in the above algorithm includes the job with largest pi. The for loop of the line 8 considers the remaining job in the jobs in the order required by the greedy algorithm method. At all times, the set of jobs already included in the solution is maintained in J. If J[i],1≤i≤k, is the set already included,then J is such that d[J][i]]≤d[J[i+1]],1≤i≤k. When job i is being considered, the while loop determines where in J this job has to be inserted. The worst case computing time of Algorithm JS is θ(n2). The computing time of JS can be reduced from θ(n2) to nearby O(n2) by using disjoint set union and find algorithms and a different method to determine the feasibility of a partial solution.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
105
MODULE 4
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
106
DYNAMIC PROGRAMMING Dynamic programming is an algorithm design method that can be used when the solution to a problem can be viewed as the result of a sequence of decisions.Below are some of the examples of problems that can be viewed this way. 1)KNAPSACK-The solution to the knapsack problem can be viewed as the result of a sequence of decisions.We have to decide the values of xi,1 ≤ i ≤ n.An optimal sequence of decisions maximizes the objective function ∑pixi.It also satisfies the constraints ∑wixi≤m and 0 ≤ xi ≤1. 2)OPTIMAL MERGE PATTERNS-An optimal merge pattern tells us which pair of files should be merged at each step.An optimal sequence of decisions is a least cost sequence. 3)SHORTEST PATH-One way to find a shortest path from vertex i to vertex j in a directed graph G is to decide which vertex should be the second vertex,which the third and so on.An optimal sequence of decisions is one that results in a path of least length.
For some of the problems that may be viewed in this way,an optimal sequence of decisions can be found by making the decisions one at a time and never making an erroneous decision.This is true for all problems solvable by the greedy method.For many problems it is not possible to make stepwise decisions in such a manner that the sequence of decisions made is optimal.
One way to solve problems for which it is not possible to make a sequence of stepwise decisions leading to an optimal decision sequence is to try all possible decision sequences.We could enumerate all decision sequences and then pick out the best.But the time and space requirements may be prohibitive.Dynamic programming often drastically reduces the amount of enumeration by avoiding the enumeration of some decision sequences that cannot possibly be optimal.In dynamic programming an optimal sequence of decisions is obtained by making explicit appeal to the principle of optimality.
PRINCIPLE OF OPTIMALITY The principle of optimality states that an optimal sequence of decisions has the property that whatever the initial state and decisions are,the remaining decisions must constitute an optimal decision sequence with regard to the state resulting from the first decision.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
107
Thus, the essential difference between the greedy method and dynamic programming is that in the greedy method only one decision sequence is ever generated.In dynamic programming ,many decision sequences may be generated.However,sequences containing suboptimal subsequences cannot be optimal(if the principle of optimality holds)and so will not be generated as far as possible. Example:SHORTEST PATH Consider the shortest path problem.Assume that i,i1,i2,.........ik,j is a shortest path from i to j.Starting with the initial vertex i,a decision has been made to go to vertex i1.Following this decision the problem state is defined by vertex i1 and we need to find a path from i1 to j.It is clear that the sequence i1,i2,.......ik,j must constitute a shortest i1 to j path.If not ,let i1,r1,r2,........rq,j be a shortest i1 to j path.Then i,i1,r1,.......,rq,j is an i to j path that is shorter than the path i,i1,i2,.......,ik,j.Therefore the principle of optimality applies for this problem. Because of the use of principle of optimality , decision sequences containing subsequences that are suboptimal are not considered. Although the total number of different decision sequences is exponential in the number of decisions(if there are d choices for each of the n decisions to be made then there are dn possible sequences),dynamic programming algorithms often have a polynomial complexity.
Another important feature of dynamic programming approach is that optimal solutions to subproblems are retained so as to avoid recomputing their values.The use of these tabulated values make it natural to recast the recursive equations into an iterative algorithm.
MULTISTAGE GRAPHS EXPLANATION Theory A multistage graph G = (V, E) is a directed graph in which the vertices are partitioned into k>=2 disjoint sets Vi, 1<=i<=k. If (u, v) is an edge in E, then u ε Vi and v ε Vi+1 for some i, 1<=i
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
108
The multistage graph problem is to find a minimum-cost path from s to t. Each set Vi defines a stage in the graph. Because of the constraints on E, every path from s to t starts in stage 1, goes to stage 2, then to stage 3, then stage 4, etc., and eventually terminates in stage k. A dynamic programming formulation for a k-stage graph problem is obtained by using the principle of optimality. According to this principle a path (i, k) is said to be optimal if and only if the intermediate paths (i, j) and (j, k) are also optimal. The multistage graph problem has two approaches namely, forward and backward . In forward approach the resulting path is obtained by moving in the direction of destination from source, even though it appears in reverse. In the latter case it from destination to source tracing the lowest cost path. Equation
The cost of a path (i, j) is given by the equation
cost (i, j) = min {c (j, l) + cost (i+1, l)} l ε Vi+1 (j, l) ε E where j is a vertex in Vi.
Here cost (i, j) means i th level and the cost of edge from j th node to the last node.
EXAMPLE Consider the following figure. The graph is a 5 stage graph, with 12 vertices and the cost of each node is given. The aim is to find the minimum cost path from the first node to the last node. Figure V1
V2
V3
Department of Computer Science & Engineering
V4
V5
SJCET, Palai
Algorithm Analysis and Design (R 606)
109
4
2
6 2
9
6
1
7 1
9 5
4
2
3
4
7
3
7 7 7
11
4
2
3
10 00 0
5 11
2
8
8
12
5 6
11
5
Cost Calculation cost (4, 9) =4 cost (4,10) =2 cost (4,11) =5 cost (3,6) =cost from 6 th to 12 th node = min { 5+ cost (4, 9),6+ cost (4, 10) }=7 cost (3,7) = min { 4+ cost (4, 9),3+ cost (4, 10) }=5 cost (3,8) = min { 5+ cost (4, 10),6+ cost (4, 11) }=7 cost (2,2) = min { 4+ cost (3, 6),2+ cost (3, 7), 1+ cost (3, 8) }=7 cost (2,3) = min { 2+ cost (3, 6),7+ cost (3, 7)}=9 cost (2,4) = 11+cost (3, 8)=18 cost (2,5) = min { 11+ cost (3, 7),8+ cost (3, 8)}=15 cost (1,1) = min { 9+ cost (2, 2),7+ cost (2,3), 11+ cost (2, 4) ,2+ cost (2, 5)}=16 By selecting the least cost edges from each group we can determine which all edges will be involved in the minimum cost path.
Thus the minimum cost path in forward approach is (1, 2, 7, 10, 12) and in backward approach it is (1, 3, 6, 10, 12).Both have a cost of 16 each.
FORWARD APPROACH EXPLANATION:
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
110
A multistage graph G = (V, E) is a directed graph in which the vertices are partitioned into k>=2 disjoint sets Vi, 1<=i<=k. If (u, v) is an edge in E, then u ε Vi and v ε Vi+1 for some i, 1<=i
A dynamic programming formulation for a k-stage graph problem is obtained by using the principle of optimality. According to this principle a path (i, k) is said to be optimal if and only if the intermediate paths (i, j) and (j, k) are also optimal.
The multistage graph problem has two approaches namely, forward and backward . In forward approach the resulting path is obtained by moving in the direction of destination from source, even though it appears in reverse. In the latter case it from destination to source tracing the lowest cost path. By using the forward approach,we obtain the cost of a path (i, j) which is given by the following equation:
cost (i, j) = min {c (j, l) + cost (i+1, l)} l ε Vi+1 (j, l) ε E , where j is a vertex in Vi.
Here cost (i, j) means i th level and the cost of edge from j th node to the last node. Consider the example given below. This is a 5 stage graph, with 12 vertices and the cost of each node is given. The aim is to find the minimum cost path from the first node to the last node. This can be done by using the forward approach as shown below: EXAMPLE:
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
V1
V2
111
V3
V4
V5
4
2
6 2
9
6
1
7 1
9 5
4
2
3
4
7
3
7 7 7
11
4
2
3
10 00 0
5 11
2
8
8
12 2
5 6
11
5
CALCULATING THE MINIMUM COST: cost (4, 9) = cost from 4th node to the 9th node = 4 cost (4,10) = 2 cost (4,11) =5 cost (3,6) = min { 6+ cost (4, 9), 6+ cost (4, 10) }= 7 cost (3,7) = min { 4+ cost (4, 9), 3+ cost (4, 10) }= 5 cost (3,8) = min { 5+ cost (4, 10), 6+ cost (4, 11) }= 7 cost (2,2) = min { 4+ cost (3, 6), 2+ cost (3, 7), 1+ cost (3, 8) }= 7
While calculating the value of cost (2,2) the values of cost (3,6), cost (3,7) and cost (3,8) have been reused so as to avoid their re-computation.
cost (2,3) = min { 2+ cost (3, 6), 7+ cost (3, 7)}= 9
cost (2,4) = min{11+cost (3, 8)}= 18 Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
112
cost (2,5) = min { 11+ cost (3, 7), 8+ cost (3, 8)}= 15
cost (1,1) = min { 9+ cost (2, 2), 7+ cost (2,3), 11+ cost (2, 4) , 2+ cost (2, 5)}= 16
A minimum cost s to t path has a cost of 16. Thus, the cost of forward approach is= 16.
By selecting the least cost edges from each group we can determine which all edges will be involved in the minimum cost path.
Thus the minimum cost path in forward approach is (1, 2, 7, 10, 12) which has the cost of 16. It is represented using dotted lines.
This is the multistage graph forward approach problem.
BACKWARD APPROACH : The Multistage graph problem can be solved using backward approach in the following manner. Let bp(i,j) be a minimum-cost path from vertex s to a vertex j in Vi . let bcost(i,j) be the cost of bp(i,j). From the backward approach we obtain
bcost(i,j) = min {bcost(i-1,l) + c(l,j)} l Є Vi-1Є E
Algorithm in psedocode corresponding to obtain a minimum-cost s-t graph is BGraph.(Algorithm 1.1) The first subscript on bcost, p and d are omitted for the same reasons as before. This algorithm has the same complexity as FGraph provided G is now represented by itsinverse adjacency lists (i.e., for each vertex v we have a list of vertices w such thatЄ E
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
113
ALGORITHM
1. Algorithm BGraph(G,k,n,p) 2. // Same function as FGraph 3. { 4.
bcost[1] :=0.0;
5.
for j :=2 to n do
6.
{ / / Compute bcost[j].
7.
Let r be such that is an edge of G is an edge of and bcost is an edge of
8.
G and bcost[r] + c[r,j] is minimum;
9.
bcost[j] :=bcost[r] + c[r,j];
10.
d[j] := r;
11.
}
12.
/ / Find a minimum-cost path.
13.
p[1] := 1; p[k] :=n;
14.
for j := k – 1 to 2 do p[j] := d[p[j+1]];
15.
}
It should be easy to see that both FGraph and BGraph work correctly even on a more generalized version of multistage graphs. In this generalization, the graph is permitted to have edges such that u Є Vi , v Є Vj and i< j. In the pseudocodes FGraph and BGraph, bcost(i,j) is set to ∞ for any Є E. When programming these pseudocodes, one could use the maximum allowable floating point number for ∞. If the weight of any such edge is added to some other costs, a floatin point overflow might occur. Care should be taken to avoid such overflows.
Eg: d(B, T) = min{9+d(D, T), 5+d(E, T), 16+d(F, T)} = min{9+18, 5+13, 16+2} = 18. d(C, T) = min{ 2+d(F, T) } = 2+2 = 4 Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
114
d(S, T) = min{1+d(A, T), 2+d(B, T), 5+d(C, T)} = min{1+22, 2+18, 5+4} = 9. The above way of reasoning is called backward reasoning.
9
B
5
D E
16
F
d(D, T) d(E, T)
T
d(F, T)
Backward
approach
(forward reasoning) d(S, A) = 1 d(S, B) = 2 d(S, C) = 5 d(S,D)=min{d(S, A)+d(A, D),d(S, B)+d(B, D)} = min{ 1+4, 2+9 } = 5 d(S,E)=min{d(S, A)+d(A, E),d(S, B)+d(B, E)} = min{ 1+11, 2+5 } = 7 d(S,F)=min{d(S, A)+d(A, F),d(S, B)+d(B, F)} = min{ 2+16, 5+2 } = 7 d(S,T) = min{d(S, D)+d(D, T),d(S,E)+d(E,T), d(S, F)+d(F, T)} = min{ 5+18, 7+13, 7+2 } =9 Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
115
Forward approach and backward approach: Note that if the recurrence relations are formulated using the forward approach then the relations are solved backwards . i.e., beginning with the last decision On the other hand if the relations are formulated using the backward approach, they are solved forwards. Sample Graph and Simulation of the Algorithm
Stage
Stage
Stage
Stage
Stage
Stage
I
II
III
IV
V
VI
8 2
12
5
9
1 3
4
13
6
7
10 00 0
15
14
11
SIMULATION OF THE SOLUTION USING BACKWARD COSTS Format: COST(stage, node) = minimum cost of traveling to the node in stage from the source(node 1). STEP I COST(I,1) = 0 STEP II COST(II,2) = COST(I,1) + cost(1,2) = 0 + 10 = 10 Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
116
COST(II,3) = COST(I,1) + cost(1,3) = 0 + 20 = 20 COST(II,4) = COST(I,1) + cost(1,4) = 0 + 30 = 30 STEP III COST(III,5) = min{COST(II,2) + cost(2,5), COST(II,3) + cost(3,5), COST(II,4) + cost(4,5)} =min{10 +10, 20+40, 30+∞} = 20---via the path 1-2-5 COST(III,6) = min{COST(II,2) + cost(2,6), COST(II,3) + cost(3,6), COST(II,4) + cost(4,6)} =min{10 +20, 20+∞, 30+40} = 20---via the path 1-3-6 COST(III,7) = min{COST(II,2) + cost(2,7), COST(II,3) + cost(3,7), COST(II,4) + cost(4,7)} =min{10 +30, 20+50, 30+30} = 40---via the path 1-2-7 STEP IV COST(IV,8)=min{COST(III,5) + cost(5,8), COST(III,6) + cost(6,8), COST(III,7) + cost(7,8)} =min{20+10, 20+∞ ,40+∞ } Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
117
=30---via the path 1-2-5-8 COST(IV,9)=min{COST(III,5) + cost(5,9), COST(III,6) + cost(6,9), COST(III,7) + cost(7,9)} =min{20+20, 20+20 ,40+∞ } =40---via the path 1-2-5-9 or via the path 1-3-6-9 COST(IV,10)=min{COST(III,5) + cost(5,10), COST(III,6) + cost(6,10), COST(III,7) + cost(7,10)} =min{20+10, 20+∞ ,40+∞ } =30---via the path 1-2-5-10 COST(IV,11)=min{COST(III,5) + cost(5,11), COST(III,6) + cost(6,11), COST(III,7) + cost(7,11)} =min{20+30, 20+30 ,40+30 } =50---via the path 1-2-5-11 or via the path 1-3-6-11 STEP V COST(V,12)=min{COST(IV,8) + cost(8,12), COST(IV,9) + cost(9,12), COST(IV,10) + cost(10,12), COST(IV,11) + cost(11,12)} =min{30+10 ,40+∞ ,30+∞,50+∞} = 40—via the path 1-2-5-8-12 Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
118
COST(V,13)=min{COST(IV,8) + cost(8,13), COST(IV,9) + cost(9,13), COST(IV,10) + cost(10,13), COST(IV,11) + cost(11,13)} =min{30+20 ,40+20 ,30+10,50+10} = 40—via the path 1-2-5-8-13 COST(V,14)=min{COST(IV,8) + cost(8,14), COST(IV,9) + cost(9,14), COST(IV,10) + cost(10,14), COST(IV,11) + cost(11,14)} =min{30+30 ,40+10 ,30+20,50+30} =50---via the path 1-2-5-10-14 or via 1-2-5-9-14 or 1-3-6-9-14 STEP VI COST(VI,15)=min{COST(V,12)+cost(12,15), COST(V,13)+cost(13,15), COST(V,14)+cost(14,15)} =min{40+20 ,40+10 ,50+30} =50---via the path 1-2-5-8-13-15
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
119
ALL PAIRS SHORTEST PATH Finding all pairs shortest path consists of finding the shortest distance between every pair of nodes in a possibly directed graph. Various means of doing so are known, and the following list gives a few of the common methods: Floyd-Warshall algorithm is an elegant, quickly implementable O(n3) algorithm (Assumes absence of negatively-weighed cycles). Johnson's algorithm is harder to implement, but might perform better for sparse graphs. Algorithms for single source problem might also be repeatedly used, although they often perform worse or are harder to optimize
FLOYD-WARSHELL ALGORITHM In computer science, the Floyd–Warshall algorithm (sometimes known as the WFI Algorithm or Roy–Floyd algorithm, since Bernard Roy described this algorithm in 1959) is a graph analysis algorithm for finding shortest paths in a weighted, directed graph. A single execution of the algorithm will find the shortest paths between all pairs of vertices. The Floyd–Warshall algorithm is an example of dynamic programming
Algorithm The Floyd-Warshall algorithm compares all possible paths through the graph between each pair of vertices. It is able to do this with only V3 comparisons. This is remarkable considering that there may be up to V2 edges in the graph, and every combination of edges is tested. It does so by incrementally improving an estimate on the shortest path between two vertices, until the estimate is known to be optimal. Consider a graph G with vertices V, each numbered 1 through N. Further consider a function shortestPath(i,j,k) that returns the shortest possible path from i to j using only vertices 1 through k as intermediate points along the way. Now, given this function, our goal is to find the shortest path from each i to each j using only nodes 1 through k + 1. There are two candidates for this path: either the true shortest path only uses nodes in the set (1...k); or there exists some path that goes from i to k + 1, then from k + 1 to j that is better. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
120
We know that the best path from i to j that only uses nodes 1 through k is defined by shortestPath(i,j,k), and it is clear that if there were a better path from i to k + 1 to j, then the length of this path would be the concatenation of the shortest path from i to k + 1 (using vertices in (1...k)) and the shortest path from k + 1 to j (also using vertices in (1...k)). Therefore, we can define shortestPath(i,j,k) in terms of the following recursive formula
This formula is the heart of Floyd Warshall. The algorithm works by first computing shortestPath(i,j,1) for all (i,j) pairs, then using that to find shortestPath(i,j,2) for all (i,j) pairs, etc. This process continues until k=n, and we have found the shortest path for all (i,j) pairs using any intermediate vertices.
Pseudocode Conveniently, when calculating the kth case, one can overwrite the information saved from the computation of k − 1. This means the algorithm uses quadratic memory. Be careful to note the initialization conditions: 1 /* Assume a function edgeCost(i,j) which returns the cost of the edge from i to j 2
(infinity if there is none).
3
Also assume that n is the number of vertices and edgeCost(i,i)=0
4 */ 5 6 int path[][]; 7 /* A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path 8
from i to j using intermediate vertices (1..k-1). Each path[i][j] is initialized to
9 edgeCost(i,j) or infinity if there is no edge between i and j. 10 */ 11 12 procedure FloydWarshall () 13 for k: = 1 to n Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) 14 15
121
for each (i,j) in {1,..,n}2 path[i][j] = min ( path[i][j], path[i][k]+path[k][j] );
Analysis To find all n2 of
from those of
requires 2n2 bit operations. Since we begin with
and compute the sequence of n zero-one matrices the total number of bit operations used is
,
, ...,
,
. Therefore, the complexity of
the algorithm is Θ(n3) and can be solved by a deterministic machine in polynomial time
Applications and generalizations The Floyd–Warshall algorithm can be used to solve the following problems, among others: Shortest paths in directed graphs (Floyd's algorithm). Transitive closure of directed graphs (Warshall's algorithm). In Warshall's original formulation of the algorithm, the graph is unweighted and represented by a Boolean adjacency matrix. Then the addition operation is replaced by logical conjunction (AND) and the minimum operation by logical disjunction (OR). Finding a regular expression denoting the regular language accepted by a finite automaton (Kleene's algorithm) Inversion of real matrices (Gauss-Jordan algorithm). Optimal routing. In this application one is interested in finding the path with the maximum flow between two vertices. This means that, rather than taking minima as in the pseudocode above, one instead takes maxima. The edge weights represent fixed constraints on flow. Path weights represent bottlenecks; so the addition operation above is replaced by the minimum operation. Testing whether an undirected graph is bipartite. Fast computation of Pathfinder Networks. Maximum Bandwidth Paths in Flow Networks
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
122
JOHNSON’S ALGORITHM Johnson's algorithm is a way to find shortest paths between all pairs of vertices in a sparse directed graph. It allows some of the edge weights to be negative numbers, but no negativeweight cycles may exist.
Johnson's algorithm consists of the following steps: 1. First, a new node q is added to the graph, connected by zero-weight edge to each other node. 2. Second, the Bellman-Ford algorithm is used, starting from the new vertex q, to find for each vertex v the least weight h(v) of a path from q to v. If this step detects a negative cycle, the algorithm is terminated. 3. Next the edges of the original graph are reweighted using the values computed by the Bellman-Ford algorithm: an edge from u to v, having length w(u,v), is given the new length w(u,v) + h(u) −h(v). 4. Finally, for each node s, Dijkstra's algorithm is used to find the shortest paths from s to each other vertex in the reweighted graph. In the reweighted graph, all paths between a pair s and t of nodes have the same quantity h(s) -h(t) added to them, so a path that is shortest in the original graph remains shortest in the modified graph and vice versa. However, due to the way the values h(v) were computed, all modified edge lengths are non-negative, ensuring the optimality of the paths found by Dijkstra's algorithm. The distances in the original graph may be calculated from the distances calculated by Dijkstra's algorithm in the reweighted graph by reversing the reweighting transformation.
Analysis The time complexity of this algorithm, using Fibonacci heaps in the implementation of Dijkstra's algorithm, is O(V2log V + VE): the algorithm uses O(VE) time for the Bellman-Ford stage of the algorithm, and O(V log V + E) for each of V instantiations of Dijkstra's algorithm. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
123
Thus, when the graph is sparse, the total time can be faster than the Floyd-Warshall algorithm, which solves the same problem in time O(V3).
Example The first three stages of Johnson's algorithm are depicted in the illustration below.
The graph on the left of the illustration has two negative edges, but no negative cycles. At the center is shown the new vertex q, a shortest path tree as computed by the Bellman-Ford algorithm with q as starting vertex, and the values h(v) computed at each other node as the length of the shortest path from q to that node. Note that these values are all non-positive, because q has a length-zero edge to each vertex and the shortest path can be no longer than that edge. On the right is shown the reweighted graph, formed by replacing each edge weight w(u,v) by w(u,v) + h(u) −h(v). In this reweighted graph, all edge weights are non-negative, but the shortest path between any two nodes uses the same sequence of edges as the shortest path between the same two nodes in the original graph. The algorithm concludes by applying Dijkstra's algorithm to each of the four starting nodes in the reweighted graph.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
124
SHORTEST PATH PROBLEM
A graph with 6 vertices and 7 edges In graph theory, the shortest path problem is the problem of finding a path between two vertices (or nodes) such that the sum of the weights of its constituent edges is minimized. An example is finding the quickest way to get from one location to another on a road map; in this case, the vertices represent locations and the edges represent segments of road and are weighted by the time needed to travel that segment. Formally, given a weighted graph (that is, a set V of vertices, a set E of edges, and a realvalued weight function f : E → R), and one element v of V, find a path P from v to each v' of V so that
is minimal among all paths connecting v to v' . The problem is also sometimes called the single-pair shortest path problem, to distinguish it from the following generalizations: The single-source shortest path problem, in which we have to find shortest paths from a source vertex v to all other vertices in the graph. The single-destination shortest path problem, in which we have to find shortest paths from all vertices in the graph to a single destination vertex v. This can be reduced to the single-source shortest path problem by reversing the edges in the graph.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
125
The all-pairs shortest path problem, in which we have to find shortest paths between every pair of vertices v, v' in the graph. These generalizations have significantly more efficient algorithms than the simplistic approach of running a single-pair shortest path algorithm on all relevant pairs of vertices.
Algorithms The most important algorithms for solving this problem are: Dijkstra's algorithm solves the single-pair, single-source, and single-destination shortest path problems. Bellman-Ford algorithm solves single source problem if edge weights may be negative. A* search algorithm solves for single pair shortest path using heuristics to try to speed up the search. Floyd-Warshall algorithm solves all pairs shortest paths. Johnson's algorithm solves all pairs shortest paths, and may be faster than FloydWarshall on sparse graphs. Perturbation theory finds (at worst) the locally shortest path.
Applications Shortest path algorithms are applied to automatically find directions between physical locations, such as driving directions on web mapping websites like Mapquest or Google Maps. If one represents a nondeterministic abstract machine as a graph where vertices describe states and edges describe possible transitions, shortest path algorithms can be used to find an optimal sequence of choices to reach a certain goal state, or to establish lower bounds on the time needed to reach a given state. For example, if vertices represents the states of a puzzle like a Rubik's Cube and each directed edge corresponds to a single move or turn, shortest path algorithms can be used to find a solution that uses the minimum possible number of moves. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
126
In a networking or telecommunications mindset, this shortest path problem is sometimes called the min-delay path problem and usually tied with a widest path problem. For example, the algorithm may seek the shortest (min-delay) widest path, or widest shortest (min-delay) path. A more lighthearted application is the games of "six degrees of separation" that try to find the shortest path in graphs like movie stars appearing in the same film. Other applications include "operations research, plant and facility layout, robotics, transportation, and VLSI design".
Related problems For shortest path problems in computational geometry, see Euclidean shortest path. The traveling salesman problem is the problem of finding the shortest path that goes through every vertex exactly once, and returns to the start. Unlike the shortest path problem, this problem is NP-complete and, as such, is believed not to be efficiently solvable (see P = NP problem) . The problem of finding the longest path in a graph is also NP-complete. The Canadian traveller problem and the stochastic shortest path problem are generalizations where either the graph isn't completely known to the mover, changes over time, or where actions (traversals) are probabilistic. The problems of recalculation of shortest paths arises if some graph transformations (e.g., shrinkage of nodes) are made with a graph
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
127
LOWER BOUND THEORY Our main task for each problem is to obtain a correct and efficient solution. If two algorithms solving the same problem were discovered and their times differed by an order of magnitude, then the one with the smaller order was generally regarded as superior. To establish a given algorithm in the most efficient way, a function g(n) , that is a lower bound on the time, is discovered. If we have an algorithm whose computing time is the same order as g(n), then we know that asymptotically we can do no better. There is a mathematical notation for expressing lower bounds. If f(n) is the time for some algorithm, then we write f(n)=Ω(g(n)) to mean that g(n) is a lower bound for f(n). Formally this equation can be written if there exist positive constants c and n0 such that |f(n)| ≥ c|g(n)| for all n > n0. In addition to developing lower bounds to within a constant factor, we are also concerned with determining more exact bounds. Deriving good lower bounds is often more difficult than devising efficient algorithms. Perhaps this is because a lower bound states a fact about all possible algorithms for solving a problem. Usually we cannot enumerate and analyze all these algorithms, so lower bound proofs are often hard to obtain. However , for many problems it is possible to easily observe that a lower bound identical to n exists, where n is the number of inputs( or possibly outputs) to the problem. For example, consider all algorithms that find the maximum of an unordered set of n integers. Clearly every integer must be examined at least once, so Ω(n) is a lower bound for any algorithm that solves this problem. Or, suppose we wish to find an algorithm that efficiently multiplies two n×n matrices. Then Ω(n2) is a lower bound on any such algorithm since there are 2n2 inputs that must be examined and n2 outputs that must be computed. Bounds such as these are often reffered to as trivial lower bounds because they are so easy to obtain. We know how to find the maximum of n elements by an algorithm that uses only n-1 comparisons so there is no gap between the upper and lower bounds for this problem. But for matrix multiplication the best known algorithm requires O(n2+€) operations (€ > 0) , and so there is no reason to believe that a better method cannot be found.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
128
COMPARISON TREES FOR SEARCHING AND SORTING A comparison tree for binary search on an array is a binary tree that depicts all possible search paths.i.e it shows all different sequences of comparisons undertaken by binary search when searching for keys that may or may not be present in the array.
X:A(1)
Failure
X: A(2)
Failure
X:A(n)
Failure
Failure
Suppose that we are given a set S of distinct values on which an ordering relation < holds. The sorting problem calls for determining a permutation of the integers 1 to n, say p(1) to p(n), such that the n distinct values from S stored in A[1:n] satisfy A[p(1)] < A[p(2)] <. .. .< A[p(n)]. The ordered searching problem asks whether a given element x E S occurs within the elements in A[1:n], then we are to determine an I between 1 and n such that A[i] = x. The merging problem assumes that two ordered sets of distinct inputs from S are given in A[1:m] and B[1:n] such that A[1] < . . . < A[m] and B[1] < . . . B[n]; these m+n values are to be rearranged into an array C[1:m+n] so that C[1] < . . . < C[m+n]. For all these problems we restrict the class of algorithms we are considering to those which work solely by making comparisons between elements. No arithmetic involving elements is permitted, though it is possible for the algorithm to move elements around.Thes algorithms are referred to as
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
129
comparison based algorithms. We rule out algorithms such as radix sort that decompose the values into subparts. a)
Ordered Searching In obtaining the lower bound for the ordered searching problem, we consider
only those comparison based algorithms in which every comparison between two elements of S is of the type ―compare x and A[i]‖. Each internal node in the binary tree represents a comparison between x and an A[i], or x > A[i].If x=A[i],the algorithm terminates. The left branch is taken if x < A[i], and the right is taken if x > A[i].If the algorithm terminates following a left or right branch , then no I has been found such that x = A[i] and the algorithm must declare the search successful. b)
Sorting We can describe any sorting algorithm that satisfies the restrictions of the
comparison tree model by a binary tree. Consider the case in which the n numbers A[1:n] to be sorted are distinct.Now,any comparison between A[i] and A[j] must result in one of two possibilities: either A[i] < A[j] or A[i] > A[j].So, the comparison tree is a binary tree in which each internal node is labeled by the pair i:j which represents the comparison of A[i] with A[j].If A[i] < A[j] , then the algorithm proceeds down the left branch of the tree; otherwise right branch. The external nodes represent termination of the algorithm. Associate with every path from the root to an external node is a unique permutation. c)
Selection Any comparison tree that models comparison-based algorithms for finding
the maximum of n elements has at least 2^ n-1 external nodes since each path from the root to an external node must contain at least n-1 internal nodes. This implies at least n-1 comparisons for otherwise at least two of the input items never lose a comparison and the largest is not yet found.
Comparison trees
comparison tree n! leaves : every permutation must be a leaf -case # comparisons = height of tree
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
130
a1a2a3 : a1< a2?
a1a2a3 : a2
a1a2a3
a2a1a3 : a1< a3?
a1a3a2 : a1< a3?
a1a3a2
a2a1a3 a2a3a1 : a2< a3?
a3a1a2
a2a3a1
a3a2a1
Comparison tree for insertion sort of three items
LOWER BOUND FOR COMPARISON-BASED SORTING It is generally much more difficult to show that an algorithm is ‗‗best possible‘‘ for a certain task, than to come up with a ‗‗good‘‘ algorithm for that task. In the latter case, one need only argue about one algorithm— the one that is supposedly ‗‗good‘‘; in the former case, one must argue about all possible algorithms — even those which one knows nothing about! To answer the question ‗‗what‘s the best way to do a job‘‘ we must start by fixing the set of tools that may be used to do the job. For the problem at hand, sorting, we will take pair wise comparisons of keys as the available tools. Of course, this leaves out of consideration Bin sorting (which is not based on key comparisons). But, in a sense, we can justify this on the ground that Bin sorting is not a ‗‗general‘‘ sorting method: it is applicable only if keys have a particular form. At any rate, it‘s important to keep in mind that the result Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
131
we are about to present only applies to sorting algorithms based on comparisons. Suppose we want to sort n keys K1 , K2 , . . . , Kn . Let‘s assume that all keys are distinct, so that for any Ki , Kj where i
j , either Ki < Kj or Ki > Kj. The main theoretical
device we‘ll use to analyze our problem is a decision (or comparison) tree. This is a useful way of representing any comparison-based algorithm that sorts n keys (for any given n). Before introducing the formal definition, let‘s develop some intuition about decision trees by studying an example. Example 1: Below is a decision tree that corresponds to one possible algorithm for sorting 3 keys, K1 , K2 , K3 .
1
1:2
< > 2:3
<
2:3
>
< >
321
1:3 123 1: 3
<
>
> 213
231
< 132 312
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
132
The internal nodes of this tree correspond to comparisons the algorithm makes. The labels in those nodes, specify which keys are to be compared. For example the label "1:2" of the root indicates that K1 is to be compared with K2. Depending on the outcome of the comparison in a node, the left or the right branch out of that node is taken. The label of each leaf is the permutation specifying how to rearrange the keys to get them sorted. For example, consider the node with label "2,3,1". This means that K2K2); then from node "2:3" to the left (signifying that K2 K3). These three comparisons imply that K2
c, K
a, K3=b
(where a < b < c). The execution starts at the root of the tree. The node there specifies that K1 and K2 are to be compared. Since K1>K2, we take the right branch from the root and arrive at the "2:3" node. This indicates we must compare K2 to K3 and since K2K3 and therefore we take the right branch which leads us to the leaf labeled "2,3,1". This indicates that the keys in sorted order are K2 K3} if K1 K3} sorted order of keys is K3 , K1 , K2 else {K1>K2} if K2 K3} sorted order of keys is K2 , K3 , K1 else {K2>K3} sorted order of keys is K3 , K2 , K1 Using the intuition we have gained by studying this example, let us now give the formal Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
133
definition of a decision tree. Definition 1: A decision tree of order n is a binary tree so that (1) It has n! leaves, each labeled by a different permutation of 1, 2, . . . , n. (2) Internal nodes are labeled by pairs of indices of the form ‗‗i : j
i
j
n.
(3) In the path from the root to a leaf p (1) p (2) . . . p (n) (p is a permutation of 1, 2, . . . , n) there is either a node ‗‗p (i) : p (i from that node to its left child — or ‗‗p (i from that node to its right child —
— in which case the path goes i)‘‘ — in which case the path goes i < n. (The path may contain other
nodes too but must contain at least these.) The idea is that leaves correspond to the possible outcomes of sorting n distinct keys. Internal node ‗‗i : j‘‘ corresponds to the comparison of Ki and Kj. If the outcome is Ki < Kj then the left subtree of the node ‗‗i : j‘‘ contains the subsequent comparisons made until the order of the keys is determined. Symmetrically, if the outcome is Ki > Kj , the right subtree of ‗‗i : j‘‘ contains the subsequent comparisons. Part (3) of the definition essentially requires that every relationship determined by the algorithm must have been established by actual comparisons: the algorithm cannot ‗‗guess‘‘. Any comparison-based algorithm for sorting n keys corresponds to a decision tree of order n. The execution of the algorithm on input sequence of keys K1, K2, . . . , Kn follows the path from the root to the leaf labeled by the permutation p such that Kp (1) < Kp (2) < . . . < Kp (n). Note that for a given sorting algorithm we need a different -3decision tree for each n to represent all possible executions of that algorithm when the input consists of n keys. Example 2: Consider the algorithm for insertion sort: INSERTION -SORT(A) begin for i := 2 to n do for j := i down to 2 do if A[ j] < A[ j 1] then A[ j
A[ j 1]
else break end
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
134
WORST CASE LOWER BOUND ON THE NUMBER OF COMPARISONS Let Cn denote the minimum number of comparisons required to sort n keys. For any decision tree, the worst case number of comparisons required by the algorithm represented by that tree is precisely the height of the tree. Lemma: Any binary tree of height h has at most 2h leaves. Proof: Trivial induction on h. By definition, any decision tree of order n is a binary tree with n! leaves. Thus, by the lemma, it must have height at least
n
Cn
n
approximation says that n Cn
n (n/e)n. Thus, n (n/e)n
from which it follows that Cn
n/e)n = n log n n log e n log n).
AVERAGE CASE LOWER BOUND ON THE NUMBER OF COMPARISONS Consider a decision tree of order n representing some sorting algorithm. If we assume that all initial arrangements of the keys to be sorted are equally likely, the average case number of comparisons performed by that algorithm is equal to the external path length of the decision tree divided by the number of leaves in the tree.† The following fact can be easily proved: Fact 2: The tree that minimizes the external path length has all leaves in at most two depths d and d 1, for some d. By Facts 1 and 2 we may assume that in the decision tree that minimizes the average number of comparisons, all leaves have depth d or d 1 for some d. Let Cn be the minimum average case number of comparisons needed to sort n keys. Also, let Nd and Nd−1 be the number of leaves in the corresponding decision tree at depth d and d 1 respectively. Recall that the number of leaves in T is n!. Thus we have Cn = [(d 1) Nd− d Nd ]/n! (1) But we have: Nd Nd−1 = n! (2) and Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) Nd
135
Nd−1 =2d (3)
Equation (2) says that the total number of leaves in T is n!. For equation (3) note that if we gave 2 children to each leaf of depth d 1, we would get the maximum possible number of nodes at depth d, which is 2d . † Recall that the external path length of the tree is the sum of the depths of all leaves. -5Solving (2) and (3) for Nd and Nd−1, we get: Nd =2 n
d (4)
and Nd−1 =2d n! (5) Substituting (4) and (5) in (1) we obtain: Cn = [(d 1) Nd− d Nd ]/n! = (d n n
d )/n!
But d
n
= log n
Cn = (n! log n n
n
n! 2e )/n!
= log n Cn
n
Hence, Cn
n(n/e)n
n/e)n = n log n n log e.
n log n).
Therefore, any comparison-
n log n) comparisons
both in the worst and in the average case.
ORACLES AND ADVERSARY ARGUMENTS
One of the proof techniques that is useful for obtaining lower bounds consists of making use of an oracle. The most famous oracle in the history was called the Delphic oracle, located in Delphi in Greece. This oracle can still be found, situated in the side of a hill embedded in some rocks. In olden times people would approach the oracle and ask it a question. After some period of time elapsed, the oracle would reply and a caretaker would interpret the oracle‘s answer.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
136
A similar phenomenon takes place when we use an oracle to establish a lower bound. Given some model of computation such as comparison trees, the oracle tells us the outcome of each comparison. To derive a good lower bound, the oracle tries its best to cause the algorithm to work as hard as it can. It does this by choosing as the outcome of the next test, the result that causes the most work to be required to determine the final answer. And by keeping tracks of the work that is done, a worst-case lower bound for the problem can be derived.
MERGING Now we consider the merging problem. Given the sets A[l:m] and B[l:n], Where the item in A and the item in B are sorted, we investigate lower bounds for algorithms that merge these two sets to give a single sorted set. As was the case of sorting, we assume that all the m+n elements are distinct and that A[1]
) ways that the
A‘s and B‘s can merge together while preserving the ordering within A and B. For example, if m=3, n=2, A[i]=x,A[2]=y,A[3]=z,B[1]=u,B[2]=v, there are (
)=10 ways in which A and
B merge: u,v,x,y,z;u,x,v,y,z;u,x,y,v,z;u,x,y,z,u;x,u,v,y,z;x,u,y,v,z;x,u,y,z,v;x,y,u,v,z;x,y,u,z,v; and x,y,u,v. Thus if we use comparison trees as our model for merging algorithm, then there will be external nodes, and therefore at least [log
] comparisons are required by any comparison-
based merging algorithm. The conventional merging algorithm takes m+n-1 comparisons. If we let MERGE(m,n) be the minimum number of comarisons needed to merge m items, then we have the inequality [log
]
MERGE(m,n)-1
The exercises show that these upper and lower bounds can get arbitrarily far apart as m gets much smaller than n. This should not be a surprise becoz the conventional algorithm is designed to work best when m and n binary insertion would required the fewest number of comparisons needed to merge A[1] into B[1],…..,B[n]. When m and n are equal, the lower bound given by the comparison tree model is too and the number of comparisons for the conventional merging algorithm can be shown to be optimal.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
137
Theorm: MERGE(m,m)=2m-1, for m≥1. Proof: Consider any algorithm that merges the two sets A[1] <……..< A[m] and B[1]<…….
INSERTION SORT If the first few objects are already sorted, an unsorted object can be inserted in the sorted set in proper place. This is called insertion sort. An algorithm consider the elements one at a time, inserting each in its suitable place among those already considered (keeping them sorted). Insertion sort is an example of an incremental algorithm; it builds the sorted sequence one number at a time. INSERTION_SORT (A) 1. For j = 2 to length [A] do 2.
key = A[j]
3.
{Put A[j] into the sorted sequence A[1 . . j-1]
4.
i ← j -1
5.
while i > 0 and A[i] > key do
6.
A[i+1] = A[i]
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) 7. 8.
138
i = i-1 A[i+1] = key
Analysis Best-Case The while-loop in line 5 executed only once for each j. This happens if given array A is already sorted. T(n) = an + b = O(n) It is a linear function of n. Worst-Case The worst-case occurs, when line 5 executed j times for each j. This can happens if array A starts out in reverse order T(n) = an2 + bc + c = O(n2) It is a quadratic function of n.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
139
The graph shows the n2 complexity of the insertion sort.
Stability Since multiple keys with the same value are placed in the sorted array in the same order that they appear in the input array, Insertion sort is stable.
Extra Memory This algorithm does not require extra memory. For Insertion sort we say the worst-case running time is θ(n2), and the best-case running time is θ(n). Insertion sort use no extra memory it sort in place. The time of Insertion sort is depends on the original order of a input. It takes a time in Ω(n2) in the worst-case, despite the fact that a time in order of n is sufficient to solve large instances in which the items are already sorted.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
140
Implementation void insertionSort(int numbers[], int array_size) { int i, j, index; for (i=1; i < array_size; i++) {
index = numbers[i]; j = i; while ((j > 0) && (numbers[j-1] > index)) {
numbers[j] = numbers[j-1]; j = j - 1;
} numbers[j] = index; } }
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
141
Adversary argument • Suppose we have an algorithm we think efficient. • Image an adversary tries to prove otherwise. • At each point in the algorithm, whenever an decision (i.e., key comparison) is made, the adversary tells us the result of the decision. • The adversary chooses the answer which tries to force the algorithm work hard (i.e., do a lot of decision, or to say, the answer releases as less new information as possible). • You can think the adversary is constructing a ―bad‖ input while it is answering the questions. The only requirement on the answers is that they must be internally consistent. • If the adversary can force the algorithm to perform f(n) steps, then f(n) is the lower bound, i.e, at least how many steps in the worst case. Simply Put: • Playing a guessing game between you and your friend. – You are to pick up a date, and the friend will try to guess the date by asking YES/NO questions. – Your purpose is forcing your friend to ask as many questions as possible. • To question ―is it in winter‖, your answer should be NO. • To question ―is the first letter of the month‘s name in the first half of the alphabet‖? Your answer should be YES. • Idea: – You did not pick up a date in advance at all, but – Construct a date according to the questions. The – The requirement is that the finally constructed date should be consistent to all your answers to the questions. – Looks like cheating, but it is a good way to find the lower bound.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
142
Lower Bound for Algorithms that remove at most One Inversion per Comparison Insertion Sort, either does nothing or moves the key in the jth slot to the (j+1)st slot. By moving the key in the jth slot up one slot, we have remedied the fact that ‗x‘ (number being compared with) should come before the key. However, this is all we have accomplished. We show that all sorting algorithms that sort only by comparisons of keys, and accomplish such a limited amount of rearranging after each time, require at least quadratic time. We obtain our results under the assumption that the keys to be sorted are distinct. Clearly, the worst case bound still holds true with this restriction removed because a lower bound on the worst-case performance from some inputs of some subsets is also a lower bound when all inputs are considered. In general, we are concerned with sorting n distinct keys that come from any ordered set. However, without loss of generality, we can assume that the keys to be sorted are simply the positive integers 1,2,…….,n, because we can substitute 1 for the smallest key, 2 for the second smallest, and so on. For example, suppose we have alpha input, [Ralph, Clyde, Dave]. We can associate 1 with Clyde, 2 with Dave and 3 with Ralph. To obtain the equivalent input, [3, 1, 2]. Any algorithm that sorts these integers only by comparison of keys would have to do the same number of comparisons to sort the three names. A permutation of the first n positive integers can be thought of as an ordering of those integers. Because there are n! Permutations, of the first n positive integers. There are n! different orderings of those integers. For example the following six permutations are all the ordering of the first three positive integers: [1,2,3] [1,3,2] [2,1,3] [2,3,1] [3,1,2] [3,2,1] This means that n! Different inputs (to a sorting algorithm) containing n different keys. These six permutations are the different inputs of size three (3). We denote a permutation by [k1,k2,…………,kn]. That is ki is the integer at the ith position. For the permutation [3, 1, 2], for example, K1=3, k2=1, k3=2 R and s must be integers between 1 and n such that s > r. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
143
Given a permutation, the pair (s, r) is an inversion in either the permutation or its transpose but not both. Showing that there are n ( n - 1 ) / 2 such pairs of integers between 1 and n is left as an exercise. This means that a permutation and its transpose have exactly, n ( n - 1 ) / 2 inversions between them. So the average no of inversions in a permutation and its transpose is, 1 n(n 1) * 2 2
n(n 1) 4
Therefore, we consider all permutations equally probable for the input, the average number of inversions in the input is also n (n-1) / 4. Because we assume that the algorithm removes at most one inversion after each comparison, on an average it must do at least this many comparisons to remove all inversion sand thereby sort the input. Insertion Sort removes at most the inversion consisting of S[j] and x after each comparison, and therefore this algorithm is in the class of algorithms addressed by Theorem. Because Insertion Sort‘s worst case time complexity is n ( n – 1 ) / 2 and its average – case time complexity is about n2/4, its about as good as we can hope to do (as far as comparisons of keys are concerned) with algorithms that sort only by comparisons of keys and remove at least one inversion after each comparison.
SELECTION SORT This type of sorting is called "Selection Sort" because it works by repeatedly element. It works as follows: first find the smallest in the array and exchange it with the element in the first position, then find the second smallest element and exchange it with the element in the second position, and continue in this way until the entire array is sorted.
SELECTION_SORT (A) for i ← 1 to n-1 do min j ← i; min x ← A[i] for j ← i + 1 to n do If A[j] < min x then min j ← j Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
144
min x ← A[j] A[min j] ← A [i] A[i] ← min x
Selection sort is among the simplest of sorting techniques and it work very well for small files. Furthermore, despite its evident "naïve approach "Selection sort has a quite important application because each item is actually moved at most once, Section sort is a method of choice for sorting files with very large objects (records) and small keys. The worst case occurs if the array is already sorted in descending order. Nonetheless, the time require by selection sort algorithm is not very sensitive to the original order of the array to be sorted: the test "if A[j] < min x" is executed exactly the same number of times in every case. The variation in time is only due to the number of times the "then" part (i.e., min j ← j; min x ← A[j] of this test are executed.
The Selection sort spends most of its time trying to find the minimum element in the "unsorted" part of the array. It clearly shows the similarity between Selection sort and Bubble sort. Bubble sort "selects" the maximum remaining elements at each stage, but wastes some effort imparting some order to "unsorted" part of the array. Selection sort is quadratic in both the worst and the average case, and requires no extra memory. For each i from 1 to n - 1, there is one exchange and n - i comparisons, so there is a total of n -1 exchanges and (n -1) + (n -2) + . . . + 2 + 1 = n(n -1)/2 comparisons. These observations hold no matter what the input data is. In the worst case, this could be quadratic, but in the average case, this quantity is O(n log n). It implies that the running time of Selection sort is quite insensitive to the input.
Implementation
void selectionSort(int numbers[], int array_size) { int i, j; int min, temp;
for (i = 0; i < array_size-1; i++) Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
145
{ min = i; for (j = i+1; j < array_size; j++) { if (numbers[j] < numbers[min]) min = j; } temp = numbers[i]; numbers[i] = numbers[min]; numbers[min] = temp; } }
SELECTION OF KTH SMALLEST ELEMENT In computer science, a selection algorithm is an algorithm for finding the k-th smallest number in a list (such a number is called the kth order statistic.) This includes the cases of finding the minimum, maximum, and median elements. There are worst-case linear time selection algorithms. Selection is a subproblem of more complex problems like the nearest neighbor problem and shortest path problems. A worst-case linear algorithm for the general case of selecting the kth largest element was published by Blum, Floyd, Pratt, Rivest, and Tarjan in their 1973 paper Time bounds for selection, sometimes called BFPRT after the last names of the authors. The algorithm that it is based on was conceived by the inventor of quicksort,C.A.R.Hoare, and is known as Hoare's selection algorithm or quickselect. In quicksort, there is a subprocedure called partition that can, in linear time, group a list (ranging from indices left to right) into two parts, those less than a certain element, and those greater than or equal to the element. Here is pseudocode that performs a partition about the element list[pivotIndex]: Algorithm function partition(list, left, right, pivotIndex) pivotValue := list[pivotIndex] swap list[pivotIndex] and list[right] // Move pivot to end Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
146
storeIndex := left for i from left to right-1 if list[i] < pivotValue swap list[storeIndex] and list[i] storeIndex := storeIndex + 1 swap list[right] and list[storeIndex] // Move pivot to its final place return storeIndex In quicksort, we recursively sort both branches, leading to best-case Ω(n log n) time. However, when doing selection, we already know which partition our desired element lies in, since the pivot is in its final sorted position, with all those preceding it in sorted order preceding it and all those following it in sorted order following it. Thus a single recursive call locates the desired element in the correct partition: Algorithm function select(list, left, right, k) select pivotIndex between left and right pivotNewIndex := partition(list, left, right, pivotIndex) if k = pivotNewIndex return list[k] else if k < pivotNewIndex return select(list, left, pivotNewIndex-1, k) else return select(list, pivotNewIndex+1, right, k) Note the resemblance to quicksort; indeed, just as the minimum-based selection algorithm is a partial selection sort, this is a partial quicksort, generating and partitioning only O(log n) of its O(n) partitions. This simple procedure has expected linear performance, and, like quicksort, has quite good performance in practice. It is also an in –place algorithm, requiring only constant memory overhead, since the tail recursion can be eliminated with a loop like this: Algorithm function select(list, left, right, k) loop select pivotIndex between left and right pivotNewIndex := partition(list, left, right, pivotIndex) Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
147
if k = pivotNewIndex return list[k] else if k < pivotNewIndex right := pivotNewIndex-1 else left := pivotNewIndex+1 Like quicksort, the performance of the algorithm is sensitive to the pivot that is chosen. If bad pivots are consistently chosen, this degrades to the minimum-based selection described previously, and so can require as much as O(n2) time. David Musser describes a "median-of-3 killer" sequence that can force the well-known median-of-three pivot selection algorithm to fail with worst-case behavior .
The algorithm works as follows: 1. Find the minimum value in the list 2. Swap it with the value in the first position 3. Repeat the steps above for remainder of the list (starting at the second position) Effectively, we divide the list into two parts: the sublist of items already sorted, which we build up from left to right and is found at the beginning, and the sublist of items remaining to be sorted, occupying the remainder of the array. Here is an example of this sort algorithm sorting five elements: 64 25 12 22 11 11 25 12 22 64
11 12 25 22 64 11 12 22 25 64
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
148
Selection sort can also be used on list structures that make add and remove efficient, such as a linked list. In this case it's more common to remove the minimum element from the remainder of the list, and then insert it at the end of the values sorted so far. For example: 64 25 12 22 11 11 64 25 12 22 11 12 64 25 22 11 12 22 64 25 11 12 22 25 64
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
149
MODULE 5
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
150
BACKTRACKING Many problems with searching a set of solutions or which ask for an optimal solution satisfying some constraints can be solved using the backtracking formulation. In many applications of the backtrack method, the desired solution is expressible as an n-tuple(x1,…..,xn), where the xi are chosen from some from finite set Si. Often the problem to be solved calls for finding one vector that maximizes (or minimizes or satisfies) a criterion function P(x1,…..,xn). Sometimes it seeks all vectors that satisfy P. The criterion function P is the inequality a[xi]≤a[xi+1] for 1 ≤ i < n. The set Si is finite and includes the integers 1 through n. Many of the problems we solve using backtracking require that all the solutions satisfy a complex set of constraints. For any problem these constraints can be classified into two categories: explicit and implicit. The explicit constraints depend on the particular instance I of the problem being solved. All tuples that satisfy the explicit constraints define a possible solution space for I. the implicit constraints are the rules that determine which of the tuples in the solution space of I satisfy the criterion function. Thus implicit constraints describe the way in which xi must relate to each other.
CONTROL ABSTRACTION (i) Recursive backtracking algorithm Algorithm Backtrack(k) //This schema describes the backtracking process using recursion. On entering, the first //k-1 values x[1], x[2],…..,x[k-1] of the solution vector x[1:n] have been assigned. x[ ] and //n are global. { for (each x[k] Є T(x[1],…..,x[k-1]) do { if (Bk(x[1],x[2],…..,x[k])!=0) then {
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
151
if (x[1],x[2],…..,x[k] is a path to an answer node) then write (x[1:k]); if (k
(ii)General iterative backtracking method Algorithm IBacktrack(n) //This schema describes the backtracking process. //All solutions are generated in x[1:n] and printed as soon as they are determined. { Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
152
k:= 1; while(k≠0) do { if (there remains an untried x[k] Є T(x[1],x[2],…..,x[k-1]) and Bk (x[1],…..,x[k]) is true) then { if (x[1],….x[k] is a path to answer node) then write (x[1:k]); k:=k+1;//Consider the next set. } else k:=k-1; //Backtrack to the previous set. } } Explanation T() will yield the set of possible values that can be placed as the first component x[1] of the solution vector. The component x[1] will take on those for which the bounding function B1x(1) is true. The variable k is continually incremented and a solution vector is grown until either a solution in found or no untried value of x k remains. When k is decremented, the algorithm must resume the generation of possible elements for the kth position that have not yet been tried. Conclusion The efficiency of both algorithms depends very much on four factors: 1. The time to generate next xk 2. The number of xk satisfying the explicit constraints 3. The time for the bounding functions Bk 4. The number of xk satisfying the Bk
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
153
Constraints Solutions must satisfy a set of constraints Explicit vs. implicit Definition 1: Explicit constraints are rules that restrict each xi to take on values only from a given set. eg) xi
0
or Si = { all nonnegative real numbers }
xi = 0 or 1 or Si = { 0, 1 } li
xi
ui
or Si = {a : li
a
ui }
All tuples satisfying the explicit constraints define a possible solution space for I (I=problem instance) Definition 2: The implicit constraints are rules that determine which of the tuples in the solution space of I satisfy the criterion function. Thus implicit constrains describe the way in which the xi must relate to each other.
Classic combinatorial problem Place eight queens on an 8*8 chessboard so that no two attack Without loss of generality, assume that queen i is placed on row i All solutions represented as 8-tuples (x1,x2,…,x8) where xi is the column on which queen i is placed Constraints • •
Explicit constraints – Si={1,2,…,8} – So, solution space consists of 88 8-tuples Implicit constraints – No two xi‘s can be the same (By this, solution space reduced from 88 to 8!) – No two queens can be on the same diagonal
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
154
BOUNDING FUNCTIONS The backtrack algorithm as its virtue the ability to yield the same answer with far fewer than m trials. Its basic idea is to build solution vector, one competent at a time and to use modified criterion functions Pi(x1,……,xn) called bounding functions, to test whether the vector being formed has any chance of success. The major advantage of this method is this: if it is realized that the partial vector (x1, x2,….., xi) can in no way lead to an optimal solution, then mi+1……mn possible test vectors can be ignored entirely.
N-QUEENS PROBLEM The n-queens problem is a generalization of the 8-queens problem. Here n queens are to be placed on an nxn chessboard so that no two attack, that is no two queens are on the same row, column, or diagonal. The solution space consists of all n! permutations of the n-tuple (1,2,…,n). The tree is called permutation tree. The edges are labeled by possible values of xi. Edges from level 1 to level 2 nodes specify the values for x1. Edges from level i to i+1 are labeled with values of xi. The solution space is defined by all the paths from the root node to a leaf node. For eg. If n=4, then there will be 4! =24 leaf nodes in the tree. Eg: 8-queens problem A classic problem is to place eight queens on an 8x8 chessboard so that no two ―attack,‖ that is, so that no two of them are on the same row, column, or diagonal.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
•
155
Bounding function – No two queens placed on the same column xi’s are distinct – No two queens placed on the same diagonal how to test? • The same value of ―row-column‖ or ―row+column‖ • Supposing two queens on (i,j) and (k,l) – i-j=k-l (i.e., j-l=i-k) or i+j=k+l (i.e., j-l=k-i) • So, two queens placed on the same diagonal iff |j-l| = |i-k|
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
156
This example shows how the backtracking works(4-Queens)
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
157
TREE STRUCTURE
Tree organization of the 4-queens solution space. Nodes are numbered as in depth first search.
The n-queens problem is a generalization of the 8-queens problem. Now n queens are to be placed on an n×n chess board so that no two attack; that is, no two queens are on the same row, column or diagonal.Generalising our discussions, the solution space consists of all n! permutations of n-tuple (1, 2.., n).The above figure shows a possible tree organization for the case n=4. A tree such as this is called a permutation tree. The edges are labeled by possible values of xi. Edges from level 1 to level 2 nodes specify the value for x1.Thus the leftmost sub tree contains all solutions with x1=1 and x2=2,and so on. Edges from level to level i+1are labeled with the value of xi.the solution space is defined by all paths from the root node to a leaf node. There are 4! =24 nodes in the tree.
ALGORITHM Algorithm Place (k, ί) // Returns true if a queen can be placed in the kth row and //ith column. Otherwise it returns false. x[] is a //global array whose first (k –1) values have been set. //Abs (p) returns the absolute value of p. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
158
{ for j: =1 to k-1 do if ((x [j] = ί) // Two in the same column or (Abs (x [j] – ί ) = Abs (j-k)) ) // or in the same diagonal then return false; return true; }
Algorithm Nqueens (k, n) // Using backtracking, this procedure prints all // possible placements of n queens on an n x n // chessboard so that they are nonattacking. { for ί: =1 to n do { if Place (k, ί) then { x [k] : = ί; if (k=n) then write (x[1:n]); else Nqueens (k+1,n); } } }
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
159
SUM OF SUBSETS Given positive numbers wi, 1≤i≤n, and m, find all subsets of the wi whose sum is m eg) (w1,w2,w3,w4) = (11,13,24,7) and m=31 Solutions are (11,13,7) and (24,7) Representation of solution vector Variable-sized By giving indices In the above example, (1,2,4) and (3,4) Explicit constraints: xi ∈ { j | j is integer and 1≤j≤n} Implicit constraints: no two be the same, the sums are m Fixed-sized
n-tuple (x1,x2,…,xn) where xi∈{0,1}, 1≤i≤n In the above example, (1,1,0,1) and (0,0,1,1)
Variable tuple size Suppose we are given n distinct positive numbers(usually called weights) and we desire to find all combinations of these numbers whose sums are m.This is called sum of subsets problem. We could formulate this problem using either fixed-or variable-sized tuple Given positive numbers wi,1<=i<=n, and m, this problem calls for finding all subsets of the wi whose sums are m.For example if n=4,( w1,w2,w3,w4)=(11,13,24,7), and m=31,then the desired subsets are (11,13,7) and (24,7).Rather than represent the solution vector by the wi which sum to m we could represent the solution vector by giving the indices of these wi.Now the two solutions are described by the vectors (1,2,4) and (3,4).In general all solutions are ktuples (x1,x2,.....xk), 1<=k<=n and different solutions may have different sized tuples.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) •
160
Solution space defined by all paths from the root to any node
Fixed tuple size: •
• Solution space defined by all paths from the root to a leaf node Bounding function • Bk(x1,..,xk)=true iff
–
Assuming wi’s in nondecreasing order, (x1,..,xk) cannot lead to an answer node if
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
–
•
161
So, the bounding function is
Backtracking algorithm for the sum of sunsets –
Invoked by SumOfSubsets(0,1,∑i=1,nwi)
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
162
Example:n=6, w[1:6]={5,10,12,13,15,18}, m=30
•
Terminology – A node which has been generated and all of whose children have not yet been generated is called a live node – The live node whose children are currently being generated is called E-node – A dead node is a generated node which is not to be expanded further or all of whose children have been generated • Two different ways of tree generation • Backtracking • Depth first node generation with bounding functions – Branch-and-bound – E-node remains E-node until it is dead Four factors for efficiency of the backtracking algorithms
Time to generate the next xk Number of xk satisfying the explicit constraints Time for the bounding function Bk Number of xk satisfying Bk
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
163
A solution space organization for the sum of subsets problem.Nodes are numbered in BFS
* The first three relatively independent of the problem instance, and the last dependent
1 1
X1=1
X1=4 X1=2 3 3
2 2
5 5
4 4
X2=2 X2=4 X 6 6
7 7
X3=3
X3=4
12
13
14 6
8
X2=3
X2=4 9 99
10
11 11 1
X3=4
X3=4
15 6
X4=4 16 Fig 1
The tree of fig 1 represents corresponds to variable tuple size formulation.The edges are labelled such that an edge from a level i node to a level i+1 node represents a value for xi.At each node, the solution space is partitioned into subsolution spaces.The solution space is defined by all paths from the root node to any node in the tree,since any such path corresponds to a subset satisfying the explicit constraints.Thr possible paths are (1),(1,2),(1,2,3),(1,2,3,4),(1,2,4),(1,3,4),(2),(2,3) and so on.Thus the leftmost subtree defines all subsets containing w1,the next subtree defines all subsets containing w2 but not w1 and so on. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
164
Another organization for the sum of subsets problem.Nodes are numbered in D-search
1 1
X1=1
X3=1
30 11
X4=1 31 28 X4=0 11 22 8 1
X3=1
X4=1 29 24 X4=0 11 24 1
20 20 1
5 11
4 1
19 19 1
27 12 1
X2=0
X2=1
X2=0
18 11 81 X3=0
26 22 6 1
3 1
2 12 1
X2=1
X1=0
X3=0 21 11
X4=1 25 22 X =0 4 1 22 00001 ==
X3=0 X3=1 1 12
11 X4=1 2 X4= X4= 23 1 16 1 17 0 14 14 1 61 1 1 1 1
X3=1 6 11
13 11 X4= 10 151 11 1 0 1
FIG 2
The tree of fig 2 corresponds to the fixed tuple size formation.Edges from level i nodes level i+l nodes are labelled with the value of xi w hich is either zero or one.All paths from root to a leaf node defining the solution space .The left subtree of the root defines all subsets containing w1,the right subtree defines all subsets not containing w1, and so on.Now there are 24 leaf nodes.
Department of Computer Science & Engineering
SJCET, Palai
X4 11 =1 8 1 11
Algorithm Analysis and Design (R 606)
165
KNAPSACK PROBLEM Explanation: Given n positive weights wi , n positive profits pi, and a positive number m that is the knapsack capacity, this problem calls for choosing a subset of the weights such that ∑ i≤i≤n wixi ≤ m and ∑ i≤i≤n pixi is maximized. The xi‘s constitute a zero-one-valued vector. The solution space for this problem consists of the 2n distinct ways to assign zero or one values to the x i‘s. Thus the solution space is the same as that for the sum of subsets proble. Two possible tree organizations are possible. One corresponds to the fixed tuple size formulation and the other to the variable tuple size formulation. Backtracking algorithms for the knapsack problem can arrived by using either of these two state space trees. Regardless of which is used, bounding functions are needed to help kill some live nodes without expanding them. A bounding function for this problem is obtained by using an upper bound on the value of the best feasible solution obtainable by expanding the given live node and any of its descendants. If this upper bound is not higher than the value of the best solution determined so far, then that live node can be killed. Now by using the fixed tuple size formulation, if at node Z the values of xi, 1≤i≤k, have already been determined, then an upper bound for Z can be obtained by relaxing the requirement xi=0 or 1 to 0≤xi ≤1 for k+1≤i≤n and using the greedy algorithm to solve the relaxed problem. Function Bound(cp,cw,k) determines an upper bound on the best solution obtainable by expanding any node Z at level k+1 of the state space tree. The object weights and profits are w[i] and p[i]. It is assumed that p[i]/w[i]≥p[i+1]/w[i+1], 1≤i
SJCET, Palai
Algorithm Analysis and Design (R 606)
166
path y[i], 1≤ i ≤ k, is the path to the current node. The current weight cw = ∑k-1i=1 w[i]y[i] and ∑i=1k-1 p[i]y[i]. In lines 13 to 17 and 23 to 27 the solution vector is updated if need
cp= be.
So far, all the backtracking algorithms have worked on a static state space tree.
Algorithm: Bounding Function Algorithm Bound(cp,cw,k) //cp is the current profit total, cw is the current //weight total; k is the index of the last removed //item; and m is the knapsack size. { b:= cp; c:=cw; for i:=k+1 to n do { c:=c+w[i]; if(c
Algorithm: Backtracking solution to the 0/1 knapsack problem. Algorithm Bknap(k,cp,cw) //m is the size of the knapsack; n is the number of weights. //and profits. w[] and p[] are the weights and profits. //p[i]/w[i] ≥ p[i+1]/w[i+1]. fw is the final weight of //knapsack; fp is the final maximum profit. x[k] = 0 if w[k] //is not in the knapsack; else x[k]=1. { // Generate left child. if (cw + w[k] ≤ m) then Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
167
{ y[k]:=1; if(kfp) and (k=n)) then { fp:=cp +p[k]; fw:=cw+w[k]; for j:=1 to k do x[j]:=y[j]; } } // Generate right child. if (Bound(cp,cw,k)≥fp) then { y[k] :=0; if (k fp) and (k=n)) then { fp:=cp; fw:=cw; for j:=1 to k do x[j]:=y[j]; } } }
ALGORITHM // CP-Current Profit; //K-index of last removed access { b=cp;c=cw; for P=K+1 to n do { c=c+w[i]; if(c
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
168
else return b+(1-(c-m)/w[i])+p[i]; } Return(b); }
Algorithm B knap(K,cp,cw) { If(w+w[K]<=m) then { Y[K]=1; If(Kfp)and(K=n)then { fp=cp+p[K];fw=cw+w[K]; for j=1 to K do x[j]=y[j]; } } If(Bound(cp,w,K)>=fp) then { Y[K]=0; If(k
SJCET, Palai
Algorithm Analysis and Design (R 606)
169
B knap(K+1,cp,cw); If((cp>fp)and(k=n)) then { fp=cp; fw=cw; for j=1 to k do x[j]=y[j]; } } }
BRANCH AND BOUND ALGORITHM TECHNIQUE Introduction Branch and bound is another algorithm technique that we are going to present in our multipart article series covering algorithm design patterns and techniques. B&B, as it is often abbreviated, is one of the most complex techniques and surely cannot be discussed in its entirety in a single article. Thus, we are going to focus on the so-called A* algorithm that is the most distinctive B&B graph search algorithm. If you have followed this article series then you know that we have already covered the most important techniques such as backtracking, the greedy strategy, divide and conquer, dynamic programming, and even genetic programming. As a result, in this part we will compare branch and bound with the previously mentioned techniques as well. It is really useful to understand the differences. Branch and bound is an algorithm technique that is often implemented for finding the optimal solutions in case of optimization problems; it is mainly used for combinatorial and discrete global optimizations of problems. In a nutshell, we opt for this technique when the domain of
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
170
possible candidates is way too large and all of the other algorithms fail. This technique is based on the en masse elimination of the candidates. You should already be familiar with the tree structure of algorithms. Out of the techniques that we have learned, both the backtracking and divide and conquer traverse the tree in its depth, though they take opposite routes. The greedy strategy picks a single route and forgets about the rest. Dynamic programming approaches this in a sort of breadth-first search variation (BFS). Now if the decision tree of the problem that we are planning to solve has practically unlimited depth, then, by definition, the backtracking and divide and conquer algorithms are out. We shouldn't rely on greedy because that is problem-dependent and never promises to deliver a global optimum, unless proven otherwise mathematically. As our last resort we may even think about dynamic programming. The truth is that maybe the problem can indeed be solved with dynamic programming, but the implementation wouldn't be an efficient approach; additionally, it would be very hard to implement. You see, if we have a complex problem where we would need lots of parameters to describe the solutions of sub-problems, DP becomes inefficient. Branch and bound is a systematic method for solving optimization problems B&B is a rather general optimization technique that applies where the greedy method and dynamic programming fail. 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). Rather, a carefully selected criterion determines which node to expand and when, and another criterion tells the algorithm when an optimal solution has been found. The basic concept underlying the branch-and-bound technique is to divide and conquer. Since the original ―large‖ problem is hard to solve directly,it is divided into smaller and smaller subproblems until these subproblems can be conquered. The dividing (branching) is done by partitioning the entire set of feasible solutions into smaller and smaller subsets.The conquering (fathoming) is done partially by (i) giving a bound for the best solution in the subset;(ii) discarding the subset if the bound indicates that it can‘t contain an optimal solution.These
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
171
three basic steps – branching, bounding, and fathoming – are illustrated on the following example.
Branch-and-Bound Algorithms A counter-part of the backtracking search algorithm which, in the absence of a cost criteria, the algorithm traverses a spanning tree of the solution space using the breadth-first approach. That is, a queue is used, and the nodes are processed in first-in-first-out order Procedure Expand(E) begin /* Generate all the children of E; */ I := E->I; X,p: nodepointer; S[1:n]: Boolean; /* S is a bitmap set initialized to 0*/ /* S will contain all the jobs that have been assigned by the partial path from the root to E */ p := E; while (p is not the root) do S[p->J] := 1; p := p-> Parent; endwhile for job=1 to n do if S[job] = 0 then X := new(node); X->I := I + 1; X->J := job; X->Parent := E; X->CC := E->CC + AX->I,X->J-mX->I; Insert(X,H); endif endfor Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
172
end . If a cost criteria is available, the node to be expanded next (i.e., the branch) is the one with the best cost within the queue. In such a case, the cost function may also be used to discard (i.e., the bound) from the queue nodes that can be determined to be expensive. A priority queue is needed here. Cost-Based Tree Traversal of branch and bound A function can be considered to be a tree generator, if when given a node X and index i it produces the i‘th child of the node. The following function produces a complete binary tree of 11 nodes.
The recursive function provided for deriving permutations is another example of a function that may be used to generate trees. Besides for a tree generator function, we also need a cost function to decide in what order to traverse the nodes when searching for a solution. The algorithm proceeds in the following manner. 1. Initialization: The root of the of the tree is declared to be alive. 2. Visit: The cost criteria decides which of the live nodes is to process next. 3. Replacement: The chosen node is removed from the set of live nodes, and its children are inserted into the set. The children are determined by the tree generator function. 4. Iteration: The visitation and replacement steps are repeated until no alive nodes are left. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
173
In the case of backtracking the cost criteria assumes a last-in-first-out (LIFO) function, which can be realized with a stack memory. A first-in-first-out cost criteria implies the FIFO branch-and-bound algorithm, and it can be realized with queue memory. A generalization to arbitrary cost criteria is the basis for the priority branch-and-bound algorithm, and a priority queue memory can be employed to realize the function.
FIFO BRANCH AND BOUND ALGORITHM FIFO branch and bound algorithm for the job sequencing problem can begin with upper= infinity. While implementing FIFO B&B algorithm it is not economical to kill live nodes with c®> upper each time upper is updated. Each solution is assumed to be expressible as an array X[1:n] (as was seen in Backtracking). A predictor, called an approximate cost function CC, is assumed to have been defined. A live node is a node that has not been expanded.A dead node is a node that has been expanded. The expanded node (or E-node for short) is the live node with the best CC value. Branch and Bound is a general search method. Starting by considering the root problem (the original problem with the complete feasible region), the lower-bounding and upper-bounding procedures are applied to the root problem.If the bounds match, then an optimal solution has been found and the procedure terminates. Otherwise, the feasible region is divided into two or more regions, these subproblems partition the feasible region. The algorithm is applied recursively to the subproblems. If an optimal solution is found to a subproblem, it is a feasible solution to the full problem, but not necessarily globally optimal. If the lower bound for a node exceeds the best known feasible solution, no globally optimal solution can exist in the subspace of the feasible region represented by the node. Therefore, the node can be removed from consideration. The search proceeds until all nodes have been solved or pruned, or until some specified threshold is met between the best solution found and the lower bounds on all unsolved subproblems. A counter-part of the backtracking search algorithm which, in the absence of a cost criteria, the algorithm traverses a spanning tree of the solution space using the breadth-first approach. That is, a queue is used, and the nodes are processed in firstin-first-out order. If a cost criteria is available, the node to be expanded next (i.e., the branch) is the one with the best cost within the queue. In such a case, the cost function may also be used to discard (i.e., the bound) from the queue nodes that can be determined to be expensive. A priority queue is needed here.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
174
The general FIFO B&B algorithm follows:
Procedure B&B() begin E: nodepointer; E := new(node);
-- this is the root node which -- is the dummy start node
H: heap;
-- A heap for all the live nodes
-- H is a min-heap for minimization problems, -- and a max-heap for maximization problems. while (true) do if (E is a final leaf) then -- E is an optimal solution print out the path from E to the root; return; endif Expand(E); if (H is empty) then report that there is no solution; return; endif E := delete-top(H); endwhile end
Procedure Expand(E) begin - Generate all the children of E; - Compute the approximate cost value CC of each child; - Insert each child into the heap H; end
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
175
We need to define the full record of a node .We need to fully implement the Expand procedure Every node corresponds to something like X[i]=j, which signifies that the job X[i] assigned to person i is j. Every node must store its CC value. Each node must point to its parent so that when an optimal leaf is generated, the path from that leaf to the root can be traced and printed out as the optimal solution.Therefore, a node record structure should look like:
Record node Begin Parent: nodepointer; I: integer; -- person I J: integer; -- Job J is assigned to person I CC: real; End
Take the 2nd CC formula: CC(X at level k) = cost so far + sumni=k+1mi where mi is the minimum of row i. observe that if X is a pointer to a node, then X->CC = X->Parent->CC + AX->I,A->J - mX->I Write a piece of code that computes the mis for i=1,2,...,n Code for Expand(E): Procedure Expand(E) begin /* Generate all the children of E; */ I := E->I; X,p: nodepointer; S[1:n]: Boolean; /* S is a bitmap set initialized to 0*/ /* S will contain all the jobs that have been assigned by the partial path from the root to E */ p := E; while (p is not the root) do Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
176
S[p->J] := 1; p := p-> Parent; endwhile for job=1 to n do if S[job] = 0 then X := new(node); X->I := I + 1; X->J := job; X->Parent := E; X->CC := E->CC + AX->I,X->J-mX->I; Insert(X,H); endif endfor end.
Although a number of algorithms have been proposed for the integer linear programming problem, the FIFO branch-and-bound technique has proven to be reasonably efficient on practical problems, and it has the added advantage that it solves continuous linear programs as sub problems.The technique is also used in a lot of software in global optimization.
Fifo B&B Cost-Based Tree Traversal
A function can be considered to be a tree generator, if when given a node X and index i it produces the i‘th child of the node.The following function produces a complete binary tree of 11 nodes.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
177
The recursive function provided for deriving permutations is another example of a function that may be used to generate trees. Besides for a tree generator function, we also need a cost function to decide in what order to traverse the nodes when searching for a solution. The algorithm proceeds in the following manner. 1. Initialization: The root of the of the tree is declared to be alive. 2. Visit: The cost criteria decides which of the live nodes is to process next. 3. Replacement: The chosen node is removed from the set of live nodes, and its children are inserted into the set. The children are determined by the tree generator function. 4. Iteration: The visitation and replacement steps are repeated until no alive nodes are left. In the case of backtracking the cost criteria assumes a last-in-first-out (LIFO) function, which can be realized with a stack memory. A first-in-first-out cost criteria implies the FIFO branch-and-bound algorithm, and it can be realized with queue memory. A generalization to arbitrary cost criteria is the basis for the priority branch-and-bound algorithm, and a priority queue memory can be employed to realize the function. •
Search the tree using a breadth-first search (FIFO branch and bound).
•
Search the tree as in a bfs, but replace the FIFO queue with a stack (LIFO branch and bound).
•
Replace the FIFO queue with a priority queue (least-cost (or max priority) branch and bound). The priority of a node p in the queue is based on an estimate of the likelihood that the answer node is in the subtree whose root is p. FIFO branch and bound finds solution closest to root.Backtracking may never find a solution because tree depth is infinite (unless repeating configurations are eliminated).
•
Least-cost branch and bound directs the search to parts of the space most likely to contain the answer. So it could perform better than backtracking.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
178
LIFO BRANCH AND BOUND ALGORITHM LIFO branch and bound algorithm for the job sequencing problem can begin with upper= infinity. While implementing LIFO B&B algorithm it is not economical to kill live nodes with c®> upper each time upper is updated. Each solution is assumed to be expressible as an array X[1:n] (as was seen in Backtracking). A predictor, called an approximate cost function CC, is assumed to have been defined. A live node is a node that has not been expanded.A dead node is a node that has been expanded. The expanded node (or E-node for short) is the live node with the best CC value. Branch and Bound is a general search method. Starting by considering the root problem (the original problem with the complete feasible region), the lower-bounding and upper-bounding procedures are applied to the root problem.If the bounds match, then an optimal solution has been found and the procedure terminates. Otherwise, the feasible region is divided into two or more regions, these subproblems partition the feasible region. The algorithm is applied recursively to the subproblems. If an optimal solution is found to a subproblem, it is a feasible solution to the full problem, but not necessarily globally optimal. If the lower bound for a node exceeds the best known feasible solution, no globally optimal solution can exist in the subspace of the feasible region represented by the node. Therefore, the node can be removed from consideration. The search proceeds until all nodes have been solved or pruned, or until some specified threshold is met between the best solution found and the lower bounds on all unsolved subproblems. A counter-part of the backtracking search algorithm which, in the absence of a cost criteria, the algorithm traverses a spanning tree of the solution space using the breadth-first approach. That is, a queue is used, and the nodes are processed in firstin-first-out order. If a cost criteria is available, the node to be expanded next (i.e., the branch) is the one with the best cost within the queue. In such a case, the cost function may also be used to discard (i.e., the bound) from the queue nodes that can be determined to be expensive. A priority queue is needed here. A general LIFO B&B algorithm :
Procedure B&B() begin E: nodepointer; E := new(node);
-- this is the root node which -- is the dummy start node
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) H: heap;
179
-- A heap for all the live nodes
-- H is a min-heap for minimization problems, -- and a max-heap for maximization problems. while (true) do if (E is a final leaf) then -- E is an optimal solution print out the path from E to the root; return; endif Expand(E); if (H is empty) then report that there is no solution; return; endif E := delete-top(H); endwhile end
Procedure Expand(E) begin - Generate all the children of E; - Compute the approximate cost value CC of each child; - Insert each child into the heap H; end
We need to define the full record of a node .We need to fully implement the Expand procedure Every node corresponds to something like X[i]=j, which signifies that the job X[i] assigned to person i is j. Every node must store its CC value. Each node must point to its parent so that when an optimal leaf is generated, the path from that leaf to the root can be traced and printed out as the optimal solution.Therefore, a node record structure should look like:
Record node Begin Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
180
Parent: nodepointer; I: integer; -- person I J: integer; -- Job J is assigned to person I CC: real; End
Take the 2nd CC formula: CC(X at level k) = cost so far + sumni=k+1mi where mi is the minimum of row i. observe that if X is a pointer to a node, then X->CC = X->Parent->CC + AX->I,A->J - mX->I Write a piece of code that computes the mis for i=1,2,...,n Although a number of algorithms have been proposed for the integer linear programming problem, the LIFO branch-and-bound technique has proven to be reasonably efficient on practical problems, and it has the added advantage that it solves continuous linear programs as sub problems.The technique is also used in a lot of software in global optimization.
Lifo B&B Cost-Based Tree Traversal
A function can be considered to be a tree generator, if when given a node X and index i it produces the i‘th child of the node.The following function produces a complete binary tree of 11 nodes.
The recursive function provided for deriving permutations is another example of a function that may be used to generate trees. Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
181
Besides for a tree generator function, we also need a cost function to decide in what order to traverse the nodes when searching for a solution. The algorithm proceeds in the following manner. 5. Initialization: The root of the of the tree is declared to be alive. 6. Visit: The cost criteria decides which of the live nodes is to process next. 7. Replacement: The chosen node is removed from the set of live nodes, and its children are inserted into the set. The children are determined by the tree generator function. 8. Iteration: The visitation and replacement steps are repeated until no alive nodes are left. In the case of backtracking the cost criteria assumes a last-in-first-out (LIFO) function, which can be realized with a stack memory. A last-in-first-out cost criteria implies the LIFO branch-and-bound algorithm, and it can be realized with queue memory. A generalization to arbitrary cost criteria is the basis for the priority branch-and-bound algorithm, and a priority queue memory can be employed to realize the function. •
Search the tree using a breadth-first search (FIFO branch and bound).
•
Search the tree as in a bfs, but replace the FIFO queue with a stack (LIFO branch and bound).
•
Replace the FIFO queue with a priority queue (least-cost (or max priority) branch and bound). The priority of a node p in the queue is based on an estimate of the likelihood that the answer node is in the subtree whose root is p. LIFO branch and bound finds solution closest to root.Backtracking may never find a solution because tree depth is infinite (unless repeating configurations are eliminated).
•
Least-cost branch and bound directs the search to parts of the space most likely to contain the answer. So it could perform better than backtracking.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
182
LC CONTROL ABSTRACTION listnode= record { Listnode *next,*parent; Float cost; } Algorithm LCSearch(t) //Search t for an answer node. { If *t is an answer node then output t and return E:=t; //E-node Initalize the list of live nodes to be empty; Repeat { for each child x of E do { If x is an answer node then output the path from x to t and return; Add(x);//x is a new live node. (x->parent):=E;//Pointer for path to root } If there are no more live nodes then { Write(―No answer node‖);return; } E:=Least(); }until(false); }
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
183
15- PUZZLE
The 15 puzzle consists of 15 squares numbered from 1 to 15 that are placed in a box leaving one position out of the 16 empty. The goal is to reposition the squares from a given arbitrary starting arrangement by sliding them one at a time into the configuration shown above. For some initial arrangements, this rearrangement is possible, but for others, it is not.
The n-puzzle is known in various versions, including the 8 puzzle, the 15 puzzle, and with various names. It is a sliding puzzle that consists of a frame of numbered square tiles in random order with one tile missing. If the size is 3×3, the puzzle is called the 8-puzzle or 9puzzle, and if 4×4, the puzzle is called the 15-puzzle or 16-puzzle. The object of the puzzle is to place the tiles in order (see diagram) by making sliding moves that use the empty space. Theorem: The goal state is reachavle from intial state iff ∑16 i=1less(i)+x is even. For any state let less(i) be the number of tiles j such that jposition(i).Let position(i) be the position number in the intial state of the tile numbered i.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
184
First ten steps in depth first search
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
185
TRAVELLING SALESMAN PROBLEM The Travelling Salesman problem (TSP) is a problem in combinatorial optimization studied in operations research and theoretical computer science. Given a list of cities and their pairwise distances, the task is to find a shortest possible tour that visits each city exactly once. It is used as a benchmark for many optimization methods. The TSP has several applications even in its purest formulation, such as planning, logistics, and the manufacture of microchips. Slightly modified, it appears as a sub-problem in many areas, such as genome sequencing. In these applications, the concept city represents, for example, customers, soldering points, or DNA fragments, and the concept distance represents travelling times or cost, or a similarity measure between DNA fragments.
Asymmetric and symmetric In the symmetric TSP, the distance between two cities is the same in each direction. Thus, the underlying structure is an undirected graph between; especially, each tour has the same length in both directions. In the asymmetric TSP, the distance from one city to the other need not equal the distance in the other direction, in general, there may not even be a connection in the other direction.
Problem: You are given a list of n cities along with the distances between each pair of cities. The goal is to find a tour which starts at the first city, visits each city exactly once and returns to the first city, such that the distance traveled is as small as possible. This problem is known to be NP-complete , i.e. no serial algorithm exists that runs in time polynomial in n, only in time exponential in n, and it is widely believed that no polynomial time algorithm exists. In practice, we want to compute an approximate solution, i.e. a single tour whose length is as short as possible, in a given amount of time. More formally, we are given a graph G=(N,V,W) consisting of a set N of n nodes (or cities), a set of edges V = {(i,j)} connecting cities, and a set of nonnegative weights W = {w(i,j)} giving the length of edge (i,j) (distance from city i to city j). The graph is directed, so that an Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
186
edge (i,j) may only be traversed in the direction from i to j, and edge (j,i) may or may not exist. Similarly, w(i,j) does not necessarily equal w(j,i), if both edges exist.
Branch-and-Bound for TSP A simple improvement on the algorithm prunes the search tree by observing that if a partial tour is already longer than the best solution found so far, there is no reason to continue searching that path. Naive Branch-and-Bound Solution of TSP
w = w(1,2) + w(2,3) + w(3,4) + ... + w(n-1,n) + w(n,1) Best_S_so_far = ( n, [ 1, 2, 3, ... , n-1, n ], w ) S = ( 1, [ 1 ], 0 ) Search( S, Best_S_so_far ) print Best_S_so_far
procedure Search( S, Best_S_so_far )
let ( k, [ i1, i2, ... , ik ], w ) = S let ( n, [ i1B, i2B, ... , inB ], wB ) = Best_S_so_far if k = n then new_w = w + w(ik,i1) if new_w < wB then Best_S_so_far = ( k, [ i1, i2, ... , ik ], new_w ) end if else for all j not in [ i1, i2, ... , ik ] new_w = w + w(ik,j) if new_w < wB then New_S = ( k+1, [ i1, i2, ... , ik, j ], new_w ) Search( New_S, Best_S_so_far ) end if end for endif return end
Better Branch and Bound Algorithm for TSP
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
187
Another strategy for searching the solution space is to repeatedly divide it into two parts: those with a given edge and those without the edge. The search tree would unfold as follows:
----------| all solns | ----------/
\
----------------
-----------------
| solns with e_i |
| solns w/out e_i |
---------------/
-----------------
\
/
\
----------- ---------- ---------- ----------| with e_j | | w/out e_j | | with e_k | | w/out e_k | ----------- ---------- ---------- -----------
Bounding the solutions: Assume the input is given as a dense adjacency matrix. We will put infinities, rather than zeros on the diagonal to avoid traversing these self-edges. i\j 1
2
3
4
5
6
7
\ ________________________________________ 1
|Inf
3
93
13
33
9
57
2
| 4 Inf
77
42
21
16
34
3
| 45
17 Inf
36
16
28
25
4
| 39
90
80 Inf
56
7
91
5
| 28
46
88
33 Inf
25
57
6
| 3
88
18
46
7
| 44
26
33
27 84
92 Inf
7
39 Inf
We can subtract a constant from a given row or column, as long as the values remain nonnegative. This changes the weight of each tour, but not the set of legal tours or their relative weights. We therefore normalize the matrix by subtracting the minimum value in each row from the row and the minimum value of each column from the column. This results in a matrix with at least one zero in every row and column. i\j 1
2
3
4
5
6
7
\ ________________________________________ 1
|Inf
0
83
9
30
6
50
2
| 0 Inf
66
37
17
12
26
3
| 29
1 Inf
19
0
12
5
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) 4
| 32
83
66 Inf
5
| 3
21
56
6
| 0
85
8
7
| 18
0
0
49
0
7 Inf
188
80
0
28
42
89 Inf
0
0
58
13 Inf
Any solution must use one entry from every row and every column, so the sum of the values we just subtracted is a lower bound on the weight of solution. In this case, we subtracted [3 4 16 7 25 3 26] from the rows and then [0 0 7 1 0 0 4] from the columns, so the lower bound on the weight of any solution is 96. Representing the set of solutions: The adjacency matrix can be used to represent the set of solutions. When an edge is chosen for the solution, the row and column containing that edge is deleted. When an edge is eliminated from the solution, its entry is changed to infinity so that it will never be chosen. In the above example, assume we choose to split the search space on the edge from 4 to 6. For the right subtree, which represents all solutions not containing (4,6), we replace the (4,6) entry by infinity. The minimum value in row 4 is now 32, so we can renormalize the matrix and improve the lower bound to 96+32 = 128. Column 6 has another 0 entry, so it remains unchanged. The matrix for the right subtree is: i\j 1
2
3
4
5
6
7
\ ________________________________________ 1
|Inf
0
83
9
30
6
2
| 0 Inf
66
37
17
12
26
3
| 29
1 Inf
19
0
12
5
4
| 0
51
34 Inf
5
| 3
21
56
6
| 0
85
8
7
| 18
0
0
17 Inf
7 Inf
50
48
0
28
42
89 Inf
0
0
58
13 Inf
The left subtree represents all solutions containing (4,6). We therefore delete row 4 and column 6 from the matrix and renormalize. In addition, since we have used edge (4,6), edge (6,4) is no longer usable, so we replace the (6,4) with infinity.The matrix can now be renormalized, in this case by subtracting 3 from the row with i=5 (now the 4th row in the smaller matrix), yielding a lower bound of 96+3=99 and the matrix: i\j 1
2
3
4
5
7
\ __________________________________ 1
|Inf
0
83
9
30
50
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606) 2
| 0 Inf
66
37
17
26
3
| 29
1 Inf
19
0
5
5
| 0
18
53
4 Inf
25
6
| 0
85
8 Inf
89
7
| 18
0
0
58 Inf
0
189
0
The process outlined so far can be used by repeatedly following these steps. Following the left branches we are guaranteed to reach some solution in n levels. Following the right branch, we will eventually have a matrix full of infinities, at which point the lower bound Choice of the splitting edge: In general, the right branches represent a larger set of solutions than the left branches. Therefore, in choosing the splitting edge, we look for something that will raise the lower bound of the right-hand subtree as much as possible. In the example, edge (4,6) was chosen because its value was zero and the next larger value in row 4 was 32. There are other zero entries in the matrix, for example, (3,5), but the improvement in the lower bound for that case would have been only 1 (for row 3) plus 17 (for column 5). Therefore, the general rule is to search for the zero entry at (i,j) that maximizes the increase in the lower bound (largest sum of minimum in row i and minimum in column j, not counting the zero at (i,j)). Insertion of infinities in left-branches: When expanding a left branch in the search tree for edge (i,j), we noted that edge (j,i) should be made infinity. In general, we are trying to avoid the creation of non-covering cycles in the tour, i.e., cycles that traverse only a subset of the nodes. For the example above, assume that the left-most search path unfolds with the following edge splits: (4,6), (3,5), and (2,1). At this point the partial solution contains three disconnected paths; all cycles were prevented by marking (6,4), (5,3), and (1,2) as infinity.
Department of Computer Science & Engineering
SJCET, Palai
Algorithm Analysis and Design (R 606)
190
----------| all solns | ----------/
\
------------
-------------
| with (4,6)| -----------/
-------------
| with (3,5)|
/
-------------
\
------------
------------
| w/out (4,6)|
| w/out (3,5)| -------------
\
------------
------------
| with (2,1)|
| w/out (2,1)|
------------
------------
The next choice of splitting edge is (1,4), so according to our above rule (4,1) should be changed to infinity. However, at this point the adjacency matrix does not contain a row for 4, since it was removed with the (4,6) step. Moreover, the partial solution is now: 2-1-4-6 &3-5.
Department of Computer Science & Engineering
SJCET, Palai