0% found this document useful (0 votes)
25 views13 pages

Chapter3_odd

2020111522256195Foundations of Algorithms - Richard E. Neapolitan Chapter3_odd Solution

Uploaded by

히마가나
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views13 pages

Chapter3_odd

2020111522256195Foundations of Algorithms - Richard E. Neapolitan Chapter3_odd Solution

Uploaded by

히마가나
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Chapter 3: Dynamic Programming Solutions

Section 3.1

1) Establish Equality 3.1 given in this section.

If k = 0, the definition of the binomial coefficient

gives n!/(1∙n!) = 1. If k=n, the same definition yields n!/(n!∙1) = 1.

 n − 1  n − 1 (n − 1)! (n − 1)!
We are left with the case 0 < k < n:   +   = + =
 k − 1  k  (k − 1)!(n − k )! k!(n − k − 1)!
(n − 1)! (n − 1)! (n − 1)! n(n − 1)! n! n
k + (n − k ) = (k + n − k ) = = =  
k!(n − k )! k!(n − k )! k!(n − k )! k!(n − k )! k!(n − k )!  k 

3) Implement both algorithms for the Binomial Coefficient problem (Algorithms 3.1 and 3.2)
on your system and study their performances using different problem instances.

/*Program that times Binomial function calls*/


#include <time.h>
#include <iostream>
using namespace std;

//Recursive binomial
int bino_rec(int n, int k){
if ( k == 0 || k == n ) /* base case */
return 1;
else /* recursive step */
return bino_rec(n-1, k-1) + bino_rec(n-1, k);
}

int B[101][101]; //for algorithm simplicity only!

//Dynamic programming binomial


int bino_dyn(int n, int k){
Chapter 3: Dynamic Programming Solutions

int min;

for (int i=0; i<=n; i++){


if (i<k) min = i;
else min = k;
for(int j=0; j<=min; j++)
if (j==0 || j==i)
B[i][j] = 1;
else
B[i][j] = B[i-1][j-1] + B[i-1][j];
}
return B[n][k];
}

int main(){
time_t begin, end;
int N, k;
cout << ("Enter positive integer N(<=100): ");
cin >> N;
cout << ("Enter positive integer k(<=100): ");
cin >> k;
begin = time(NULL);
cout << "Binomial recursive : " << bino_rec(N,k) << endl;
end = time(NULL);
cout << "\ttime = " << difftime(end, begin) << " s" << endl;

begin = time(NULL);
cout << "Fibonacci dynamic prog.: " << bino_dyn(N,k) << endl;
end = time(NULL);
cout << "\ttime = " << difftime(end, begin) << " s" << endl <<endl;

return 0;
}

As expected, increasing k makes the recursive algorithm “go exponential”.


Chapter 3: Dynamic Programming Solutions

Section 3.2

5) Use Floyd’s algorithm for the Shortest Paths problem 2 (Algorithm 3.4) to

construct the matrixD, which contains the lengths of the shortest paths, and

the matrixP, which contains the highest indices of the intermediate vertices

on the shortest paths, for the following graph. Show the actions step by step.

Constructing D:

D0:
0 4 INF INF INF 10 INF
3 0 INF 18 INF INF INF
INF 6 0 INF INF INF INF
INF 5 15 0 2 19 5
INF INF 12 1 0 INF INF
INF INF INF INF INF 0 10
INF INF INF 8 INF INF 0

D1:
0 4 INF INF INF 10 INF
3 0 INF 18 INF 13 INF
INF 6 0 INF INF INF INF
INF 5 15 0 2 19 5
INF INF 12 1 0 INF INF
INF INF INF INF INF 0 10
INF INF INF 8 INF INF 0
Chapter 3: Dynamic Programming Solutions

D2:
0 4 INF 22 INF 10 INF
3 0 INF 18 INF 13 INF
9 6 0 24 INF 19 INF
8 5 15 0 2 18 5
INF INF 12 1 0 INF INF
INF INF INF INF INF 0 10
INF INF INF 8 INF INF 0

D3:
0 4 INF 22 INF 10 INF
3 0 INF 18 INF 13 INF
9 6 0 24 INF 19 INF
8 5 15 0 2 18 5
21 18 12 1 0 31 INF
INF INF INF INF INF 0 10
INF INF INF 8 INF INF 0

D4:
0 4 37 22 24 10 27
3 0 33 18 20 13 23
9 6 0 24 26 19 29
8 5 15 0 2 18 5
9 6 12 1 0 19 6
INF INF INF INF INF 0 10
16 13 23 8 10 26 0

D5:
0 4 36 22 24 10 27
3 0 32 18 20 13 23
9 6 0 24 26 19 29
8 5 14 0 2 18 5
9 6 12 1 0 19 6
INF INF INF INF INF 0 10
16 13 22 8 10 26 0

D6:
0 4 36 22 24 10 20
3 0 32 18 20 13 23
9 6 0 24 26 19 29
8 5 14 0 2 18 5
9 6 12 1 0 19 6
INF INF INF INF INF 0 10
16 13 22 8 10 26 0
Chapter 3: Dynamic Programming Solutions

