Strassen 矩阵乘法

         快累死了,因为计算这个计算的头晕脑胀,加减乘除严重的忘记了,总算是出来了,

          矩阵乘法最原始的解决手段大家都是知道的,但是算法的时间复杂度却是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;
	}
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值