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(蒙特卡洛树搜索)

原理

  1. Selection:使用UCB公式选择节点
  2. Expansion:扩展未探索的子节点
  3. Simulation:随机模拟到终局
  4. 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)
是否需要评估函数 必须 必须 可选
适用场景 确定环境 确定环境 不确定环境
最优性保证 概率收敛

实际应用建议

  1. 简单场景:使用Alpha-Beta剪枝(深度3-5层)
  2. 复杂博弈:采用MCTS(2000+次迭代)
  3. 实时系统:结合启发式评估和剪枝策略
  4. 参数调优:根据实验调整UCB中的探索系数、模拟次数等参数

完整实现需要考虑状态表示优化、记忆化存储、并行化计算等工程细节。在伯克利Pac-Man项目中,这些算法通常用于multi-agent场景下的幽灵AI控制。

posted @ 2025-04-08 10:00  kkman2000  阅读(70)  评论(0)    收藏  举报