2011-02-17 72 views
0

我正在从事AI作业,尽管我的教授提出了建议,但我无意在lisp中编写此作业。不过,我想想递归写,最好保持简洁。这里是我的问题:Python中的递归有多安全?

我正在运行用完堆栈空间的一大风险,如果我进行了一个大的状态空间搜索? Python堆栈有多深?

+1

为什么你不使用尾调用递归呢?堆栈溢出不应该成为问题。 – alternative 2011-02-17 21:23:40

+15

把它写在lisp里是个好主意。 – 2011-02-17 21:24:04

回答

20

有多深不Python的堆栈去?

Python中默认的递归限制是1000帧。您可以使用sys.setrecursionlimit(n)来改变这一点,风险自负。

如果您在使用python设置,我会建议使用更适合的语言模式。如果你想使用递归式的搜索,并需要任意堆栈的深度,你可以使用Python的增强型发生器(协程)来创建一个“蹦床模式”(在PEP342有一个例子)

,尽管我教授的建议,我无意写这个任务在lisp

如果练习的目的是基于递归的,tail-call优化语言,如lisp,可能是你最好的选择。

5

递归在Python(CPython的,这是)不能超过sys.getrecursionlimit()走得更深。您可以使用sys.setrecursionlimit将此限制设置为不同的值。

我看到三个选项:

  1. 使用Lisp语言毕竟,它是递归的问题,优化(与智能Lisp语言的编译器将消除尾递归)
  2. 在递归函数设置递归限制得到无限递归(在程序饮食flaming death的风险)
  3. 使用迭代有一个明确的堆栈。一个简单的list会做。 append被推,pop被弹出。
3
>>> i=0 
>>> def a(): 
...  global i 
...  i += 1 
...  try: 
...    a() 
...  except: 
...    print(i) 
... 
>>> a() 
999 
>>> import sys 
>>> sys.getrecursionlimit() 
1000 

不知道是否有帮助

2

Python的限制递归值的深度可以通过调用sys.setrecursionlimit调用sys.getrecursionlimit和变化找出。默认值不是很大。如果将它设置的太高,那么当Python递归时,最终可能会吹出C堆栈。虽然默认值在所有平台上都应该是安全的(你得到一个Python异常而不是崩溃),但是“太高”依赖于平台。

有语言,使有关尾调用优化了有力保障。 Scheme是最着名的例子;这是一个Lisp方言。不管你有多么不喜欢你的教授,你都应该考虑学习至少一种类似Lisp的语言。

1

正如其他人所指出的那样,尽管存在C栈溢出的风险(假设您正在使用CPython),但您可以使用sys.setrecursiondepth()来增加递归深度。如果遇到这个问题,您可以通过调用thread.stack_size()新的堆栈大小来创建堆栈大小更大的线程,然后生成一个新线程来完成实际工作。