这个问题参考了打击代码:
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)被执行了2次。我读了一本书,作者提到如果我们之间有10个电台,那么min_cost(1,3)会运行144次。
如何在不实际干运的情况下找出这些数字。我知道使用递归方程式我们可以计算出函数所用的时间,但是怎么能说这个特定的函数会执行很多次呢?
答案 0 :(得分:11)
虽然我知道你不想让干跑只计算电话,但我还是想先做,只是为了看看发生了什么。所以,这里是:
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的调用次数是(k-1)的幂的3。 了解我们必须证明的内容有时会大大简化查找证据。
现在,来证明本身。
它将是proof by induction。
首先,请注意min_cost(s, d)
的来电次数仅取决于d-s
的值,而不取决于s
和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))
如果通过归纳假设,我们已经证明f(v)= 3 v 对于所有v&lt; k,那么f(k)是:
1 + 2 *(3 1 + 3 2 + ... + 3 k-1 ),这是trivially 3 k ,完成我们的证明。
最后,请注意,虽然所提出的算法是指数的,但是基本问题可以在多项式时间内解决,最简单的是在O((ds)^ 2)中通过记忆我们已经完成所有工作的调用来解决。 / p>
答案 1 :(得分:3)
当使用递归时,有几个选项可以计算该数量。最简单的方法是在递归方法中添加另一个变量,每次递归时都会增加该变量,并且在返回它的最后一个语句中,它不会递增,但只返回最后一个量,这将递归&#39;返回&# 39;上层要求。
伪代码中的示例:
function recursionfunction(x, y, recursioncount) {
if(expressionIsFalse) {
recursionfunction(x, y, recursioncount+1);
} else {
return recursioncount;
}
}
print recursionfunction('','', 0);
另一种工作方式是通过引用,指针或全局变量(取决于编程语言)分配变量并递增该计数器。
这对你有帮助吗?
答案 2 :(得分:2)
我认为一个全局变量位于函数之外(如果是Java中的类成员,或者是C ++ / C中的全局变量),并且每次调用它时它的值都增加一个就可以了。