一个 MAX 面对两个同目标的对手时,搜索树可能按 MAX、MIN1、MIN2 连续展开。把每层机械地切换 max/min 会算错。下面用完整的小树核对三方一轮搜索,叶节点数字都是从 MAX 视角定义的教学收益,没有游戏模型调用或训练。
先定义谁在每层行动
根由 MAX 在 A、B 两个动作中选择。随后 MIN1 选一个分支,再由 MIN2 选一个叶节点。两个 MIN 都希望 MAX 的收益更小,这是本例的同目标对手假设。Berkeley 的多智能体搜索项目明确提醒多个鬼怪会形成多个 MIN 层;教材说明 minimax 的节点价值按当前行动者取最小或最大。

| 根动作 | MIN1 第一分支的叶值 | MIN1 第二分支的叶值 | 根动作最终价值 |
|---|---|---|---|
| A | 3、5 | 4、2 | min(3,2)=2 |
| B | 1、6 | 7、4 | min(1,4)=1 |
MIN2 先把 A 的两组叶节点缩成 3、2,MIN1 再取 2;B 缩成 1、4,再取 1;MAX 最后选 A 得到 2。这里不是平均收益,也不是随机对手的期望值。
运行按行动者索引的完整递归
保存 multi_minimax.py,用 Python 3 运行 python multi_minimax.py。每个列表是一层可选动作,叶节点是数值。函数只处理本文三层完整树;扩展更深树时应把 actor 用模 3 轮换,并明确定义截断深度。
tree=[[[3,5],[4,2]],[[1,6],[7,4]]]
def value(node,actor):
if isinstance(node,(int,float)):
return node
values=[value(child,actor+1) for child in node]
return max(values) if actor==0 else min(values)
scores=[value(branch,1) for branch in tree]
chosen=max(range(len(scores)),key=lambda i:scores[i])
print("root action scores:",scores,"chosen:","AB"[chosen])
assert scores==[2,1] and chosen==0
def wrong(node,depth):
if isinstance(node,(int,float)):
return node
vals=[wrong(child,depth+1) for child in node]
return max(vals) if depth%2==0 else min(vals)
bad_scores=[wrong(branch,1) for branch in tree]
print("incorrect alternation:",bad_scores)
assert bad_scores==[4,6]
用反例定位错误
错误函数在第三层使用 max,得到 A=4、B=6,反而选 B。检查节点时要按当前行动者的目标,不按偶数层必为 MAX。如果对手随机行动,应改为 expectimax 的概率加权;如果三人收益并非同一标量对立,需要另用合适的多方博弈模型,不能将每个别人都当 MIN。
本例展开完整叶节点,没有剪枝、深度限制、启发式评估或实际游戏界面。一轮含 MAX 和两位 MIN 的行动,所谓“深度 1”是一个动作还是整轮,必须先约定。终局真实收益与截断处估值也应分别记录。验收先复算这棵小树,再增加一层完整轮次,避免只凭返回一个动作就判断搜索正确。
资料与核对依据
- https://inst.eecs.berkeley.edu/~cs188/textbook/games/minimax.html
- https://inst.eecs.berkeley.edu/~cs188/fa26/projects/proj2/
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/33219.html