快累死了,因为计算这个计算的头晕脑胀,加减乘除严重的忘记了,总算是出来了,
矩阵乘法最原始的解决手段大家都是知道的,但是算法的时间复杂度却是O(n^3),如果采用Strassen对问题的分析,在分治的基础上,计算的时间复杂度变为了O(n^2.81),废话少说,代码奉上:
public class Num1 {
public static void main(String[] args) {
int[][] nul1 = { { 1, 2, 3, 4 }, { 2, 5, 8, 9 }, { 9, 1, 4, 6 },
{ 5, 2, 3, 9 } };
int[][] nul2 = { { 5, 6, 6, 4 }, { 8, 7, 8, 7 }, { 8, 5, 2, 3 },
{ 7, 8, 9, 5 } };
// int[][] nul1 = { {5,6}, { 8,7 }};
// int[][] nul2 = { { 13,7}, {8,11} };
int length = nul1.length;
int[][] num = new int[length][length];
num = multip(nul1, nul2);
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++)
System.out.print(num[i][j] + " ");
System.out.println();
}
}
private static int[][] multip(int[][] nul1, int[][] nul2) {
int len = nul1.length;
int[][] re = new int[len][len];
if (len == 2) {
int p = (nul1[0][0] + nul1[1][1]) * (nul2[0][0] + nul2[1][1]);
int q = nul2[0][0] * (nul1[1][0] + nul1[1][1]);
int r = nul1[0][0] * (nul2[0][1] - nul2[1][1]);
int s = nul1[1][1] * (nul2[1][0] - nul2[0][0]);
int t = (nul1[0][0] + nul1[0][1]) * nul2[1][1];
int u = (nul1[1][0] - nul1[0][0]) * (nul2[0][0] + nul2[0][1]);
int v = (nul1[0][1] - nul1[1][1]) * (nul2[1][0] + nul2[1][1]);
re[0][0] = p + s - t + v;
re[0][1] = r + t;
re[1][0] = q + s;
re[1][1] = p + r - q + u;
} else {
int[][] A1 = new int[len / 2][len / 2];
int[][] A2 = new int[len / 2][len / 2];
int[][] A3 = new int[len / 2][len / 2];
int[][] A4 = new int[len / 2][len / 2];
int[][] B1 = new int[len / 2][len / 2];
int[][] B2 = new int[len / 2][len / 2];
int[][] B3 = new int[len / 2][len / 2];
int[][] B4 = new int[len / 2][len / 2];
int i;
int j;
int index1 = len / 2;
for (i = 0; i < len / 2; i++)
for (j = 0; j < len / 2; j++) {
A1[i][j] = nul1[i][j];
B1[i][j] = nul2[i][j];
}
for (i = 0; i < len / 2; i++)
for (j = len / 2; j < len; j++) {
A2[i][j - index1] = nul1[i][j];
B2[i][j - index1] = nul2[i][j];
}
for (i = len / 2; i < len; i++)
for (j = 0; j < len / 2; j++) {
A3[i - index1][j] = nul1[i][j];
B3[i - index1][j] = nul2[i][j];
}
for (i = len / 2; i < len; i++)
for (j = len / 2; j < len; j++) {
A4[i - index1][j - index1] = nul1[i][j];
B4[i - index1][j - index1] = nul2[i][j];
}
int[][] P = new int[len / 2][len / 2];
int[][] Q = new int[len / 2][len / 2];
int[][] R = new int[len / 2][len / 2];
int[][] S = new int[len / 2][len / 2];
int[][] T = new int[len / 2][len / 2];
int[][] U = new int[len / 2][len / 2];
int[][] V = new int[len / 2][len / 2];
P = multip(add(A1, A4), add(B1, B4));
Q = multip(add(A3, A4), B1);
R = multip(A1, sub(B2, B4));
S = multip(A4, sub(B3, B1));
T = multip(add(A1, A2), B4);
U = multip(sub(A3, A1), add(B1, B2));
V = multip(sub(A2, A4), add(B3, B4));
System.out.println("----P----");
for (int m = 0; m < P.length; m++) {
for (int n = 0; n < P.length; n++)
System.out.print(P[m][n] + " ");
System.out.println();
}
System.out.println("---------");
System.out.println("----Q----");
for (int m = 0; m < Q.length; m++) {
for (int n = 0; n < Q.length; n++)
System.out.print(Q[m][n] + " ");
System.out.println();
}
System.out.println("---------");
System.out.println("----R----");
for (int m = 0; m < R.length; m++) {
for (int n = 0; n < R.length; n++)
System.out.print(R[m][n] + " ");
System.out.println();
}
System.out.println("---------");
System.out.println("----S----");
for (int m = 0; m < S.length; m++) {
for (int n = 0; n < S.length; n++)
System.out.print(S[m][n] + " ");
System.out.println();
}
System.out.println("---------");
System.out.println("----T----");
for (int m = 0; m < T.length; m++) {
for (int n = 0; n < T.length; n++)
System.out.print(T[m][n] + " ");
System.out.println();
}
System.out.println("---------");
System.out.println("----U----");
for (int m = 0; m < U.length; m++) {
for (int n = 0; n < U.length; n++)
System.out.print(U[m][n] + " ");
System.out.println();
}
System.out.println("---------");
System.out.println("----V----");
for (int m = 0; m < V.length; m++) {
for (int n = 0; n < V.length; n++)
System.out.print(V[m][n] + " ");
System.out.println();
}
System.out.println("---------");
int[][] C1 = new int[len / 2][len / 2];
int[][] C2 = new int[len / 2][len / 2];
int[][] C3 = new int[len / 2][len / 2];
int[][] C4 = new int[len / 2][len / 2];
C1 = sub(add(P, S, V), T);
C2 = add(R, T);
C3 = add(Q, S);
C4 = sub(add(P, R, U), Q);
int m, n;
int index = len / 2;
for (m = 0; m < index; m++)
for (n = 0; n < index; n++)
re[m][n] = C1[m][n];
for (m = 0; m < index; m++)
for (n = 0; n < index; n++)
re[m][n + index] = C2[m][n];
for (m = 0; m < index; m++)
for (n = 0; n < index; n++)
re[m + index][n] = C3[m][n];
for (m = 0; m < index; m++)
for (n = 0; n < index; n++)
re[m + index][n + index] = C4[m][n];
}
return re;
}
private static int[][] sub(int[][] b2, int[][] b4) {
int len = b2.length;
int[][] sub = new int[len][len];
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
sub[i][j] = b2[i][j] - b4[i][j];
return sub;
}
private static int[][] add(int[][] a1, int[][] a2, int[][]... arg) {
int len = a1.length;
int[][] sum = new int[len][len];
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
sum[i][j] = a1[i][j] + a2[i][j];
for (int i = 0; i < arg.length; i++)
for (int j = 0; j < a1.length; j++)
for (int k = 0; k < a1.length; k++)
sum[j][k] += arg[i][j][k];
return sum;
}
}