Sei sulla pagina 1di 19

12304

DATA STRUCTURES AND ALGORITHMS UNIT V


DYNAMIC PROGRAMMING

Dynamic Programming: Dynamic programming is an algorithm that can be used when the solution to a problem can be viewed as the result of a sequence of decisions. In dynamic programming, we examine the decision sequence to see whether an optimal decision sequence contains optimal decision subsequence. (1) KNAPSACK PROBLEM We have already discussed what a Knapsack problem is. Now let us see how to solve this using dynamic programming. Given: n Number of objects m Total capacity of the sack w[ ] weights of the objects p[ ] profits of the objects

Aim of the problem: Fill the sack up to maximum capacity such that the total profit of selected objects is maximized.

x p
i =1 i

i =n

i is maximized

Constraint:

Total weight of the selected objects should not exceed the maximum capacity of the sack.

xw m
i =1 i i

i =n

where x = { 0.. 1} or x = {0, 1} 0/1 Knapsack problem. Example: N = 3, M = 6 W = { 2, 3, 4 } P = { 1, 2, 5 } 5.1

The Knapsack problem using dynamic programming is solved by first generating all the feasible solutions and then selecting the optimum solution. S represents the set of feasible solution for a collection of objects. The set of feasible solutions is generated using the following technique. Generation of Feasible solutions: Si+1 = Si + Si1 Initially no objects are selected and hence the set has only pair (0,0) in the set. S0 = { (0,0) }; S01 = { (1,2) }

The set S01 is generated by adding (P,W) = (1,2) of the selected object with every pair of the set S0. Similarly the consecutive sets are generated as follows. S1 = { (0,0), (1,2) } S11 = { (2,3), (3,5) } S21 = { (5,4), (6,6), (7,7), (8,9) }

S2 = { (0,0), (1,2), (2,3), (3,5) } S3 = { (0,0), (1,2), (2,3), (5,4), (6,6) }

Now in the last set S3 gives all the possible feasible solutions. From this the solution with the best value is (6,6) and hence this is the optimal solution. The objects selected corresponding to the solution (6,6) is found out using the following technique. First find whether (6,6) is present in the previous set S2. If it is not present then the third object is selected. The solution of this intermediate stage is (6,6) (5,4) = (1,2). Now find out whether (1,2) is present in the previous set S1. We find that this is not present and hence the second object cannot be selected. Now find out whether (1,2) is present in the previous set S0. We find that this is present in that set. Therefore the first object is selected. Therefore the final solution is X={1 0 1} Algorithm DKNAPSACK( n, m, w[], p[], x[] ) s[0].p[1] = 0, s[0].w[1] = 0, s[0].c = 1 for i = 1 to n for j = 1 to s[i-1].c 5.2

s[i].p[j] = s[i-1].p[j] + p[i] s[i].w[j] = s[i-1].w[j] + w[i] s[i].c = s[i].c + 1 end for s[i] = union(s[i], s[i-1]) s[i].c = s[i].c + s[i-1].c l = s[i].c for j = 1 to l if (s[i].p[j] s[i].p[j+1] and s[i].w[j] s[i].w[j+1]) or (s[i].w[j] > m) delete (s[i].p[j], s[i].w[j]) s[i].c = s[i].c 1 end if end for end for last = s[n].c t1 = s[n].p[last], t2 = s[n].p[last] for i = n to 1 if find( t1, t2 ) = s[i 1] x[i] = 0 else x[i] = 1 t1 = t2 p[i] t2 = t2 w[i] end if end for print x[ ] end DKNAPSACK

(2) TRAVELING SALESMAN PROBLEM The traveling salesman problem presents a graph showing n number of cities which are connected using edges. The cost or distance of each edge is given using the cost matrix. Given: A graph showing n number of cities connected by edges. Cost of each edge is given using the cost matrix.

Aim of the problem: Find the shortest path to cover all the cities and come back to the same city. Constraints: All the cities should be covered. Each city should be visited only once. The starting and the ending point should be the same. 5.3

Solution: 1) Find all possible feasible solutions by taking the permutation of the cities which is to be covered. By this all possible paths connecting the cities and satisfying the constraints are generated. 2) Find the cost of each path using the cost matrix. 3) Find out the path with minimum cost. That is selected as the optimum solution. Example: Consider the following example. There are 4 cities given. These are connected with edges as shown. The cost of the edges are shown.

The cost matrix for the given graph is


1 1 2 3 4 0 20 5 10 2 20 0 15 25 3 5 15 0 5 4 10 25 5 0

