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

如何在递归函数中获取值?Minimax实现Nim游戏遇最优动作返回问题

解决Minimax版Nim无法返回最优动作的问题

我之前帮不少人排查过Minimax算法的这类问题——核心问题在于你当前的实现只专注于计算整棵树的效用值,却没把“产生这个效用的动作”同步跟踪保存下来。Minimax要返回最优动作,得在递归回溯的时候,同时把效用值和对应的最佳动作绑定在一起返回才行。

给你具体的修改思路和示例:

1. 修改递归函数的返回值

把原来只返回效用值的函数,改成返回一个元组 (最佳效用值, 最优动作)。比如原来的函数可能是这样:

def minimax(state, player):
    # ... 计算效用值
    return utility_value

现在改成:

def minimax(state, player):
    # 处理终止状态:比如Nim中石子数为0时,返回效用和空动作
    if is_terminal(state):
        return (get_utility(state), None)
    
    best_move = None
    if player == "Max":
        max_value = -float('inf')
        # 生成当前状态下所有可能的合法动作(比如Nim中取1颗石子,从5变4)
        for move in generate_moves(state):
            next_state = apply_move(state, move)
            # 递归调用Min玩家的回合
            current_value, _ = minimax(next_state, "Min")
            # 更新最大值和对应的动作
            if current_value > max_value:
                max_value = current_value
                best_move = move  # 这里记录下产生最大值的动作
        return (max_value, best_move)
    else:  # Min玩家回合
        min_value = float('inf')
        for move in generate_moves(state):
            next_state = apply_move(state, move)
            current_value, _ = minimax(next_state, "Max")
            if current_value < min_value:
                min_value = current_value
                best_move = move
        return (min_value, best_move)

2. 适配Nim游戏的具体逻辑

你需要把上面的is_terminal、generate_moves、apply_move、get_utility替换成Nim游戏的实现:

  • is_terminal(state):判断当前石子数是否为0
  • generate_moves(state):比如当前石子数是n,生成所有合法的取子动作(比如取1颗,得到n-1)
  • apply_move(state, move):把动作应用到当前状态,得到下一个状态(比如从5取1,得到4,同时切换玩家为Min)
  • get_utility(state):终端状态的效用值,比如Max赢了返回1,Min赢了返回-1

3. 调用函数获取最优动作

当你从初始状态(5, "Max")调用时,直接取返回元组的第二个元素:

initial_state = (5, "Max")  # 匹配你的状态定义格式
utility, best_move = minimax(initial_state[0], initial_state[1])
# 或者根据你的状态处理逻辑调整调用方式,最终拿到的best_move就是(4, "Min")
print(f"最优动作:{best_move}")

关键注意点

  • 确保在遍历所有可能动作时,每一次递归都要把对应的动作和它的效用值关联起来,而不是只更新数值
  • 如果你的状态包含玩家信息,记得在apply_move里完成玩家的切换(Max→Min,Min→Max)

这样修改后,你的算法就能在计算效用值的同时,把产生该效用的最优动作给返回出来了。

内容的提问来源于stack exchange,提问作者Vural Erdogan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:53:01