我遇到分歧并征服矩阵乘法工作。根据我的理解,你将大小为nxn的矩阵分成象限(每个象限是n / 2),然后你做:
C11 = A11⋅ B11 + A12 ⋅ B21
C12 = A11⋅ B12 + A12 ⋅ B22
C21 = A21 ⋅ B11 + A22 ⋅ B21
C22 = A21 ⋅ B12 + A22 ⋅ B22
我的分而治之的输出真的很大,我在找出问题时遇到了麻烦,因为我对递归并不是很好。
示例输出:
原始矩阵A:
4 0 4 3
5 4 0 4
4 0 4 0
4 1 1 1
A x A
古典:
44 3 35 15
56 20 24 35
32 0 32 12
29 5 21 17
分而治之:
992 24 632 408
1600 272 720 1232
512 0 512 384
460 17 405 497
有人可以告诉我,我为分而治之做错了吗?我的所有矩阵都是int[][]
,经典方法是传统的3循环矩阵乘法
答案 0 :(得分:5)
您以错误的方式递归调用divideAndConquer
。你的函数做的是对矩阵进行平方。为了使分割和征服矩阵乘法起作用,它需要能够将两个可能不同的矩阵相乘。
看起来应该是这样的:
private static int[][] divideAndConquer(int[][] matrixA, int[][] matrixB){
if (matrixA.length == 2){
//calculate and return base case
}
else {
//make a11, b11, a12, b12 etc. by dividing a and b into quarters
int[][] c11 = addMatrix(divideAndConquer(a11,b11),divideAndConquer(a12,b21));
int[][] c12 = addMatrix(divideAndConquer(a11,b12),divideAndConquer(a12,b22));
int[][] c21 = addMatrix(divideAndConquer(a21,b11),divideAndConquer(a22,b21));
int[][] c22 = addMatrix(divideAndConquer(a21,b12),divideAndConquer(a22,b22));
//combine result quarters into one result matrix and return
}
}
答案 1 :(得分:2)
尝试一些调试方法:
尝试一些非常简单的测试矩阵作为输入(例如全零,具有一个或几个战略矩阵)。您可能会在“失败”中看到一个模式,它会显示您的错误所在。
确保您的“经典”方法能够为您提供正确的答案。对于小型矩阵,您可以在线使用Woflram Alpha来测试答案:http://www.wolframalpha.com/examples/Matrices.html
调试递归:在函数的入口和出口添加printf()
语句,包括调用参数。运行测试矩阵,将输出写入日志文件,然后使用文本编辑器打开日志文件。逐步完成每个案例,在编辑器中编写注释,确保它在每一步都正常工作。添加更多printf()
语句,并在需要时再次运行。
祝你好运!
答案 2 :(得分:2)
有人能告诉我,我为分而治之做错了吗?
是:
int[][] a = divideAndConquer(topLeft);
int[][] b = divideAndConquer(topRight);
int[][] c = divideAndConquer(bottomLeft);
int[][] d = divideAndConquer(bottomRight);
int[][] c11 = addMatrix(classical(a,a),classical(b,c));
int[][] c12 = addMatrix(classical(a,b),classical(b,d));
int[][] c21 = addMatrix(classical(c,a),classical(d,c));
int[][] c22 = addMatrix(classical(c,b),classical(d,d));
您将在此处执行额外的乘法步骤:您不应同时调用divideAndConquer()
和classical()
。
你实际做的是:
C11 = (A11^2)⋅(B11^2) + (A12^2)⋅(B21^2)
C12 = (A11^2)⋅(B12^2) + (A12^2)⋅(B22^2)
C21 = (A21^2)⋅(B11^2) + (A22^2)⋅(B21^2)
C22 = (A21^2)⋅(B12^2) + (A22^2)⋅(B22^2)
这是不正确的。
首先,删除divideAndConquer()
次来电,然后用topLeft / topRight / etc替换/ b / c / d。
看看它是否能给你正确的结果。
您的divideAndConquer()
方法需要一对输入参数,因此您可以使用A * B.完成后,请拨打classical()
的电话,然后使用divideAndConquer()
。 (或将它们保存为长度不是2的倍数的矩阵。)
答案 3 :(得分:1)
您可能会发现Strassen's algorithm上的Wiki文章很有帮助。