Let us start visiting from the node 1. Then the remaining 3 cites are 2, 3 and 4. By applying the permutation function we generate the following possible paths. 1 1 1 1 1 1 2 2 3 3 4 4 3 4 2 4 2 3 4 3 4 2 3 2 1 1 1 1 1 1 50 55 55 55 55 50

Now calculate the cost of each path and select the minimum of these. If there more than one path having the same cost, then first occurring path is selected.

5.4

As per the results shown above, the shortest path selected is the first path. Therefore the final solution may be, 1 2 3 4 1

The cost of the path is 50 Algorithm TRAVEL(cost[ ], n ) x=2 for s = 1 to n 1 list[s] = x x=x+1 end for for i = 1 to (n 1)! for j = 2 to n path[i][j] = perm(list) path[i][j] = path[i][n] = 1 pathcost[i] = 0 end for end for for i = 1 to (n-1)! for j = 1 to n pathcost[i] = pathcost[i] + cost[path[i][j]][path[i][j+1]] end for end for min = 0, minpos = 0 for i = 1 to (n-1)! If pathcost[i] < min min = pathcost[i] minpos =i end if end for print Shortest path is path[minpos][ ] print Shortest path cost is pathcost[i] end Travel Program //Travelling Salesman problem using Dynamic Programming

5.5

#include <iostream.h> #include <conio.h> class dynamic { private: int n, r, c[5][5], d[24], p[24][6], list[5]; public: dynamic(); void getdata(); void display(); int fact(int num); int min(int list[]); void perm(int list[], int k, int m); void sol(); }; dynamic::dynamic() { r=0; for (int i=0;i<n;i++) for (int j=0;j<n;j++) c[i][j]=0; } void dynamic::getdata() { cout<<"Enter no. of cities:"; cin>>n; cout<<endl; for (int i=0;i<n;i++) { for (int j=0;j<n;j++) { if (i!=j) { if (c[i][j]==0) { cout<<"Enter cost from "<<i<<" to "<<j<<" :"; cin>>c[i][j]; c[j][i]=c[i][j]; } } } } for (i=0;i<n-1;i++) list[i]=i+1; } int dynamic::fact(int num) 5.6

{ int f=1; if (num!=0) for (int i=1;i<=num;i++) f=f*i; return f; } void dynamic::perm(int list[], int k, int m) { int i,temp; if (k==m) { for (i=0;i<=m;i++) { p[r][i+1]=list[i]; } r++; } else for (i=k;i<=m;i++) { temp=list[k]; list[k]=list[i]; list[i]=temp; perm(list,k+1,m); temp=list[k]; list[k]=list[i]; list[i]=temp; } } void dynamic::sol() { perm(list,0,n-2); for (int i=0;i<fact(n-1);i++) { p[i][0]=0; p[i][n]=0; } for (i=0;i<fact(n-1);i++) { d[i]=0; for (int j=0;j<n;j++) { d[i]=d[i]+c[p[i][j]][p[i][j+1]]; } } } int dynamic::min(int list[]) { int minimum=list[0]; 5.7

for (int i=0;i<(n-1);i++) { if (list[i]<minimum) minimum=list[i]; } return minimum; } void dynamic::display() { int i,j; cout<<endl<<"The cost Matrix:"<<endl; for (i=0;i<n;i++) { for (j=0;j<n;j++) cout<<c[i][j]<<"\t"; cout<<endl; } cout<<endl<<"The Possible paths and their corresponding cost:"<<endl; for (i=0;i<fact(n-1);i++) { for (j=0;j<n+1;j++) cout<<p[i][j]<<"\t"; cout<<"--> "<<d[i]<<endl; } cout<<endl<<"The shortest path :"<<endl; for (i=0;i<fact(n-1);i++) { if (d[i]==min(d)) break; } for (j=0;j<=n;j++) { cout<<p[i][j]<<" "; } cout<<endl<<"\nThe cost of this path is "<<d[i]<<endl; } void main() { clrscr(); dynamic ts; ts.getdata(); ts.sol(); ts.display(); getch(); } Output 5.8

Enter no. of cities:4 Enter cost from 0 to 1 :30 Enter cost from 0 to 2 :6 Enter cost from 0 to 3 :4 Enter cost from 1 to 2 :5 Enter cost from 1 to 3 :10 Enter cost from 2 to 3 :20 The cost Matrix: 0 30 6 4 30 0 5 10 6 5 0 20 4 10 20 0 The Possible paths and their corresponding cost: 0 1 2 3 0 --> 59 0 1 3 2 0 --> 66 0 2 1 3 0 --> 25 0 2 3 1 0 --> 66 0 3 2 1 0 --> 59 0 3 1 2 0 --> 25 The shortest path : 02130 The cost of this path is 25 BACKTRACKING METHOD Backtracking is a systematic way to search for the solution to a problem. In Backtracking method, We begin by defining a solution space for the problem. The solution space is the collection all possible solutions to the given problem. The solution space is usually represented as a tree or a graph. Organize solution space so that it can be easily searched. Once we have defined an organization for the solution space, this is searched in a depth first manner (DFS). During the search if infeasible solution is sensed then backtrack to previous node. The search terminates when we have found the answer.