D7:
0 4 36 22 24 10 20
3 0 32 18 20 13 23
9 6 0 24 26 19 29
8 5 14 0 2 18 5
9 6 12 1 0 19 6
26 23 32 18 20 0 10
16 13 22 8 10 26 0

Constructing P:
P0:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

P1:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

P2:
0 0 0 2 0 0 0
0 0 0 0 0 0 0
2 0 0 2 0 2 0
2 0 0 0 0 2 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

P3:
0 0 0 2 0 0 0
0 0 0 0 0 0 0
2 0 0 2 0 2 0
2 0 0 0 0 2 0
3 3 0 0 0 3 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
Chapter 3: Dynamic Programming Solutions

P4:
0 0 4 2 4 0 4
0 0 4 0 4 0 4
2 0 0 2 4 2 4
2 0 0 0 0 2 0
4 4 0 0 0 4 4
0 0 0 0 0 0 0
4 4 4 0 4 4 0

P5:
0 0 5 2 4 0 4
0 0 5 0 4 0 4
2 0 0 2 4 2 4
2 0 5 0 0 2 0
4 4 0 0 0 4 4
0 0 0 0 0 0 0
4 4 5 0 4 4 0

P6:
0 0 5 2 4 0 6
0 0 5 0 4 0 4
2 0 0 2 4 2 4
2 0 5 0 0 2 0
4 4 0 0 0 4 4
0 0 0 0 0 0 0
4 4 5 0 4 4 0

P7:
0 0 5 2 4 0 6
0 0 5 0 4 0 4
2 0 0 2 4 2 4
2 0 5 0 0 2 0
4 4 0 0 0 4 4
7 7 7 7 7 0 0
4 4 5 0 4 4 0

7) Analyze the Print Shortest Path algorithm (Algorithm 3.5) and show that it has a linear-
time complexity.

To evaluate complexity, we count the number of array accesses P[i][j].


The path from any vertex q to any vertex r has in the worst case n-1 edges (n is the nr. of
vertices in the graph). For each of the n-1 edges, Algorithm 3.4 evaluates P[i][j] four times, so
the worst-case complexity is 4(n-1) (n).
Chapter 3: Dynamic Programming Solutions

9) Can Floyd’s algorithm for the Shortest Paths problem 2 (Algorithm 3.4) be modified to give
just the shortest path from a given vertex to another specified vertex in a graph? Justify your
answer.

Working backwards from D(n)(i,j), we note that it only depends on 3 values from the previous
table D(n-1). Based on this it is possible to reduce the number of operations by only calculating
one value from D(n), three values from D(n-1), etc. As we regress towards D(0), however, the
number of values grows and ends up being n2 (the entire table), and the asymptotic
complexity remains (n3).

Section 3.3

11) Find an optimization problem in which the principle of optimality does not apply and
therefore the optimal solution cannot be obtained using dynamic programming. Justify your
answer.

The text example: Finding the longest path between two vertices A → C of a graph (without
loops) does not have optimal substructure: if the longest path is A → … → B → … → C, this
doesn’t mean that:
• the subpath B → … → C is longest; for instance, in the B→C problem we may find that the
longest path contains A, which would create a cycle in the original problem A → C, so it’s
not allowed there.
• the subpath A → … → B is longest; for instance, in the A→B problem we may find that the
longest path contains C.

Another example: Raising a number to an integer power n with the fewest number of
multiplications (a.k.a. the Addition Chain Exponentiation problem). When n is a power of 2,
the best way is successive squaring, e.g. x8 =((x∙x)2)2 requires only 3 multiplications. If n is not
a power of 2, however, there is no optimal substructure, because a subproblem is not always
solved optimally by itself; we can prefer a suboptimal solution to a subproblem because parts
of the solution can be reused to solve other subproblems. This problem was proved to be NP-
complete (see Ch.9).
Chapter 3: Dynamic Programming Solutions

Section 3.4

13) Find the optimal order, and its cost, for evaluating the product A1×A2× A3×A4×A5, where
A1 is (10×4)
A2 is (4×5)
A3 is (5×20)
A4 is (20×2)
A5 is (2×50)
Show the final matrices M and P produced by Algorithm 3.6.

M:

0 200 1200 320 1320


0 400 240 640
0 200 240
0 2000
0

P:

1 1 1 4
2 2 4
3 4
4

Optimal order = (A1(A2(A3∙A4)))A5 Optimal cost: 1320 multiplications


Chapter 3: Dynamic Programming Solutions

15) Show that a divide-and-conquer algorithm based on Equality 3.5 has an exponential-time
complexity.

For illustration, we use the M table from Exercise 13:

0 200 1200 320 1320


0 400 240 640
0 200 240
0 2000
0

