Java 如何从值表中估计时间复杂度?

Java 如何从值表中估计时间复杂度?,java,time,complexity-theory,Java,Time,Complexity Theory,我知道我的朴素矩阵乘法算法的时间复杂度为^3。。。 但我如何通过我的价值表来证明这一点呢?Size是矩阵的行或列长度。因此,对于完整的矩阵大小 尺寸=100垫。穆特。运行时间:0.0199秒 尺寸=200垫。穆特。运行时间:0.0443秒 尺寸=300垫。穆特。运行时间:0.0984秒 尺寸=400垫。穆特。运行时间:0.2704秒 尺寸=800垫。穆特。运行时间:6.393秒 这就像查看一个值表并估计函数的图形。。。这些数字和N^3之间一定有某种关系。我怎么理解它呢 我在下面提供了我的算法。通

我知道我的朴素矩阵乘法算法的时间复杂度为^3。。。 但我如何通过我的价值表来证明这一点呢?Size是矩阵的行或列长度。因此,对于完整的矩阵大小

尺寸=100垫。穆特。运行时间:0.0199秒

尺寸=200垫。穆特。运行时间:0.0443秒

尺寸=300垫。穆特。运行时间:0.0984秒

尺寸=400垫。穆特。运行时间:0.2704秒

尺寸=800垫。穆特。运行时间:6.393秒

这就像查看一个值表并估计函数的图形。。。这些数字和N^3之间一定有某种关系。我怎么理解它呢

我在下面提供了我的算法。通过计算循环数,我已经知道它在^3上。我如何将其与上面的价值表联系起来

 /**
* This function multiplies two matrices and returns the product matrix.
* 
* @param mat1
*           The first multiplier matrix.
* @param mat2
*           The second multiplicand matrix.
* @return The product matrix.
*/
private static double[][] MatMult(double[][] mat1, double[][] mat2) {
  int m1RowLimit = mat1.length, m2ColumnLimit = mat2[0].length, innerLimit = mat1[0].length;
  if ((mat1[0].length != mat2.length))
     return null;
  int m1Row = 0, m1Column = 0, m2Row = 0, m2Column = 0;
  double[][] mat3 = new double[m1RowLimit][m2ColumnLimit];
  while (m1Row < m1RowLimit) {
     m2Column = 0;
     while (m2Column < m2ColumnLimit) {
        double value = 0;
        m1Column = 0;
        m2Row = 0;
        while (m1Column < innerLimit) {
           value += mat1[m1Row][m1Column] * mat2[m2Row][m2Column];
           m1Column++;
           m2Row++;
        }
        mat3[m1Row][m2Column] = value;
        m2Column++;
     }
     m1Row++;
  }
  return mat3;
}
方法论 可以所以你想证明你的算法的时间复杂度在^3。我理解为什么你会看一个程序运行计算所需的时间,但这个数据不可靠。我们要做的是,我们应用一种奇怪的形式来从算法的其他方面抽象出来,留下我们的度量

度量 我们将使用度量来度量您的算法。它是发生最多或承载最多处理重量的操作。在这种情况下,它是这一行:

value += mat1[m1Row][m1Column] * mat2[m2Row][m2Column];
推导递推关系 据我所知,下一步是从算法中推导出一个递归关系。也就是说,描述您的算法如何基于其过去的功能运行。让我们看看您的程序是如何运行的

正如您所解释的,您已经查看了三个while循环,并确定程序在^3上是有序的。不幸的是,这不是数学。这似乎是经常发生的事情。首先,让我们看一些数值例子

当m1RowLimit=4、m2ColumnLimit=4、innerLimit=4时,我们的度量将运行4*4*4=4^3次

当m1RowLimit=5、m2ColumnLimit=5、innerLimit=5时,我们的度量将运行5*5*5=5^3次

那么我们如何用递推关系来表示呢?好的,使用一些基础数学,我们得到:

T(n) = T(n-1) + 3(n-1)^2 + 3(n-1) + 1 for all n >= 1
T(1) = 1
用正代换和数学归纳法求解递推关系 现在,这是我们使用一些。我们首先要做的是,感受一下这种关系,这也测试了它的准确性

T(2) = T(1) + 3(1^2) + 3(1) + 1 = 1 + 3 + 3 + 1 = 8.
T(3) = T(2) + 3(2^2) + 3(2) + 1 = 8 + 12 + 6 + 1 = 27
T(4) = T(3) + 3(3^2) + 3(3) + 1 = 27 + 27 + 9 + 1 = 64
现在,我们假设Tn=n^3。让我们测试一下基本情况:

T(1) = 1^3 = 1. // Correct!
现在,我们使用数学归纳法对其进行测试,以进行下一步。算法每次增加1,因此下一步是:Tn+1。那么我们需要证明什么呢?我们需要证明,通过在一边将n增加1,在另一边对n的影响是相等的。如果对所有n+1都是真的,那么对n+1+1也是真的,依此类推。这意味着,我们的目标是证明:

