【问题标题】:matrix multiplication algorithm time complexity矩阵乘法算法时间复杂度
【发布时间】:2012-01-22 17:21:03
【问题描述】:

我想出了这个矩阵乘法算法。我在某处读到矩阵乘法的时间复杂度为 o(n^2)。 但我认为我的这个算法会给出 o(n^3)。 我不知道如何计算嵌套循环的时间复杂度。所以请纠正我。

for i=1 to n
   for j=1 to n    
     c[i][j]=0
     for k=1 to n
         c[i][j] = c[i][j]+a[i][k]*b[k][j]

【问题讨论】:

  • b[i][k] 看起来不对。我怀疑您想要在最后一行的 RHS 上使用类似 c[i][j] + a[i][k] * b[k][j] 的内容。
  • 不正确。这里 c[i][j] 是结果矩阵
  • 好吧,在这种情况下,你肯定不是在做矩阵乘法!请注意,对于给定的i,您在c[i][j] 中为每个j 计算相同的结果,因此在您的输出矩阵c 中,所有列都是相同的。您需要在最后一行将b[i][k] 替换为b[k][j]

标签: algorithm time-complexity matrix-multiplication


【解决方案1】:

我最近在大学作业中遇到了一个矩阵乘法问题,这就是我在 O(n^2) 中解决它的方法。

import java.util.Scanner;

public class q10 {
public static int[][] multiplyMatrices(int[][] A, int[][] B) {
    int ra = A.length; // rows in A
    int ca = A[0].length; // columns in A

    int rb = B.length; // rows in B
    int cb = B[0].length; // columns in B

    // if columns of A is not equal to rows of B, then the two matrices,
    // cannot be multiplied.
    if (ca != rb) {
        System.out.println("Incorrect order, multiplication cannot be performed");
        return A;
    } else {
        // AB is the product of A and B, and it will have rows,
        // equal to rown in A and columns equal to columns in B
        int[][] AB = new int[ra][cb];

        int k = 0; // column number of matrix B, while multiplying

        int entry; // = Aij, value in ith row and at jth index

        for (int i = 0; i < A.length; i++) {
            entry = 0;
            k = 0;

            for (int j = 0; j < A[i].length; j++) {
                // to evaluate a new Aij, clear the earlier entry
                if (j == 0) {
                    entry = 0;
                }

                int currA = A[i][j]; // number selected in matrix A
                int currB = B[j][k]; // number selected in matrix B

                entry += currA * currB; // adding to the current entry

                // if we are done with all the columns for this entry,
                // reset the loop for next one.
                if (j + 1 == ca) {
                    j = -1;
                    // put the evaluated value at its position
                    AB[i][k] = entry;

                    // increase the column number of matrix B as we are done with this one
                    k++;
                }

                // if this row is done break this loop,
                // move to next row.
                if (k == cb) {
                    j = A[i].length;
                }
            }
        }
        return AB;
    }

}

@SuppressWarnings({ "resource" })
public static void main(String[] args) {
    Scanner ip = new Scanner(System.in);

    System.out.println("Input order of first matrix (r x c):");
    int ra = ip.nextInt();
    int ca = ip.nextInt();

    System.out.println("Input order of second matrix (r x c):");
    int rb = ip.nextInt();
    int cb = ip.nextInt();

    int[][] A = new int[ra][ca];
    int[][] B = new int[rb][cb];

    System.out.println("Enter values in first matrix:");
    for (int i = 0; i < ra; i++) {
        for (int j = 0; j < ca; j++) {
            A[i][j] = ip.nextInt();
        }
    }

    System.out.println("Enter values in second matrix:");
    for (int i = 0; i < rb; i++) {
        for (int j = 0; j < cb; j++) {
            B[i][j] = ip.nextInt();
        }
    }

    int[][] AB = multiplyMatrices(A, B);

    System.out.println("The product of first and second matrix is:");
    for (int i = 0; i < AB.length; i++) {
        for (int j = 0; j < AB[i].length; j++) {
            System.out.print(AB[i][j] + " ");
        }
        System.out.println();
    }
}

}

【讨论】:

    【解决方案2】:

    我最近得到了矩阵乘法的O(n^2)算法,通过向量乘法很简单

    【讨论】:

    • 你确定是O(n^2)?特例是O(n^2)吗?
    • 不,它适用于所有情况。其实这个算法很复杂,但是数学很简单。
    • 你和任何人分享过吗?
    • 我相信你至少要分享一些关于这方面的见解
    【解决方案3】:

    将 m×n 矩阵乘以 n×p 矩阵的标准方法的复杂度为 O(mnp)。如果所有这些对你来说都是“n”,那就是 O(n^3),而不是 O(n^2)。编辑:在一般情况下它不会是 O(n^2) 。但是对于特定类型的矩阵,有更快的算法——如果你知道得更多,你可能会做得更好。

    【讨论】:

    • 这是错误的。一般情况下都有加速。
    • 施特拉森算法?当然。 OP 要求 O(n^2) ,这通常是不可能的。这就是我想要的。
    【解决方案4】:

    在矩阵乘法中,我们使用了 3 个 for 循环,因为每个 for 循环的执行都需要时间复杂度 O(n)。所以对于三个循环,它变成O(n^3)

    【讨论】:

      【解决方案5】:

      使用线性代数,存在比简单 O(n3) 实现更好复杂性的算法。 Solvay Strassen 算法通过将每个 2x2 子矩阵所需的乘法次数从 8 次减少到 7 次,实现了 O(n2.807) 的复杂度。

      已知最快的矩阵乘法算法是Coppersmith-Winograd算法,复杂度为O(n2.3737)。除非矩阵很大,否则这些算法不会导致计算时间的巨大差异。在实践中,使用并行算法进行矩阵乘法更容易、更快捷。

      【讨论】:

      • 根据Wikipedia,从 2014 年开始有一种矩阵乘法算法达到了 O(n^2.3729),而 Coppersmith-Winograd 算法在 2010 年之前是最快的。
      【解决方案6】:

      按照 cmets 中的说明进行更正后,您得到的简单算法是 O(n^3)。

      确实存在一些算法可以在一定程度上减少这种情况,但您不太可能找到 O(n^2) 的实现。我相信最有效实施的问题仍然悬而未决。

      有关更多信息,请参阅Matrix Multiplication 上的这篇维基百科文章。

      【讨论】:

      • 实际证明O(n^2)是不可能实现的。
      • @downhand 引用好吗?我以前没有遇到过这个结果。我想阅读证明。
      • @downhand 我知道这篇文章是近一年前的,但我很想看到证明。
      • 我能找到的最接近的是arxiv.org/abs/1204.1111的介绍
      • @ArunJoshla n 这是要相乘的(正方形)矩阵的大小。每个矩阵的大小为(n,n)。顺便说一句,你不能比 O(n^2) 做得更好,因为你至少必须读取两个矩阵中的每个数字才能将它们相乘。
      猜你喜欢
      • 2021-02-16
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      相关资源
      最近更新 更多