Trouble maker: The growth of redundant calculations is explosive.
Solution: Record the two most recently computed values to avoid recursive calls.
1 2 3 4 5 6 7 8 9 10 11 12 13
intFibonacci(int N) { int i, Last, NextToLast, Answer; if (N <= 1) return1; Last = NextToLast = 1; /*F(0) = F(1) = 1*/ for (i = 2; i <= N; i++) { Answer = Last+NextToLast; /*F(i) = F(i-1) + F(i-2)*/ NextToLast = Last; Last = Answer; /*update F(i-1) and F(i-2)*/ } /* end-for */ return Answer; }
T(N)=O(N)
Ordering Matrix Multiplications
The problem is to find the order that we can compute the product of n matrices with minimal computing time
Let bn = number of different ways to compute M1⋅M2⋯Mn. Then we have b2=1,b3=2,b4=5,⋯
Let Mij=Mi⋯Mj. Then M1n=M1⋯Mn=M1i⋅Mi+1n
Catalan number
bn=i=1∑n−1bibn−i=O(nn4n)where n>1 and b1=1
Suppose we are to multiply n matrices M1⋯Mn where Mi is an ri−1×ri matrix. Let mij be the cost of the optimal way to compute M1⋯Mn where Mi. Then we have the recurrence equations:
/*r contains number of columns for each of the N matrices*/ /*r[0] is the number of rows in matrix 1*/ /*Minimum number of multiplications is left in M[1][N]*/ voidOptMatrix(constlong r[ ], int N, TwoDimArray M) { int i, j, k, L; long ThisM; for(i = 1; i <= N; i++) M[i][i] = 0; for(k = 1; k < N; k++) /*k = j-i*/ for(i = 1; i <= N-k; i++) /* For each position */ { j = i + k; M[i][j] = Infinity; for( L = i; L < j; L++ ) { ThisM = M[ i ][ L ] + M[ L + 1 ][ j ] + r[ i - 1 ] * r[ L ] * r[ j ]; if ( ThisM < M[ i ][ j ] ) /* Update min */ M[ i ][ j ] = ThisM; } /* end for-L */ } /* end for-Left */ }
T(N)=O(N3)
Optimal Binary Search Tree
The best for static searching (without insertion and deletion)
Given N words w1<w2<⋯<wN, and the probability of searching for each wi is pi. Arrange these words in a binary search tree in a way that minimize the expected total access time
Tij is optimal →rij=k such that cij=mini<l≤j{wij+ci,l−1+cl+1,j}
T(N)=O(N3)
Floyd Shortest Path Algorithm
For all pairs of vi and vj(i=j), find the shortest path between.
Method 1
Use single-source algorithm for |V| times
T=O(∣V∣3) —— works fast on sparse graph
Method 2
Define Dk[i][j]=min{length of path i→{l≤k}→j} and D−1[i][j]=Cost[i][j]. Then the length of the shortest path from i to j is DN−1[i][j]
Algorithm
Start from D−1 and successively generate D0,D1,⋯,DN−1. If Dk−1 is done, then either
k∈/ the shortest path i→{l≤k}→j, then Dk=Dk−1
k∈ the shortest path $i\rarr{l\leq k}\rarr j = {\text{the shortest path from i to k}}\cup{\text{the shortest path from k to j}}$, then Dk[i][j]=Dk−1[i][k]+Dk−1[k][j]
/*A[ ] contains the adjacency matrix with A[i][i] = 0*/ /*D[ ] contains the values of the shortest path*/ /*N is the number of vertices*/ /*A negative cycle exists iff D[i][i] < 0*/ voidAllPairs(TwoDimArray A, TwoDimArray D, int N) { int i, j, k; for (i = 0; i < N; i++) /*Initialize D*/ for(j = 0; j < N; j++) D[i][j] = A[i][j]; for(k = 0; k < N; k++) /*add one vertex k into the path*/ for(i = 0; i < N; i++) for(j = 0; j < N; j++) if(D[i][k]+D[k][j] < D[i][j]) D[i][j] = D[i][k]+D[k][j]; /* Update shortest path */ }
T(N)=O(N3), but faster in a dense graph.
Works if there are negative edge costs, but no negative-cost cycles.