T(n + 1) = (n + 1)^3

T(n + 1) = T(n - 1 + 1) + 3(n + 1 - 1)^2 + 3(n + 1 - 1) + 1
         = T(n) + 3(n)^2 + 3(n) + 1
Assume T(n) = n^3
T(n + 1) = n^3 + 3(n)^2 + 3(n) + 1
T(n + 1) = (n+1)^3 // Factorize the function.
至此,您已经证明了算法的运行时复杂性为^3。

方法论 可以所以你想证明你的算法的时间复杂度在^3。我理解为什么你会看一个程序运行计算所需的时间,但这个数据不可靠。我们要做的是,我们应用一种奇怪的形式来从算法的其他方面抽象出来,留下我们的度量

度量 我们将使用度量来度量您的算法。它是发生最多或承载最多处理重量的操作。在这种情况下,它是这一行:

value += mat1[m1Row][m1Column] * mat2[m2Row][m2Column];
推导递推关系 据我所知,下一步是从算法中推导出一个递归关系。也就是说,描述您的算法如何基于其过去的功能运行。让我们看看您的程序是如何运行的

正如您所解释的,您已经查看了三个while循环,并确定程序在^3上是有序的。不幸的是,这不是数学。这似乎是经常发生的事情。首先,让我们看一些数值例子

当m1RowLimit=4、m2ColumnLimit=4、innerLimit=4时,我们的度量将运行4*4*4=4^3次

当m1RowLimit=5、m2ColumnLimit=5、innerLimit=5时,我们的度量将运行5*5*5=5^3次

那么我们如何用递推关系来表示呢?好的,使用一些基础数学,我们得到:

T(n) = T(n-1) + 3(n-1)^2 + 3(n-1) + 1 for all n >= 1
T(1) = 1
用正代换和数学归纳法求解递推关系 现在,这是我们使用一些。我们首先要做的是,感受一下这种关系,这也测试了它的准确性

T(2) = T(1) + 3(1^2) + 3(1) + 1 = 1 + 3 + 3 + 1 = 8.
T(3) = T(2) + 3(2^2) + 3(2) + 1 = 8 + 12 + 6 + 1 = 27
T(4) = T(3) + 3(3^2) + 3(3) + 1 = 27 + 27 + 9 + 1 = 64
现在,我们假设Tn=n^3。让我们测试一下基本情况:

T(1) = 1^3 = 1. // Correct!
现在,我们使用数学归纳法对其进行测试,以进行下一步。算法每次增加1,因此下一步是:Tn+1。那么我们需要证明什么呢?我们需要证明,通过在一边将n增加1,在另一边对n的影响是相等的。如果这是真的 ll n+1,那么n+1+1也是如此,依此类推。这意味着,我们的目标是证明:

T(n + 1) = (n + 1)^3

T(n + 1) = T(n - 1 + 1) + 3(n + 1 - 1)^2 + 3(n + 1 - 1) + 1
         = T(n) + 3(n)^2 + 3(n) + 1
Assume T(n) = n^3
T(n + 1) = n^3 + 3(n)^2 + 3(n) + 1
T(n + 1) = (n+1)^3 // Factorize the function.

至此,您已经证明了算法的运行时复杂度为^3。

第一个响应介绍了如何很好地证明算法的时间复杂度

然而,您似乎在问如何将基准测试的实验结果与时间复杂性联系起来,而不是如何证明时间复杂性

那么,我们如何解释实验数据呢?首先,您可以简单地在y轴上绘制数据运行时,在x轴上绘制大小。有了足够的数据点,这可以给你一些关于算法行为的提示

由于您已经知道算法的预期时间复杂度,因此可以绘制一条最佳拟合曲线,即一条最适合您的数据的n^3形状的线。如果您的数据与行匹配得相当好,那么您可能是正确的。如果不是的话,你可能犯了一些错误,或者你的实验结果不匹配是由于你没有考虑到的因素

要确定最佳拟合n^3线的方程,只需将计算出的时间复杂度表示为一个方程,并猜测未知数的值,直到找到一个拟合的方程。因此,对于n^3,您将有:

t = a*n^3 + b*n^2 + c*n + d
找出a、b、c和d的值,这些值构成最适合您的数据的方程。如果这种合身感还不够好,那你就有问题了


对于更严格的技术,您必须询问更精通统计学的人。我相信你想要计算的值是a.k.a.R^2,基本上告诉你预期结果和实际结果之间的差异。然而,就其本身而言,这个值并不能证明什么。验证变量之间假设关系的问题称为;wikipedia的文章提供了更多的信息,说明了如果R^2不足以满足您的需要,如何进一步解决此问题。

第一个响应包括如何很好地证明算法的时间复杂性

然而,您似乎在问如何将基准测试的实验结果与时间复杂性联系起来,而不是如何证明时间复杂性

