You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归实现水壶问题遇Recursion Error,但循环迭代多低于5000次

水壶问题:递归随机搜索爆栈,循环却正常?

核心差异:递归堆栈帧,循环原地更新

递归调用每次都会在Python的调用栈中新建一个栈帧,存储当前函数的参数、临时变量等上下文信息;而while循环始终在同一个栈帧里执行,仅更新amt1、amt2的状态,不会增加栈的深度。

你的问题根源在随机搜索的不确定性:虽然多数情况下几百到几千步就能找到目标,但偶尔会随机触发循环操作(比如反复装满7升壶再倒空,一直卡在(7,0)→(0,0)→(7,0)的循环状态)。此时递归会持续压栈,次数一旦突破你设置的sys.setrecursionlimit(5000)上限,就会触发栈溢出错误;而循环碰到这种情况,只是在原地反复执行,栈深度始终不变,最多多耗些时间直到随机选到正确路径。

代码细节拆解

递归实现的隐患

你写的random_search函数,每一次递归调用都会在栈中新增一层,哪怕是重复状态也会持续压栈。比如连续随机选中“装满j1”→“倒空j1”,递归深度会飞速上涨,分分钟突破5000的限制。即便设置了递归上限,也架不住某次随机操作一直循环同一个动作。

循环实现的稳定性

while循环全程在同一个栈帧内执行,所有状态更新都是原地修改变量,不管迭代多少次,栈深度始终为1,自然不会出现栈溢出问题。

验证一下?

给递归代码加个深度计数器,打印每次调用的深度,就能看到某次运行中深度会直接冲过5000:

import random
import sys 
sys.setrecursionlimit(5000)

j1, j2, target = 7, 3, 5
depth = 0

def random_search(amt1, amt2):
    global depth
    depth +=1
    print(f"当前递归深度:{depth}")
    r = random.randint(1,6)

    if amt1 == target:
        amt2 = 0
        print(f"We have reached the target state {(amt1, amt2)}")
        return
    
    if r==1:
        return random_search(0, amt2)
    elif r==2:
        return random_search(amt1, 0)
    elif r==3:
        return random_search(j1, amt2)
    elif r==4:
        return random_search(amt1, j2)
    elif r==5:
        return random_search(amt1 + min(amt2, (j1-amt1)), amt2 - min(amt2, (j1-amt1)))
    elif r==6:
        return random_search(amt1 - min(amt1, (j2-amt2)), amt2 + min(amt1, (j2-amt2)))

random_search(0, 0)

多跑几次就能碰到深度突破5000并触发错误的情况。

非要用递归怎么办?

可以加入深度阈值,超过后重置状态重新开始:

import random
import sys 
sys.setrecursionlimit(5000)

j1, j2, target = 7, 3, 5

def random_search(amt1, amt2, depth=0):
    if depth > 4990:  # 留余量避免触发栈上限
        return random_search(0, 0, 0)
    
    r = random.randint(1,6)

    if amt1 == target:
        amt2 = 0
        print(f"We have reached the target state {(amt1, amt2)}")
        return
    
    if r==1:
        return random_search(0, amt2, depth+1)
    elif r==2:
        return random_search(amt1, 0, depth+1)
    elif r==3:
        return random_search(j1, amt2, depth+1)
    elif r==4:
        return random_search(amt1, j2, depth+1)
    elif r==5:
        new_amt1 = amt1 + min(amt2, (j1-amt1))
        new_amt2 = amt2 - min(amt2, (j1-amt1))
        return random_search(new_amt1, new_amt2, depth+1)
    elif r==6:
        new_amt1 = amt1 - min(amt1, (j2-amt2))
        new_amt2 = amt2 + min(amt1, (j2-amt2))
        return random_search(new_amt1, new_amt2, depth+1)

random_search(0, 0)

不过这种方案只是规避问题,本质上还是不如循环稳定。

内容的提问来源于stack exchange,提问作者Sivashankaran S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:05:24