查找指数算法的时间复杂度

Posted

技术标签:

【中文标题】查找指数算法的时间复杂度【英文标题】:Finding the temporal complexity of an exponential algorithm 【发布时间】:2017-04-12 14:41:33 【问题描述】:

问题:找到切割长度为 n 的杆的最佳方法。 每个切割都是整数长度。 假设每根长度为 i 的棒都有一个价格 p(i)。 给定:长度为 n 的棒,以及价格列表 p,它提供了 0 到 n 之间的每个可能整数长度的价格。

找到最佳的削减集以获得最高价格。 可以使用任意数量的切割,从 0 到 n-1。 削减费用是免费的。

接下来我针对这个问题提出了一个简单的算法。

CUT-ROD(p,n)
if(n == 0)
    return 0
q = -infinity
for i = 1 to n
    q = max(q, p[i]+CUT-ROD(p,n-1))
return q

我怎样才能证明这个算法是指数的?一步步。 我可以看到它是指数级的。但是,我无法证明。

【问题讨论】:

递归调用不应该是CUT-ROD(p, n - i)吗?否则,切口的总长度可能会超过杆的长度。 如所写,可以通过归纳证明CUT-ROD(p, n) 产生n!递归调用总数(n>=1)。 好的,保罗。但我们怎么能做到呢?你能帮我吗? 【参考方案1】:

为了清楚起见,我们将代码翻译成 C++:

int prices[n];
int cut-rod(int n) 
  if(n == 0) 
    return 0;
  
  q = -1;
  res = cut-rod(n-1);
  for(int i = 0; i < n; i++) 
    q = max(q, prices[i] + res);
  
  return q;

注意:我们正在缓存结果of cut-rod(n-1),以避免不必要地增加算法的复杂性。在这里,我们可以看到cut-rod(n) 调用cut-rod(n-1),它调用cut-rod(n-2) 等等,直到cut-rod(0)。对于cut-rod(n),我们看到该函数迭代数组n 次。因此算法的时间复杂度等于O(n + (n-1) + (n-2) + (n-3)...1) = O(n(n+1)/2) 约等于O((n^2)/2)

编辑: 如果我们使用与问题中的算法完全相同的算法,则其时间复杂度为 O(n!),因为 cut-rod(n) 调用 cut-rod(n-1) n 次。 cut-rod(n-1) 调用 cut-rod(n-2) n-1 次,以此类推。因此时间复杂度等于 O(n*(n-1)*(n-2)...1) = O(n!)。

【讨论】:

但是,根据您的分析,该算法的运行时间与输入长度成二次成比例增长。然而,在 Cormen 的书中,他们说算法是指数的。 如果你模拟 n=4 的算法,你会看到它执行了 16 次递归计算。也就是说,确实是2^n 好的。您的算法不执行 16 次递归调用。但是我在本主题中介绍的算法可以。我的问题与该算法有关。我想证明它进行了 2^n 次递归调用。我尝试了归纳法,但未能达到预期效果。 原始算法在 for 循环中的每次迭代都不必要地调用 cut-rod。 确实...但是,我需要证明它具有指数复杂性。我现在已经知道了,但我需要证明这一点。【参考方案2】:

我不确定这是否算作一步一步的解决方案,但可以通过归纳/替换轻松显示。假设所有 i

【讨论】:

以上是关于查找指数算法的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

二分查找,教你如何提高搜索效率

快速幂算法

二分查找算法的递归循环实现及其缺陷

编写一个算法来查找数组中出现频率最高的元素。给出算法的时间复杂度

该算法查找所有组合的时间复杂度是多少?

01. 算法的时间复杂度