那么,我们如何解释实验数据呢?首先,您可以简单地在y轴上绘制数据运行时,在x轴上绘制大小。有了足够的数据点,这可以给你一些关于算法行为的提示

由于您已经知道算法的预期时间复杂度,因此可以绘制一条最佳拟合曲线,即一条最适合您的数据的n^3形状的线。如果您的数据与行匹配得相当好,那么您可能是正确的。如果不是的话,你可能犯了一些错误,或者你的实验结果不匹配是由于你没有考虑到的因素

要确定最佳拟合n^3线的方程,只需将计算出的时间复杂度表示为一个方程,并猜测未知数的值,直到找到一个拟合的方程。因此,对于n^3,您将有:

t = a*n^3 + b*n^2 + c*n + d
找出a、b、c和d的值,这些值构成最适合您的数据的方程。如果这种合身感还不够好,那你就有问题了


对于更严格的技术,您必须询问更精通统计学的人。我相信你想要计算的值是a.k.a.R^2,基本上告诉你预期结果和实际结果之间的差异。然而,就其本身而言,这个值并不能证明什么。验证变量之间假设关系的问题称为;wikipedia的文章提供了更多的信息,说明如果R^2不足以满足您的需要,如何进一步进行此操作。

根据经验,您可以使用相邻的三次多项式趋势线绘制数据,以供参考

CSV数据:

100, 0.0199 200, 0.0443 300, 0.0984 400, 0.2704 800, 6.393
根据经验,您可以用相邻的三次多项式趋势线绘制数据以供参考

CSV数据:

100, 0.0199 200, 0.0443 300, 0.0984 400, 0.2704 800, 6.393
在数学意义上,观察时间复杂度通常需要观察算法并想象它如何在非常大的输入下工作。如果你能发布算法,我相信我们可以帮助你。你的数据基于很多很多变量。内存空间、处理器速度、电缆上的物理电阻等。这些都会影响程序的输出。因此,使用较大的值。它掩盖了这些影响。你可以用数学归纳法或逆向代换法来证明你的复杂性。那么,你不能看我上面提供的数值表,通过归纳法得出一个关系吗?如果有帮助的话,我会发布算法。我已经知道它在^3上了。是的,但你想证明它在^3上。你要做的是选择一个度量,然后使用它。你实际上并没有使用时间单位。从数学意义上看,观察时间复杂度通常需要观察算法并想象它是如何工作的

对于非常大的输入。如果你能发布算法,我相信我们可以帮助你。你的数据基于很多很多变量。内存空间、处理器速度、电缆上的物理电阻等。这些都会影响程序的输出。因此,使用较大的值。它掩盖了这些影响。你可以用数学归纳法或逆向代换法来证明你的复杂性。那么,你不能看我上面提供的数值表,通过归纳法得出一个关系吗?如果有帮助的话,我会发布算法。我已经知道它在^3上了。是的,但你想证明它在^3上。你要做的是选择一个度量,然后使用它。你实际上并没有使用时间单位。它们的波动幅度从远到远,以从中获得模式。哇。信息量很大!我们能用这个来计算θ和ω吗?那。。我必须承认我不确定。通常我只是计算一下bigO,然后就完蛋了。信息量很大!我们能用这个来计算θ和ω吗?那。。我必须承认我不确定。通常我只是计算bigO,然后用它来完成。微积分是一种近似值。OP需要一个证明,因此我使用了递归关系和数学归纳法。但是我怎样才能通过我的值表来证明呢?微积分是一种近似值。OP需要一个证明,因此我使用了递归关系和数学归纳法。但我如何通过我的价值表来证明这一点呢?比我的答案要简单一些!通过这张图,你能说明在x的一系列值之间,它倾向于表现为一个三次函数吗?主观上,是的,在这个意义上,你可以调整趋势线的顺序,以查看拟合如何变化。我的意思是补充你的&古达特的更具决定性的分析,在我创建这个答案的时候,我投了赞成票。我明白了。所以,如果你要写一篇关于某个算法的论文,你可以从你的答案开始,然后是古达特的,最后是我的,为你的算法的复杂性做一个有力的证明?是的,电子表格的趋势线功能找到了古达特的。我们也可以做相反的事情:根据经验验证算法的特定实现是否满足已知的复杂性要求。或者在这种情况下可以很好地工作。比我的答案要简单一些!通过这张图,你能说明在x的一系列值之间,它倾向于表现为一个三次函数吗?主观上,是的,在这个意义上,你可以调整趋势线的顺序,以查看拟合如何变化。我的意思是补充你的&古达特的更具决定性的分析,在我创建这个答案的时候,我投了赞成票。我明白了。所以,如果你要写一篇关于某个算法的论文,你可以从你的答案开始,然后是古达特的,最后是我的,为你的算法的复杂性做一个有力的证明?是的,电子表格的趋势线功能找到了古达特的。我们也可以做相反的事情:根据经验验证算法的特定实现是否满足已知的复杂性要求。在这种情况下,您可以选择或很好地配合。