(1) KNAPSACK PROBLEM We have already discussed about the knapsack problem. Let us see how to solve this using the backtracking method. In this method a solution space is defined for the knapsack problem as shown. 5.9

This solution space consists of all feasible solutions. Now we have to find out which is the feasible solution among this. A Depth First Search Traversal is applied on this solution tree. If an object is selected, then we travel towards the left child as the left edge carries cost 1 indicating the object is selected. If at any stage of the solution, it is found that the constraint is not satisfied, then we backtrack to the previous node and go to the right child indicating that the particular object is not selected. The algorithm stops when a leaf node is reached. Given: n Number of objects m Total capacity of the sack w[ ] weights of the objects p[ ] profits of the objects

Aim of the problem: Fill the sack up to maximum capacity such that the total profit of selected objects is maximized.

x p
i =1 i

i =n

i is maximized

Constraint:

Total weight of the selected objects should not exceed the maximum capacity of the sack.

xw m
i =1 i i

i =n

where x = { 0.. 1} or x = {0, 1} 0/1 Knapsack problem. Example: N = 3, M = 6 W = { 2, 3, 4 } 5.10

P = { 1, 2, 5 } Solution: Since there are 3 objects, construct a tree with maximum level = 3 as shown.

Initially we are in level 0 of the solution space. Select the first object. Since the first object is selected, we move towards the left child of current node. Now we have moved to level 1. Compare the weight of the object selected with the available capacity of the sack. 2<6 Remaining capacity 6 2 = 4 Therefore so far the solution is correct. Now select the second object which has a weight 3 and move towards the left child of the current node. Now we have moved to level 2. Compare the weight of the object selected with the available capacity of the sack. 3<4 Remaining capacity 4 3 = 1 Now select the third object which has weight 4 and move towards the left child of the current node. Now we have moved to level 3. Compare the weight of this object with the available capacity. 4>1 The weight of the object exceeds the available capacity. This leads to an infeasible solution. Therefore backtrack to previous node which is in level 2. Move towards the right child indicating that the third object is not selected. As we have reached the leaf node with a feasible solution, the algorithm comes to an end. The final solution is therefore X = { 1, 1, 0 } Algorithm 5.11

BKNAPSACK( k, cp, cw) If k > n Return End if If cw + w[k] m x[k] = 1 cw = cw + w[k] cp = cp + p[k] KNAPSACK( k + 1, cp, cw ) Else x[k] = 0 KNAPSACK( k + 1, cp, cw ) End if End KNAPSACK (2) 8 QUEENS PROBLEM The solution for the 8 queens problem is easily obtained using the backtracking algorithm. Given, An 8 X 8 matrix representing a chessboard. 8 queens

Aim of the problem: Place 8 queens on the chessboard in such a way that none of the queens hit each other. Constraint: No two queens should be in the same column. No two queens should be in the same diagonal.

Solution: If a queen is placed in position (i, j ). Now a new queen is placed in the position (k, l) then the two queens are said to be in the same diagonal if following conditions are satisfied. i+j=k+l ij=kl The above two equations can be rearranged as follows: ik=lj ik=jl Combining the above two equations, Abs(i k) = Abs(j l) 5.12

Abs indicates the absolute value. If this condition is true, then the queens are in the same diagonal. To check whether the queens are in the same column we just check whether j = l. Now queens are placed one by one in the chessboard by checking the above conditions. If at any stage we are unable to place a queen, then we have to backtrack and change the position of the previous queen. This is repeated till we place all the 8 queens on the board. The algorithm Place checks and tells whether the new position of the queen is correct or not. If it is correct, then it returns true otherwise it returns false. Example: We try to place the queens as shown.

Solution is: 1 5 8 6 3 7 2 4

Algorithm PLACE( k, L ) For i = 1 to k 1 5.13

