使用两个参数确定算法的运行时间

时间:2016-01-13 14:46:12

标签: time-complexity complexity-theory

我已经实现了一种算法,该算法使用另外两种算法来计算图中的最短路径:Dijkstra和Bellman-Ford。基于这些算法的时间复杂度,我可以计算出我的实现的运行时间,这很容易给出代码。

现在,我想通过实验验证我的计算方法。具体来说,我想将运行时间绘制为输入大​​小的函数(我遵循描述的方法here)。问题是我有两个参数 - 边数和顶点数。

我试图修复一个参数并更改另一个参数,但这种方法会产生两个图 - 一个用于不同数量的边,另一个用于不同数量的顶点。

这引出了我的问题 - 如何根据两个图来确定增长的顺序?通常,如何通过实验确定具有多个参数的算法的运行时复杂度?

3 个答案:

答案 0 :(得分:2)

一般来说非常困难。

通过实验测量单变量情况下的运行时间的常用方法是,插入一个计数器,当您的数据结构执行基本(推定O(1))操作时递增计数器,然后获取许多不同输入大小的数据,并将其绘制在log-log图上。也就是说,log Tlog N。如果运行时间的格式为n^k,则应看到斜率k的直线,或接近此值的内容。如果运行时间类似于T(n) = n^{k log n}或其他什么,那么你应该看到一个抛物线。如果T中的n呈指数增长,您仍应看到指数增长。

您只能希望在执行此操作时获取有关最高订单字词的信息 - 从n变大后影响越来越小的意义上的低阶条款被滤除。

在两个变量的情况下,你可以尝试做一个类似的方法 - 基本上,采取三维数据,做一个log-log-log图,并尝试将平面拟合到那个。

然而,只有在大多数政权中只有一个主导词占主导地位时,这才会真正起作用。

假设我的实际功能是T(n, m) = n^4 + n^3 * m^3 + m^4

m = O(1)时,T(n) = O(n^4)。 当n = O(1)时,T(n) = O(m^4)。 当n = m,然后是T(n) = O(n^6)

在每个制度中,"切片"沿着可能nm值的平面,不同的一个术语是主导词。

因此,无法通过采用固定m的某些点和某些具有固定n的点来确定该函数。如果你这样做,你将无法得到n = m的正确答案 - 你将无法发现"中间"这样的主导词。

我建议,当你有很多变量/复杂的数据结构时,预测渐近增长的最好方法是使用铅笔和纸,并进行传统的算法分析。或者可能是混合方法。尝试将效率问题分解为不同的部分 - 如果你可以将问题分成几个不同功能的总和或产品,也许你可以抽象地确定其中一些,有些你可以通过实验估算。

答案 1 :(得分:1)

幸运的是,两个输入参数仍然很容易在三维散点图中可视化(第三维是测量的运行时间),您可以检查它是否看起来像一个平面(以log-log-log标度)或是否是弯曲。测量中自然的随机变化也起到了作用。

在Matlab中,我通常计算这样的双变量函数的最小二乘解(只是水平地连接xy的不同幂和组合,.*是一个元素 - 明智的产品):

x = log(parameter_x);
y = log(parameter_y);

% Find a least-squares fit
p = [x.^2, x.*y, y.^2, x, y, ones(length(x),1)] \ log(time)

然后,这可用于估计较大问题实例的运行时间,理想情况下,这些实例将通过实验确认拟合模型的工作原理。

这种方法也适用于更高的维度,但生成起来很乏味,也许有一种更通用的方法来实现这一点,这只是我缺乏知识的解决方法。

答案 2 :(得分:0)

我打算写下自己的解释,但它不会比this更好。