algorithm - 如何计算特定函数将在递归中执行的次数?

标签 algorithm recursion analysis

本题引用以下代码:

cost = [[1, 10, 75, 92],
         [-1, 0, 35, 50],
         [-1, -1, 0, 80],
         [-1, -1, -1, 0]]

def min_cost(source, destination):
   if s==d or s == d-1:
       return cost[s][d]
    mc = cost[s][d]
    for i in range(s+1, d):
        tmp = min_cost(s, i) + min_cost(i, d)
    if tmp < mc:
        mc = tmp
return mc

当我试运行时,我看到 min_cost(1,3) 被执行了两次。我在一本书中读到,作者提到如果中间有 10 个站,那么 min_cost(1, 3) 将运行 144 次。

我们如何在不实际进行试运行的情况下计算出这些数字?我知道使用递归方程我们可以计算出函数所用的时间,但是我们怎么能说特定函数将执行这么多次呢?

最佳答案

虽然我知道您不希望试运行只是计算调用次数,但我还是想先试一下,看看发生了什么。所以,这里是:

def min_cost(s, d):
    global count
    count += 1
    if s==d or s == d-1:
        return cost[s][d]
    mc = cost[s][d]
    for i in range(s+1, d):
        tmp = min_cost(s, i) + min_cost(i, d)
    if tmp < mc:
        mc = tmp
    return mc

for n in range (2, 8):
    cost = [[0 for i in range (n)] for j in range (n)]
    count = 0
    min_cost(0, n-1)
    print (str (n) + ': ' + str (count))

输出是:

2: 1
3: 3
4: 9
5: 27
6: 81
7: 243

因此,我们看到 d-s=k 的调用次数是 3 的 (k-1) 次方。 知道我们必须证明什么有时会大大简化寻找证据的过程。


现在,证明本身。 它将是 proof by induction . 首先,请注意 min_cost(s, d) 的调用次数仅取决于 d-s 的值,而不取决于 s 的各个值code> 和 d

基础是,对于 d-s=1,我们接到一个电话。 对于 d-s>1,我们进行一次调用,并从中进行以下调用:

min_cost(s, s+1) and min_cost(s+1, d)
min_cost(s, s+2) and min_cost(s+2, d)
...
min_cost(s, d-1) and min_cost(d-1, d)

因此,对于 d-s=k,调用次数 f(k) 为:

f(k) = 1 +
       f(1) + f(k-1) +
       f(2) + f(k-2) +
       ... +
       f(k-1) + f(1)
     = 2 * (f(1) + f(2) + ... + f(k-1))

如果根据归纳假设,我们已经证明对于所有 v < k,f(v) = 3v,则 f(k) 为:
1 + 2 * (31 + 32 + ... + 3k-1),即trivially 3k,完成我们的证明。


最后,请注意,虽然所提出的算法是指数算法,但潜在的问题可以在多项式时间内解决,最简单的是 O((d-s)^2) 通过记住我们已经完成所有工作的调用。

关于algorithm - 如何计算特定函数将在递归中执行的次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50667744/

相关文章:

r - 我有时间序列数据,如何为变量做月度报告和平均值? (使用 R)

algorithm - 是否多个点组成一个圆?

algorithm - 用于时间和产品预测的序列挖掘

algorithm - 为什么我们说 map-reduce 比传统方法更好地解决了 "Paper reference"问题?

C 编程 - 使用递归求和

r - 在 ggplot 或点阵中使用 Surv 对象

algorithm - 二进制计数器摊销分析

python - 从两个列表中排序分布的夫妇

loops - 将递归过程转变为迭代过程 - SICP 练习 1.16

java - 在递归函数中使用 Scanner 类