If x[i] = L or ABS(x[i] l ) = ABS( i k ) Return FALSE End if End for Return TRUE NQUEEN( k, n ) For i = 1 to n If PLACE( k, i ) = TRUE x[k] = i if k = n print x[ ] else NQUEEN( k + 1, n ) End if End if End for End NQUEEN Program //8 Queens problem solution using backtracking method #include <iostream.h> #include <conio.h> #include <stdlib.h> class queen { private: int x[9]; public: int place(int k, int i); void eightqueen(int k); }; int queen::place(int k, int i) { for (int j=1; j<k; j++) if ((x[j]==i) || (abs(x[j]-i)==abs(j-k))) return 0; return 1; } void queen::eightqueen(int k) { for (int i=1; i<=8; i++) { 5.14

if (place(k,i)==1) { x[k]=i; if (k==8) { for (int j=1; j<=8; j++) cout<<x[j]<<"\t"; cout<<endl; } else eightqueen(k+1); } } } void main() { clrscr(); queen q; q.eightqueen(1); getch(); } Output 1 1 1 1 5 6 7 7 8 8 4 5 6 3 6 8 3 7 8 2 7 4 2 4 2 2 5 6 4 5 3 3

BRANCH AND BOUND METHOD The branch and bound method is similar to the backtracking method except that, this method searches the nodes of the solution space in the Breadth First Search method. This braches to various nodes in search of the solution, but if an infeasible solution is encountered, then we bound back and try the next adjacent branch. (1) TRAVELING SALESMAN PROBLEM We have already solved this problem using the dynamic programming method. Now let us see how to solve this problem using branch and bound technique. Given: A graph showing n number of cities connected by edges. Cost of each edge is given using the cost matrix. Aim of the problem: Find the shortest path to cover all the cities and come back to the same city.

5.15

Constraints: Solution: The given graph is the solution space for this problem. Hence we perform a BFS in this graph to find the solution. Start from node 1. Find all the adjacent nodes of the current node. Select the node which is not yet visited and has a least cost edge. Move to the selected node and repeat the above steps. The solution is obtained when al the nodes are visited and we come back to the same city. Example: All the cities should be covered. Each city should be visited only once. The starting and the ending point should be the same.

The cost matrix for the given graph is


1 1 2 3 4 0 20 5 10 2 20 0 15 25 3 5 15 0 5 4 10 25 5 0

In the given graph, we start from node 1. The adjacent nodes of 1 are 2, 3, and 4. But we select node 3 as it has the minimum cost edge. Move to node 3. Repeat the process till we reach the node 1.

5.16

Therefore the solution to the above problem is The shortest path 1 3 4 2 1 The cost of the path is 55. Algorithm BBTRAVEL( cost[ ], n ) u = city 1 Repeat while(all cities visited) Find all cities w adjacent from u If (cost of edge is minimum ) and (city not yet visited) Move to that city and mark it visited u = current city End if End Repeat Calculate path cost Print Shortest path and its cost End TRAVEL 5.17

(2) COTAINER LOADING PROBLEM We have already solved this problem using Greedy approach. Now let us use branch and bound technique to solve this problem. In this problem, there is a ship with capacity m. The number of containers n is given and their respective weights are also given. The containers should be loaded in such a way that we load maximum number of containers in the ship and the total weight of the containers loaded into the ship does not exceed the capacity of the ship. Given: n = Number of containers w[ ] = Weights of the containers m = Total capacity of the ship Aim of the problem: Load the containers into the ship in such a way that the maximum number of containers is loaded.

x
i =1 n

is maximized.

Constraints: The total weight of the containers loaded should not exceed the capacity of the ship.

xw m
i =1 i i

Solution: Develop a solution space, which is represented as tree with left child indicating that the container is selected and the right child indicating that the container is not selected.

Initially we are in the root node. We branch towards the left child and check whether the container weight is lesser than or equal to the available capacity. If not, that is a infeasible solution and hence we bound back and select the next 5.18

adjacent branch. But if the solution is feasible at that stage, we continue selecting the next container. This is repeated till either the number of containers exhausted or the ship capacity has been filled.

Example: Let the three containers given has weight as given: w = { 20, 40, 50 } Let the ship capacity be 70.

Start from the root node. Select the first container by moving to the left child. Compare the weight of the first container with the remaining capacity of the ship. 20 < 70 Remaining capacity = 70 20 = 50 Now select the second container by branching towards the left child. Compare the weight of the container with the available capacity of the ship. 40 < 50 Remaining capacity = 10 Now select the third container by branching towards the left child. Compare the weight of the container with the available capacity of the ship 50 > 10 As the capacity of the container exceeds the capacity of the ship, bound back and go to adjacent branch. As the leaf node is reached and the solution is a feasible solution, the algorithm stops here. The final solution is x = { 1, 1, 0 }
-------End of Unit V------

5.19

Potrebbero piacerti anche