如何在矩阵中找到所有子方格的总和?

时间:2016-05-17 02:59:55

标签: java algorithm matlab matrix

我希望找到一个极大矩阵的所有子方形的总和,其中

{{1,2} 在2D矩阵中的{3,4}}将返回20.我使用java实现了这一点,但程序非常慢。有没有更快的方法,或其他更快的语言?

public class insaneMat
{
public static void main(String[] args)
{
    int[][] mat = new int[10000][10000];

    try
    {
        Scanner input = new Scanner (new File("file.in"));  
        int count = 0;
        for (int r = 0; r < mat.length; r++)
        {
            for (int c = 0; c <mat[r].length; c++)
            {
                mat[r][c] = input.nextInt();
                count++;
                System.out.println("Loaded num " + count);
            }
        }
    }
    catch(Exception e)
    {
        System.out.println("ERROR!");
    }

    int n = mat.length;
    int k;
    int sum = 0;
    for (k = 1; k < 10000; k++)
    {
        System.out.println("Calculating with subsquare of size " + k);
        for (int i=0; i<n-k+1; i++)
        {
            for (int j=0; j<n-k+1; j++)
            {
                for (int p=i; p<k+i; p++)
                    for (int q=j; q<k+j; q++)
                        sum += mat[p][q];
            }
        }
    }
    System.out.println("Number = " + sum);

}   

这在java中是有效的,除非它非常非常慢。该程序适用于2x2矩阵,如上所述,但每小时运行约30个子方块。无论我使用java还是使用其他语言,都可以用更快的方法完成吗? Matlab会有用吗?

2 个答案:

答案 0 :(得分:2)

解决这个问题的方法是解析分析每个元素[i,j]将属于大小为N的矩阵的子方数...调用此函数C(n,i ,J)。然后计算出所有i,j的C(n,i,j)*元素[i,j]之和。

计算的复杂性将是O(N^2) ...与您当前的算法O(N^5)进行比较(我怀疑算法可能是错误的...如果您想要所有子方格从1到N-1 ......真正的复杂性是O(N!)。)

无论如何,你需要的只是一些数学: - )

警告,这些金额会变得非常大。

答案 1 :(得分:0)

你所拥有的是O(n ^ 5)算法,那些往往非常慢。 Matlab将提供帮助,因为它针对Matrix操作进行了超级优化。但是,要获得最大速度,您需要编写矢量化代码,这意味着您的两个内部循环应该被压缩成类似这样的总和(sum(M [i:k + i,j:k + j]))你没有为Matlab赚很多钱,现在numpy的速度非常快。

Stephen C提到的另一个观察是,你一遍又一遍地计算同样的事情。例如,子矩阵M [2:3,3:4]的元素之和对于子矩阵M [1:3,3:4]和M [1:5,1:8]等也很有用。所以你需要保持选中这些中间结果。查看Memoization和Dynamic Programming以了解确切的技术及其背后的理论。

最简单的自动化方式是通过记忆。 https://en.wikipedia.org/wiki/Memoization这实际上是将内部循环变为单独的方法。这种方法记录了它们被调用的参数和接收的结果。因此,下次他们使用相同的参数调用时,他们可以在不进行实际计算的情况下查找结果。许多函数式语言都有一个库,可以将常规函数转换为memoized函数。看起来现在可以在Java 8中使用新功能扩展https://dzone.com/articles/java-8-automatic-memoization