2012-04-14 50 views
1

基本上我有在Python這個龐大的函數(我已經簡化到裸基礎知識)需要使這個遞歸算法迭代由於堆棧溢出

def rec(a,b): 
    if stoppingCondition==True: return 1 

    key=(a,b) 
    if key in memo: return memo[key] 

    if b==side condition: 
     memo[key]=rec(a+1,b) #RECURSIVE CALL 
     return memo[key] 

    total=0 
    for d in D: 
     if condition1==True: 
      b=some process 1 
      total+=rec(a+1,b) #RECURSIVE CALL 
     elif condition2==True: 
      for x,y in d: 
       if (some break condition==True): break 
      else: #only gets called if break didnt happen 
       b=some process 2 
       total+=rec(a+1,b) #RECURSIVE CALL 
    memo[key]=total 
    return memo[key] 

,我有一個時間讓赫克它是迭代的,因爲它爲更深的遞歸級別打了折扣。我已經閱讀了關於轉換爲循環和堆棧的其他線程,以及不能使用它的任何工作。

+0

我想我試過setrecursionlimit事情協議棧的方法BTW – 2012-04-14 23:06:27

回答

1

對於所有的b,您始終可以計算出rec(a, b),從最高的a開始,然後在沒有遞歸的簡單循環中遞減。現在,如果對rec()的所有可能調用的遍歷都是稀疏的,則此解決方案不可行,因爲它會引入大量不必要的計算。

另一個解決方案是嘗試在Python中實現尾部調用優化。我沒有嘗試過,但你可能想要測試this decorator

一個不太優雅的解決方案是增加遞歸限制,以滿足您的需求:

import sys 
sys.setrecursionlimit(10000) 
+0

,這是不夠的不幸。你發佈的裝飾器也不能正常工作(我的函數返回錯誤的值)。不知道你是什麼意思關於循環所有b從最高a開始。 – 2012-04-14 20:55:11

+0

您是否嘗試增加'setr​​ecursionlimit'的值?當你增加很多時會發生什麼?如果你知道'a'的最大值,那麼你可以開始計算所有'b'的最大值'a'的值,等等。 – 2012-04-14 21:01:38

+0

當我從main()調用我的函數時,我用a = 0和b = 0列表來完成它。 – 2012-04-14 21:05:32