**1. Introduction**

This post first introduces the **Strassen algorithm of matrix multiplication** based on divide-and-conquer strategy, and then gives several methods for solving recursion.

**2. Strassen Algorithm for matrix multiplication**

**(1) Common matrix multiplication algorithm**
The basic algorithm for matrix multiplication is calculated as follows:

If A= (AIJ) and b= (bij) are the square of the nxn (I,j = ...), then C = A. The element Cij in B is:

The Java implementation code is given below:

Public Static voidMain (string[] args) {int[] A =New int[][] {//{1, 0, 1, 2},//{1, 2, 0, 2},//{0, 2, 1, 0},//{0, 0, 1, 2},//};int[] B =New int[][] {//{1, 0, 1, 2},//{1, 2, 0, 2},//{0, 2, 1, 0},//{0, 0, 1, 2},//};p Rintmatrix (Squarematrixmutiply (A, b));}/** * Basic matrix multiplication (assuming that both matrices A and B are nxn matrices, and N is a power of 2) * @param a matrix A * @param b Matrix B * @return */Private Static int[] Squarematrixmutiply (int[] A,int[] b) {int[] C =New int[A.length] [A.length]; for(inti = 0; i < c.length; i++) { for(intj = 0; J < C.length; J + +) {C[i][j] = 0; for(intk = 0; K < C.length; k++) {C[i][j] + = a[i][k] * b[k][j];}}}returnC;}/** * Print Matrix * * @param Matrix * *Private Static voidPrintmatrix (int[] matrix) { for(int[] Is:matrix) { for(intI:is) {System.out.print (i + ")\ t");} System.out.println ();}}

Results:

**(2) A simple divide-and-conquer algorithm**
For simplicity, when the matrix C=a*b is computed using the divide-and- **Divide (Conquer) method** , the three matrices are assumed to be nxn matrices, and N is a power of 2. **Divide and Conquer (Divide and Conquer)** or the three steps mentioned in the previous article, the core of the algorithm is this formula:

Among them, AIJ,BIJ,CIJ is the sub-matrix of the N/2 * N/2 of the a,b,c matrix, namely:

It is worth noting that we do not have to create sub-arrays, which will waste θ (N2) of time to copy array elements; It is wise to directly follow the subscript.

is the pseudo-code of the original book (which says "(4.9)" is the three equations given):

The Java implementation code is given below:

Public Static voidMain (string[] args) {int[] A =New int[][] {//{1, 0, 1, 2},//{1, 2, 0, 2},//{0, 2, 1, 0},//{0, 0, 1, 2},//};int[] B =New int[][] {//{1, 0, 1, 2},//{1, 2, 0, 2},//{0, 2, 1, 0},//{0, 0, 1, 2},//};p Rintmatrix (Squarematrixmutiplybyrecursive (NewChildmatrix (A, 0, 0, a.length),NewChildmatrix (b, 0, 0, b.length), 0, 0, 0, 0));}/** * Print Matrix * * @param Matrix * *Private Static voidPrintmatrix (int[] matrix) { for(int[] Is:matrix) { for(intI:is) {System.out.print (i + ")\ t");} System.out.println ();}}/** * Matrix multiplication based on divide-and-conquer method * * @param A * @param b * @return * *Private Static int[] squarematrixmutiplybyrecursive (Childmatrix Matrixa, Childmatrix Matrixb,intLaststartrowa,intLaststartcolumna,intLASTSTARTROWB,intLASTSTARTCOLUMNB) {int[] C =New int[Matrixa.length] [Matrixa.length];if(Matrixa.length = = 1) {C[0][0] = Matrixa.getfromparentmatrix (Matrixa.startrow, Matrixa.startcolumn) *//Matrixb.getfromparentmatrix (Matrixb.startrow, Matrixb.startcolumn);returnC;}intChildlength = MATRIXA.LENGTH/2;//First step: DecompositionChildmatrix childMatrixA11 =NewChildmatrix (Matrixa.parentmatrix, Laststartrowa, Laststartcolumna, childlength); Childmatrix childMatrixA12 =NewChildmatrix (Matrixa.parentmatrix, Laststartrowa, Laststartcolumna + childlength, childlength); Childmatrix childMatrixA21 =NewChildmatrix (Matrixa.parentmatrix, Laststartrowa + childlength, Laststartcolumna, childlength); Childmatrix childMatrixA22 =NewChildmatrix (Matrixa.parentmatrix, Laststartrowa + childlength, Laststartcolumna + childlength, childLength); Childmatrix childMatrixB11 =NewChildmatrix (Matrixb.parentmatrix, LASTSTARTROWB, LASTSTARTCOLUMNB, childlength); Childmatrix childMatrixB12 =NewChildmatrix (Matrixb.parentmatrix, LASTSTARTROWB, LASTSTARTCOLUMNB + childlength, childlength); Childmatrix childMatrixB21 =NewChildmatrix (Matrixb.parentmatrix, Laststartrowb + childlength, LASTSTARTCOLUMNB, childlength); Childmatrix childMatrixB22 =NewChildmatrix (Matrixb.parentmatrix, Laststartrowb + childlength, LASTSTARTCOLUMNB + childlength, childLength);///Step two: Resolveint[] Temp1 = Squarematrixmutiplybyrecursive (childMatrixA11, childMatrixB11, 0, 0, 0, 0);int[] Temp2 = Squarematrixmutiplybyrecursive (childMatrixA12, childMatrixB21, 0, Childlength, childlength, 0);int[] C11 = Summatrix (Temp1, TEMP2);int[] Temp3 = Squarematrixmutiplybyrecursive (childMatrixA11, childMatrixB12, 0, 0, 0, childlength);int[] Temp4 = Squarematrixmutiplybyrecursive (childMatrixA12, childMatrixB22, 0, Childlength, Childlength, childlength);int[] C12 = Summatrix (Temp3, Temp4);int[] Temp5 = Squarematrixmutiplybyrecursive (childMatrixA21, childMatrixB11, childlength, 0, 0, 0);int[] temp6 = Squarematrixmutiplybyrecursive (childMatrixA22, childMatrixB21, Childlength, Childlength, childlength, 0);int[] C21 = Summatrix (TEMP5, TEMP6);int[] TEMP7 = Squarematrixmutiplybyrecursive (childMatrixA21, childMatrixB12, childlength, 0, 0, childlength);int[] Temp8 = Squarematrixmutiplybyrecursive (childMatrixA22, childMatrixB22, Childlength, Childlength, Childlength, Childlength);int[] C22 = Summatrix (TEMP7, TEMP8);//Step three: Merging for(inti = 0; i < c.length; i++) { for(intj = 0; J < C.length; J + +) {if(I < Childlength && J < Childlength) {C[i][j] = c11[i][j];}Else if(I < Childlength && J < C.length) {int[] Child = c12;c[i][j] = Child[i][j-childlength];}Else if(I < C.length && J < Childlength) {int[] Child = c21;c[i][j] = child[i-childlength][j];}Else{int[] Child = c22;c[i][j] = Child[i-childlength][j-childlength];}}returnC;}Private Static int[] Summatrix (int[] A,int[] b) {int[] C =New int[A.length] [B.length]; for(inti = 0; i < a.length; i++) { for(intj = 0; J < A.length; J + +) {C[i][j] + = a[i][j];c[i][j] + = B[i][j];}}returnC;}/** * Childmatrix represents a sub-matrix of a matrix * * @author D.K * */Static classChildmatrix {/** * Parent Matrix * /int[] Parentmatrix;/** * The starting line coordinates of the sub-matrix in the parent matrix * /intStartRow;/** * The starting column coordinates of the sub-matrix in the parent matrix * /intStartColumn;/** * Sub-matrix length * /intLength PublicChildmatrix (int[] Parentmatrix,intStartRow,intStartColumn,intLength) {Super(); This. Parentmatrix = Parentmatrix; This. StartRow = StartRow; This. StartColumn = StartColumn; This. length = length;}/** * Gets the row row of the parent matrix, colum column element * * @param row * @param colum * @return * * Public intGetfromparentmatrix (intRowintColum) {returnParentmatrix[row][colum];}}

The result is:

**(3) Strassen algorithm**
The core idea of the Strassen algorithm is to make the recursive tree slightly less lush, and it only carries 7 recursion (the above divide-and-conquer recursively 8 times). The Strassen algorithm is described as follows:

The ① decomposition Matrix A,b,c

Also do not create sub-arrays but just subscript calculations.

② creates a matrix S1,s2,s3...,s10 of 10 n/2xn/2, which is calculated as follows:

The ③ calculates 7 matrices of P1 recursively, P2 ... P3,P7, the calculation formula is as follows:

④ calculates the CIJ and calculates the formula as follows:

The implementation code is not given, similar to the above.

**3. Algorithm Analysis**

**(1) Common matrix multiplication**
For normal matrix multiplication, 3 nested loops, each of which executes N times, takes a time of θ (N3);

**(2) Simple divide and conquer algorithm**
① **Basic Condition:**T (1) =θ (1);

② **recursion:** after decomposition, the matrix size becomes the original 1/2. Recursion eight times, Time 8T (N/2), 4 matrix addition, the number of elements in each matrix is N2/4, time θ (N2), and the remainder is θ (1). Therefore, the total time is 8T (N/2) +θ (n2).

solvable, T (n) =θ (n3). It can be seen that the divide and conquer algorithm is not superior to ordinary matrix multiplication

**(3) Strassen algorithm**
The Strassen algorithm analysis is basically consistent with the above, except that only 7 recursion is performed, and an additional number of additions to the N/2XN/2 matrix are made, but only a few times. The Strassen algorithm takes:

solvable, T (n) =θ (N^LG7);

Divide and Conquer strategy (2)--Introduction to Algorithms (4)