pacman 多智能体-from-黄老师
以下是针对对抗性搜索算法的详细讲解及Python代码示例:
1. Minimax算法
原理:
- 适用于两人零和博弈
- 玩家(Max层)最大化收益,对手(Min层)最小化收益
- 递归评估所有可能走法直到终止状态或深度限制
Pac-Man应用:
幽灵智能体决策、多幽灵协同围堵
def minimax(state, depth, is_max_player):
if depth == 0 or state.is_terminal():
return evaluate(state)
if is_max_player:
max_eval = -float('inf')
for action in state.get_legal_actions():
child = state.generate_successor(action)
eval = minimax(child, depth-1, False)
max_eval = max(max_eval, eval)
return max_eval
else:
min_eval = float('inf')
for action in state.get_legal_actions():
child = state.generate_successor(action)
eval = minimax(child, depth-1, True)
min_eval = min(min_eval, eval)
return min_eval
# 评估函数示例(Pac-Man场景)
def evaluate(state):
pacman_pos = state.get_pacman_position()
food_dist = min([manhattan(pacman_pos, food) for food in state.get_food()])
ghost_penalty = sum([10/(manhattan(pacman_pos, ghost)+1) for ghost in state.get_ghosts()])
return -food_dist - ghost_penalty + state.get_score()
算法补充说明:
Minimax 算法是一种常用于博弈论和人工智能中的搜索算法,以下是关于它的详细介绍:
定义与原理
Minimax 算法的核心思想是在博弈过程中,假设双方都采取最优策略,通过递归地评估博弈树的节点来确定当前玩家的最佳行动。对于一个双人博弈,它会为每个玩家分别计算最优策略。在每个决策点,玩家会选择能使自己的收益最大化(或对手的收益最小化)的行动。
该算法通过构建博弈树来表示博弈的所有可能状态和行动序列。树的节点表示博弈的不同状态,边表示玩家的行动。在搜索过程中,算法会对叶子节点进行评估,根据评估值向上回溯更新父节点的值,最终确定根节点的最佳行动。
算法步骤
构建博弈树:从当前状态开始,生成所有可能的后续状态,形成一棵博弈树。每个节点代表一个博弈状态,边代表玩家的行动。
评估叶子节点:对于博弈树的叶子节点,根据预先定义的评估函数计算其得分。评估函数通常根据当前状态下双方的局面优劣来给出一个数值,例如在象棋中,可以根据棋子的价值、位置等因素来评估局面。
回溯更新节点值:从叶子节点开始,按照 “极小化极大” 的原则向上回溯更新父节点的值。对于最大化玩家(Max 玩家)的节点,选择其子节点中的最大值作为该节点的值;对于最小化玩家(Min 玩家)的节点,选择其子节点中的最小值作为该节点的值。
确定最佳行动:在根节点处,通过比较其子节点的值,选择对应值最大(对于 Max 玩家)或最小(对于 Min 玩家)的子节点所对应的行动作为当前的最佳行动。
示例
以井字棋游戏为例,假设玩家 A 为最大化玩家,玩家 B 为最小化玩家。在游戏的某一时刻,构建博弈树,对每个叶子节点(即游戏的最终状态或暂时无法继续扩展的状态)进行评估。如果是玩家 A 获胜的状态,评估值为 + 1;如果是玩家 B 获胜的状态,评估值为 -1;如果是平局,评估值为 0。然后按照 Minimax 算法的步骤回溯更新节点值,最终为当前玩家 A 找到最佳的落子位置。
优化与扩展
α - β 剪枝:这是一种对 Minimax 算法的优化技术,通过在搜索过程中剪掉一些不可能影响最终结果的分支,从而减少搜索空间,提高算法效率。在搜索过程中,维护两个值 α 和 β,分别表示 Max 玩家的下界和 Min 玩家的上界。当搜索到某个节点时,如果其值小于等于 α,说明该节点对 Max 玩家没有价值,可以剪掉;如果其值大于等于 β,说明该节点对 Min 玩家没有价值,也可以剪掉。
深度限制:为了避免在复杂的博弈树中进行无限深度的搜索,通常会设置一个搜索深度限制。当搜索到达指定深度时,即使没有到达叶子节点,也会使用评估函数对当前状态进行评估,并以此作为该节点的值进行回溯。这样可以在有限的时间内得到一个近似的最佳行动。
应用领域
博弈游戏:如国际象棋、围棋、井字棋等各种双人博弈游戏,Minimax 算法可以帮助计算机找到最优的下棋策略,与人类玩家进行对抗。
决策系统:在一些需要进行决策的系统中,例如资源分配、谈判策略等场景,Minimax 算法可以用于分析不同决策选项的优劣,帮助决策者选择最优策略,以应对不同的情况和对手的反应。
Minimax 算法是一种重要的搜索算法,在博弈论和人工智能领域有着广泛的应用,它为解决双人对抗博弈问题提供了一种有效的方法,并通过各种优化技术不断提高其效率和实用性。
2. Alpha-Beta剪枝
原理:
- 在Minimax基础上增加剪枝优化
- 维护alpha(当前Max玩家最佳值)和beta(当前Min玩家最佳值)
- 当某个分支的评估值超出当前alpha-beta范围时终止搜索
def alpha_beta(state, depth, alpha, beta, is_max_player):
if depth == 0 or state.is_terminal():
return evaluate(state)
if is_max_player:
value = -float('inf')
for action in state.get_legal_actions():
child = state.generate_successor(action)
value = max(value, alpha_beta(child, depth-1, alpha, beta, False))
alpha = max(alpha, value)
if beta <= alpha:
break # β剪枝
return value
else:
value = float('inf')
for action in state.get_legal_actions():
child = state.generate_successor(action)
value = min(value, alpha_beta(child, depth-1, alpha, beta, True))
beta = min(beta, value)
if beta <= alpha:
break # α剪枝
return value
# 初始调用示例
best_value = alpha_beta(initial_state, depth=3, alpha=-float('inf'), beta=float('inf'), is_max_player=True)
3. MCTS(蒙特卡洛树搜索)
原理:
- Selection:使用UCB公式选择节点
- Expansion:扩展未探索的子节点
- Simulation:随机模拟到终局
- Backpropagation:回传模拟结果
Pac-Man应用:
复杂场景决策、多目标优化(吃豆+躲避幽灵)
import math
import random
class Node:
def __init__(self, state, parent=None):
self.state = state
self.parent = parent
self.children = []
self.visits = 0
self.total_reward = 0.0
def ucb(self, exploration=1.414):
if self.visits == 0:
return float('inf')
return (self.total_reward / self.visits) + exploration * math.sqrt(math.log(self.parent.visits) / self.visits)
class MCTS:
def __init__(self, iterations=1000):
self.iterations = iterations
def search(self, root_state):
root = Node(root_state)
for _ in range(self.iterations):
node = root
# 1. Selection
while node.children:
node = max(node.children, key=lambda x: x.ucb())
# 2. Expansion
if not node.state.is_terminal():
legal_actions = node.state.get_legal_actions()
for action in legal_actions:
child_state = node.state.generate_successor(action)
node.children.append(Node(child_state, node))
node = random.choice(node.children) # 选择任意子节点扩展
# 3. Simulation
sim_state = node.state.copy()
while not sim_state.is_terminal():
sim_state = sim_state.generate_successor(random.choice(sim_state.get_legal_actions()))
# 4. Backpropagation
reward = self.calculate_reward(sim_state)
while node is not None:
node.visits += 1
node.total_reward += reward
node = node.parent
# 返回访问次数最多的动作
return max(root.children, key=lambda c: c.visits).state.last_action
def calculate_reward(self, state):
# 自定义奖励函数
return state.get_score() + 10*len(state.get_food())
算法对比分析
| 特性 | Minimax | Alpha-Beta | MCTS |
|---|---|---|---|
| 时间复杂度 | O(b^d) | O(b^(d/2)) | O(iterations) |
| 空间复杂度 | O(d) | O(d) | O(n) |
| 是否需要评估函数 | 必须 | 必须 | 可选 |
| 适用场景 | 确定环境 | 确定环境 | 不确定环境 |
| 最优性保证 | 是 | 是 | 概率收敛 |
实际应用建议:
- 简单场景:使用Alpha-Beta剪枝(深度3-5层)
- 复杂博弈:采用MCTS(2000+次迭代)
- 实时系统:结合启发式评估和剪枝策略
- 参数调优:根据实验调整UCB中的探索系数、模拟次数等参数
完整实现需要考虑状态表示优化、记忆化存储、并行化计算等工程细节。在伯克利Pac-Man项目中,这些算法通常用于multi-agent场景下的幽灵AI控制。

浙公网安备 33010602011771号