Recursion 优化Lisp递归随机游动
这个函数会导致堆栈溢出超过2000个步骤,有没有任何方法可以轻松优化它以使用更少的内存Recursion 优化Lisp递归随机游动,recursion,optimization,lisp,clisp,Recursion,Optimization,Lisp,Clisp,这个函数会导致堆栈溢出超过2000个步骤,有没有任何方法可以轻松优化它以使用更少的内存 (defun randomwalk (steps state) (displaystate state) (if (equal steps 0) nil (if (solved? state) t (let ((nrmlstate (normalize state))) (randomwalk (- steps 1) (applymove
(defun randomwalk (steps state)
(displaystate state)
(if (equal steps 0) nil
(if (solved? state) t
(let ((nrmlstate (normalize state)))
(randomwalk (- steps 1) (applymove nrmlstate (nth (random
(length (getallmoves nrmlstate))) (getallmoves nrmlstate))))
)
)
)
)
看起来您只能在尾部位置调用,这意味着您可以轻松地将其重写为完全不递归:
(取消随机行走(步骤状态)
(循环:如果(=步骤0)
:do(返回零)
:如果(已解决?状态)
:do(返回t)
:其他
:do(let*((nrmlstate(规范化状态))
(移动(getallmoves nrmlstate))
(随机移动(第n次(随机(长度移动))移动)))
(setf状态(applymove nrmlstate随机移动))
(decf步骤)
由于我没有您使用的函数,所以除了基本情况外,我无法对其进行测试 您可能希望通过更好的代码格式和可复制的测试用例来改进您的问题。请参阅此Stackoverflow帮助:正如Rainer所说,代码的格式太差,很难看到它的作用(缺少测试用例也无济于事),但在大多数实现中(但语言不保证),编译此函数会导致一个不使用堆栈的进程。(有些实现甚至可能不需要编译步骤。)我希望保持它的纯功能性,但这是可行的!我一直在使用gnu clisp,目前还没有办法增加内存限制或使clisp进行尾部递归优化。@Rossgrieebow我认为clisp具有尾部调用优化功能,因此,如果您编译该函数,将不再出现堆栈溢出,然而,由于公共LISP标准不需要实现这样的操作,甚至考虑标准中的任何优化提示,所以在便携式应用程序中不能依赖它们。因此,在CL中进行函数编程的惯用方法是通过线性更新。这样,只要接口正常工作,就可以在内部进行变异。@Rossgrieebnow顺便说一句,增加堆栈大小取决于系统,但CLISP FAQ针对无法编译或重写的递归进行了修改。