【问题标题】:Matrix returning wrong values in Java矩阵在 Java 中返回错误值
【发布时间】:2014-02-04 20:21:52
【问题描述】:

我试图在 java 中创建一个方法,使用整数作为参数将两个矩阵相乘,以告诉我在矩阵中工作的位置,并递归地将矩阵“切片”为更小的部分,然后使用所谓的 Divide 从这里将它们相乘和征服(这是一个学校的任务,尽管它确实是一个很难将两个矩阵相乘的方法!)。不出所料,在我的代码完成运行后,矩阵并没有显示我所期望的。在我的主要方法中,我有 3 个大小为 n*n(n=2、4、8、16...)的矩阵,所以它们是正方形。我将矩阵 A 和 B 乘以矩阵 D。我的主要方法是在矩阵类中。这就是我的代码现在的样子:

public class indexMult {
matrix mat = new matrix();


public void calc(int Ay, int Ax, int By, int Bx, int Dy, int Dx, int size){

    System.out.println(Ay +" "+ Ax +" "+ By +" "+ Bx +" "+ Dy +" "+ Dx +" "+ size);
    if(size==2){

        mat.D[Dy][Dx] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy+1][Dx] = mat.A[Ay+1][Ax] * mat.B[By][Bx] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy][Dx+1] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx+1];
        mat.D[Dy+1][Dx+1] = mat.A[Ay+1][Ax] * mat.B[By][Bx+1] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];


    }else{

        size = size/2;  
        for(int i=0; i<size; i++){
            for(int j=0; j<size; j++){

                calc(i, j, i, j, i, j, size);
                calc(i, size+j, i, size+j, i, size+j, size);
                calc(size+i, j, size+i, j, size+i, j, size);
                calc(size+i, size+j, size+i, size+j, size+i, size+j, size);

            }   
        }           
    }
}               

}

这个方法直接改变矩阵D。为了更容易,我在矩阵 A 和 B 的每个位置都使用了 2。我制定代码的方式也存在问题,因为结果不正确 - 但我还没有遇到这个问题。此时我的问题是,无论我将 n 设置为什么,D 都只能填充 5x5。如果我使用 n 作为 4 或 2,我会得到一个数组索引越界异常(因为我显然试图用 5x5 数据填充一个 4x4 矩阵)。但这不是我想要我的代码做的!我的代码背后的想法是将 n*n(int 大小)中的 n 除以 2,然后从这里对矩阵的每个四分之一进行递归调用,直到大小为 2x2,我可以解决该部分。我可能缺少一块将四分之一矩阵加在一起,但我还没有那么远 - 我在填充整个矩阵时遇到了麻烦,因为它在 5x5 之后停止。有没有人能够发现错误??

编辑:

在下面的答案的帮助下,以及我自己的一些修正,这种变化似乎有效 - 不仅适用于我的问题,而且可以实际计算我需要的东西! :))

calc(Ay, Ax, By, Bx, Dy, Dx, size);
        calc(Ay, Ax+size, By+size, Bx, Dy, Dx, size);

        calc(Ay, Ax, By, Bx+size, Dy, Dx+size, size);
        calc(Ay, Ax+size, By+size, Bx+size, Dy, Dx+size, size);

        calc(Ay+size, Ax, By, Bx, Dy+size, Dx, size);
        calc(Ay+size, Ax+size, By+size, Bx, Dy+size, Dx, size);

        calc(Ay+size, Ax, By, Bx+size, Dy+size, Dx+size, size);
        calc(Ay+size, Ax+size, By+size, Bx+size, Dy+size, Dx+size, size);

【问题讨论】:

  • 矩阵乘法必须是有史以来最不恰当的递归用法。我感觉到你的痛苦。
  • 我相信你不需要最后两个 for 循环。可能没有它们也能正常工作。
  • 哈哈,谢谢 :P ... 不需要他们??替换为 0? - 替换为 0 后,它停在 4x4 而不是 5x5.. 嗯,我不记得为什么要实现它们了.. 但它仍然没有填满整个空间,它停在 4x4。 2x2 也不例外!略有改善! :D
  • @ajb 递归和继承对于教授来说似乎很难找到有效的例子。我无法告诉你我见过多少不满足“is-a”关系的继承示例。

标签: java recursion matrix multiplication


【解决方案1】:

也许这些方面的东西会起作用:

public class indexMult {
matrix mat = new matrix();


public void calc(int Ay, int Ax, int By, int Bx, int Dy, int Dx, int size){

    System.out.println(Ay +" "+ Ax +" "+ By +" "+ Bx +" "+ Dy +" "+ Dx +" "+ size);
    if(size==2){

        mat.D[Dy][Dx] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy+1][Dx] = mat.A[Ay+1][Ax] * mat.B[By][Bx] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];
        mat.D[Dy][Dx+1] = mat.A[Ay][Ax] * mat.B[By][Bx] + mat.A[Ay][Ax+1] * mat.B[By+1][Bx+1];
        mat.D[Dy+1][Dx+1] = mat.A[Ay+1][Ax] * mat.B[By][Bx+1] + mat.A[Ay+1][Ax+1] * mat.B[By+1][Bx];


    }else{

        size = size/2;  
        calc(Ay, Ax, By, Bx, Dy, Dx, size);
        calc(Ay, Ax+size, By, Bx+size, Dy, Dx+size, size);
        calc(Ay+size, Ax, By+size, Bx, Dy+size, Dx, size);
        calc(Ay+size, Ax+size, By+size, Bx+size, Dy+size, Dx+size, size);
    }
}

我刚刚将循环替换为递归。

【讨论】:

  • 嗯,是的,这至少给出了一个完整的矩阵:D 非常感谢! :)) 你知道为什么我的停了吗?有点好奇发生了什么,在发布之前已经研究了一段时间。
  • 嗯。这对于非 2 的幂也可能不正确。这要复杂得多。我认为这不是一个要求。如果您也必须这样做,则还应涵盖维度为 1 的特殊情况。
  • 对不起,什么? n*n 的大小只有 2^0, 2^1, 2^2...2^n。超出这个范围会更加困难,因此我们可以创建代码以仅使用 2 的幂。
  • 我想我成功了!使用我们从教授那里得到的公式表,以及你的快速修复,我想我找到了解决这个问题的有效方法! :D 非常感谢,这项任务花费了我 2 个周末 + 放学后无休止的时间!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2021-05-11
  • 1970-01-01
  • 2017-07-18
相关资源
最近更新 更多