Introduction to algorithms (2) and introduction to Algorithms
Introduction to algorithms (2)
- Introduction to algorithms 2
- Rule separation policy
- Proxy Method
- Recursive tree
- Main Method
- Maximum sub-array
- Matrix Algorithm
- Normal computing
- Strassen Algorithm
Rule Division Rule Generation Method
Two steps:
1) form of speculative Solution
2) use mathematical induction to find the true valid Constants
Recursive tree
Draw a recursive tree to make good guesses.
In the recursive tree, each node represents the cost of a subproblem in the set of recursive function calls. We add the cost of each layer in the tree to get a set of cost of each layer, and then sum the cost of each layer to get the total cost of all layers of recursion.
T (n) = 3 T (n/4) + cn ^ 2
Main Method
There are three main theorem cases. Different cases have different usage.
Max sub-array
There are three possible cases in A [low... high:
So it can be solved recursively.
Code
#include <cstdio>const int MININT = -10000;int crossArray(int a[],int low,int high){ int mid=(low+high)/2, sum=0, left=0, right=0; for (int i = mid; i >=low ; i--) { sum+=a[i]; if (sum>left) { left=sum; } } sum=0; for (int i = mid+1; i <=high ; ++i) { sum+=a[i]; if (sum>right) { right=sum; } } return left+right;}int maxArray(int a[],int low,int high){ if(low==high){return a[low];} int mid=(low+high)/2, leftMax=MININT, rightMax=MININT, centerMax=MININT; leftMax=maxArray(a,low,mid); rightMax=maxArray(a,mid+1,high); centerMax=crossArray(a,low,high); if (leftMax>=rightMax&&leftMax>=centerMax){ return leftMax; }else if(rightMax>=leftMax&&rightMax>=centerMax){ return rightMax; }else{ return centerMax; }}int main(int argc, char const *argv[]){ int a[7]={2,-5,6,12,66,1,-55}; printf("%d\n",maxArray(a,0,6)); return 0;}
Common matrix algorithm computing
MARTRIX-MULTIPLY(A,B){ n=A.length; ElemType C[N]; for i=1 to n for j=1 to n C^ij=0 for k=1 to n C^ij=C^ij+A^ik*B^kj; return C;}
Strassen Algorithm
Generally, the time complexity of matrix multiplication is n ^ 3 = n ^ {log2 ^ 8}, and the Strassen algorithm is O (n ^ {log2 ^ 7 }) = O (n ^ {2.807 }). However, the Strassen algorithm has poor numerical stability.
Generally, the algorithm requires eight multiplication times.
R = a * e + B * g;
S = a * f + B * h;
T = c * e + d * g;
U = c * f + d * h;
Strassen converts it to 7 multiplication, because we all know that multiplication consumes more than addition and subtraction, and all time is more complex.
Strassen's processing is:
Order:
P1 = a * (f-h)
P2 = (a + B) * h
P3 = (c + d) * e
P4 = d * (g-e)
P5 = (a + d) * (e + h)
P6 = (B-d) * (g + h)
P7 = (a-c) * (e + f)
We can know that:
R = p5 + p4 + p6-p2
S = p1 + p2
T = p3 + p4
U = p5 + p1-p3-p7
// Strassen algorithm: reduce the complexity of matrix multiplication to O (n ^ lg7 )~ = O (n ^ 2.81) // The principle is to reduce 8 multiplications to 7 Operations // The best algorithm in theory is O (n ^ 2,367 ), it's just theoretical. // the following code is just a simple instance. You don't have to be honest ~ // The following space can be optimized, so it won't be difficult here ~ # Include <stdio. h> # define N 10 // matrix + matrixvoid plus (int t [N/2] [N/2], int r [N/2] [N/2], int s [N/2] [N/2]) {int I, j; for (I = 0; I <N/2; I ++) {for (j = 0; j <N/2; j ++) {t [I] [j] = r [I] [j] + s [I] [j] ;}} // matrix-matrixvoid minus (int t [N/2] [N/2], int r [N/2] [N/2], int s [N/2] [N/2]) {int I, j; for (I = 0; I <N/2; I ++) {for (j = 0; j <N/2; j ++) {t [I] [j] = r [I] [j]-s [I] [j] ;}} // matrix * matrixvoid mul (int t [N/2] [N/2], int r [N/2] [N/2], int s [N/2] [N/2]) {int I, j, k; for (I = 0; I <N/2; I ++) {for (j = 0; j <N/2; j ++) {t [I] [j] = 0; for (k = 0; k <N/2; k ++) {t [I] [j] + = r [I] [k] * s [k] [j] ;}}} int main () {int I, j, k; int mat [N] [N]; int m1 [N] [N]; int m2 [N] [N]; int a [N/2] [N/2], B [N/2] [N/2], c [N/2] [N/2], d [N/2] [N/2]; int e [N/2] [N/2], f [N/2] [N/2], g [N/2] [N/2], h [N/2] [N/2]; int p1 [N/2] [N/2], p2 [N/2] [N/2], p3 [N/2] [N/2], p4 [N/2] [N/2]; int p5 [N/2] [N/2], p6 [N/2] [N/2], p7 [N/2] [N/2]; int r [N/2] [N/2], s [N/2] [N/2], t [N/2] [N/2], u [N/2] [N/2], t1 [N/2] [N/2], t2 [N/2] [N/2]; printf ("\ nInput the first matrix...: \ n "); for (I = 0; I <N; I ++) {for (j = 0; j <N; j ++) {scanf ("% d", & m1 [I] [j]) ;}} printf ("\ nInput the second matrix...: \ n "); for (I = 0; I <N; I ++) {for (j = 0; j <N; j ++) {scanf ("% d", & m2 [I] [j]) ;}// a B c d e f g h for (I = 0; I <N/2; I ++) {for (j = 0; j <N/2; j ++) {a [I] [j] = m1 [I] [j]; B [I] [j] = m1 [I] [j + N/2]; c [I] [j] = m1 [I + N/2] [j]; d [I] [j] = m1 [I + N/2] [j + N/2]; e [I] [j] = m2 [I] [j]; f [I] [j] = m2 [I] [j + N/2]; g [I] [j] = m2 [I + N/2] [j]; h [I] [j] = m2 [I + N/2] [j + N/2];} // p1 minus (r, f, h ); mul (p1, a, r); // p2 plus (r, a, B); mul (p2, r, h); // p3 plus (r, c, d); mul (p3, r, e); // p4 minus (r, g, e); mul (p4, d, r); // p5 plus (r, a, d); plus (s, e, f); mul (p5, r, s); // p6 minus (r, B, d); plus (s, g, h); mul (p6, r, s); // p7 minus (r, a, c); plus (s, e, f); mul (p7, r, s); // r = p5 + p4-p2 + p6 plus (t1, p5, p4); minus (t2, t1, p2); plus (r, t2, p6); // s = p1 + p2 plus (s, p1, p2); // t = p3 + p4 plus (t, p3, p4 ); // u = p5 + p1-p3-p7 = p5 + p1-(p3 + p7) plus (t1, p5, p1); plus (t2, p3, p7 ); minus (u, t1, t2); for (I = 0; I <N/2; I ++) {for (j = 0; j <N/2; j ++) {mat [I] [j] = r [I] [j]; mat [I] [j + N/2] = s [I] [j]; mat [I + N/2] [j] = t [I] [j]; mat [I + N/2] [j + N/2] = u [I] [j];} printf ("\ n below is the strassen algorithm processing result: \ n "); for (I = 0; I <N; I ++) {for (j = 0; j <N; j ++) {printf ("% d", mat [I] [j]);} printf ("\ n ");} // The following is the result of processing the SIMPLE algorithm printf ("\ n: \ n"); for (I = 0; I <N; I ++) {for (j = 0; j <N; j ++) {mat [I] [j] = 0; for (k = 0; k <N; k ++) {mat [I] [j] + = m1 [I] [j] * m2 [I] [j] ;}} for (I = 0; I <N; I ++) {for (j = 0; j <N; j ++) {printf ("% d", mat [I] [j]);} printf ("\ n");} return 0 ;}
Strassen Algorithm