As in the analysis of the Minimum Multiplications algorithm, we take the basic operation to be
one evaluation of k. A problem of size n (obtaining the 1320 in example above) requires
evaluation of more than two problems of size n-1 (320 and 640 above), so we have the
inequality T(n) ≥ 2T(n-1) ≥ 2∙2T(n-2) ≥ … ≥ 2n.

17) Establish the equality

n −1 n −1
By multiplying out each term inside the sum, we have: n d − d 2
. The first sum is solved
d =1 d =1
in Example A.1, and the second in Example A.2; we only have to replace n with n-1:
(n − 1)n (n − 1)n [2(n − 1) + 1] n(n − 1)( n + 1)
n − = .
2 6 6

19) Analyze Algorithm 3.7 and show that it has a linear-time complexity.

Every call to order prints one pair of parentheses, and according to Exercise 18, a problem of
size n needs only n-1 pairs, which is (n).
Chapter 3: Dynamic Programming Solutions

Section 3.5

21) How many different binary search trees can be constructed using six distinct keys?

By the formula in Exercise 36: (1/7)*(12 choose 6) = (1/7)*924 = 132

j
23) Find an efficient way to compute p
m =i
m which is used in the Optimal Binary Search Tree

Algorithm (Algorithm 3.9).

j
The partial sums can be stored in an n x n table B, whose position B[i][j] stores p
m =i
m . We

have the recursion B[i][j+1] = B[i][j] + pj+1.


Below is a partial example with the probabilities from Exercise 22:
1 2 3 4 5 6
1 .05 .20 .25
2 .15
3 .05
4 .35
5 .05
6 .35

25) Analyze Algorithm 3.10, and show its time complexity using order notation.

We define the basic operation to be the access of an element of the array R; this is done once
per each call to the function tree, and each such call inserts in the tree one node. Since there
are n nodes total, the number of calls and that of basic operations is n, so the complexity is
linear, (n).
Chapter 3: Dynamic Programming Solutions

27) Show that a divide-and-conquer algorithm based on Equality 3.6 has an exponential time
complexity.

For illustration, we use the A table from Exercise 22:

0 1 2 3 4 5 6
1 0 .05 .25 .35 .95 1.05 1.8
2 0 .15 .25 .8 .9 1.65
3 0 .05 .45 .55 1.3
4 0 .35 .45 1.2
5 0 .05 .45
6 0 .35
7 0

As in the analysis of the Minimum Multiplications algorithm, we take the basic operation to be
one evaluation of k. A problem of size n (obtaining the 1.8 in example above) requires
evaluation of more than two sub-problems of size n-1 (1.05 and 1.65 above), so we have the
inequality T(n) ≥ 2T(n-1) ≥ 2∙2T(n-2) ≥ … ≥ 2n.
Chapter 3: Dynamic Programming Solutions

Section 3.6

29) Write a more detailed version of the Dynamic Programming algorithm for the TSP
(Algorithm 3.11).

One design decision is how to store the subsets of vertices. This can be done, for example, with
an array of n linked lists, each of them holding the set of vertices (from zero – empty set – to
(n – 2) sets) and the respective optimal cost and j vertex associated.

Below is an example of matrix D for n = 5 (from Exercise 28). The “ground” symbol means a
null pointer. Only the line for v2 is shown:

The sets themselves can be stored as strings, arrays of boolean (used below), or even the data
structure described in Appendix C.

For homogeneity, the list node for the empty set can be made the same as the others
(although technically it does not need a j index or a next pointer):
struct NodeType{
bool set[n-1];
int min;
int jay;
struct NodeType* next;
};
Chapter 3: Dynamic Programming Solutions

When we generate the subsets A ⊆ V− {v1} containing k vertices, we need to store them in an
array:
bool arrayOfSubsets[1..maxSubsets][n-1]
where maxSubsets is the maximum over k of Binomial(n-2, k), so it can store the most subsets
that can be generated. Alternatively, the subsets can also be stored in a linked list.

The more detailed pseudocode is:


void travel (int n, const number W[][], index P[][], number& minlength) {
index i , j , k, temp_j, minIndex;
number value, temp_min;
struct nodeType* D[2..n][ 0..n-2];
for (i = 2; i <= n; i++)
D[ i ][0]->min = W[ i ][1];
for (k = 1; k <= n−2; k++) {
Generate all subsets A ⊆ V−{v1} containing k vertices, store them in arrayOfSubsets;
for ( all subsets A in arrayOfSubsets)
for (i such that i != 1 and vi is not in A) {
temp_min = INFINITY;
for (each j:vj∈A) {
find in the list D[ j ][k-1] the node x containing the set A− {vj};
value = W[ i ][ j ] + x.min;
if (value < temp_min) {
temp_min = value;
temp_j = j ;
}
}
Navigate to end of list D[i][k];
Append a node y with:
y.min = temp_min;
y.jay = temp_j;
} //end for i
}
} //end for k
minlength = minimum (W[1][ j ] + D[ j ][V− {v1,vj}]);
2≤j≤n
minIndex = value of j that gave the minimum;
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy