递归多人游戏中的收益率

时间:2017-02-24 21:05:24

标签: python recursion

我刚写了这个函数并从解释器“RecursionError:比较超出最大递归深度”中得到错误 是否有可能在此递归中使用yield?

def multiplyer(fir, sec):
    if(sec==1):
       return fir
    else: 
       return fir+multiplyer(fir, sec-1)
print(multiplyer(5, 2983))

4 个答案:

答案 0 :(得分:1)

根本不需要使用yield(据我所知,它无论如何都不会起作用)。您的multiplayer功能仅相当于:

def multiplayer(fir,sec):
    return fir*sec

此外yield不会有太大的区别,因为它仍然会导致递归错误:毕竟你仍然会执行2983深度调用(对于调用堆栈来说通常太多)。 Python也不支持尾递归优化(TRO)

如果要使用生成器,则使用

yield。生成器生成多个(可以是零,一个或多个)值。但是,您需要一个单独的值(并且需要立即使用)。但是假设您使用yield之类的:

def multiplyer(fir, sec):
    if(sec==1):
       yield fir
    else:
       yield fir+next(multiplyer(fir, sec-1))

print(next(multiplyer(5, 2983)))

它不会有任何区别:你仍然会进行递归并达到界限。

答案 1 :(得分:1)

你的堆栈空间不足,因为你让函数自己调用了2983次,这意味着你在堆栈上存储了那么多的返回地址和参数,这是不合理的。

如果您的要求是使用递归,则可以通过执行以下操作将递归深度减少到 O(logn)顺序:

def multiplyer(fir, sec):
    if sec==1:
       return fir
    elif sec==0:
       return 0
    else: 
       return multiplyer(fir, sec//2) + multiplyer(fir, (sec+1)//2)
print(multiplyer(5, 2983))

或者更有效率,还减少了对 O(logn)顺序的递归调用次数:

def multiplyer(fir, sec):
    if sec==0:
       return 0
    elif sec%2 == 0: 
       return 2 * multiplyer(fir, sec//2)
    else:
        return fir + 2 * multiplyer(fir, sec//2)
print(multiplyer(5, 2983))

答案 2 :(得分:0)

处理递归时,您可以检查允许的最大递归深度,如:

sys.setrecursionlimit(3000)

,好的是你也可以设置它:

{{1}}

但是,这并没有说明您的代码,或者它是否适合您要实现的目标。

答案 3 :(得分:0)

不要在迭代中使用Python中的递归。生成器优化了内存的使用,没有别的。它们比替代方案慢,并且不提供全局递归限制的任何变通方法(实际上是对调用堆栈大小的限制;非递归调用也计入限制)。

# Just demonstrating the conversion from recursion to iteration.
# fir * sec would be the most efficient solution.
def multiplyer(fir, sec):
    rv = 0
    while sec > 0:
        rv += fir
        sec -= 1
    return rv