尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

融合搜索与强化学习的多智能体路径规划:解决动态环境下的旋转与避障难题

融合搜索与强化学习的多智能体路径规划:解决动态环境下的旋转与避障难题 1. 项目概述当搜索算法遇上强化学习解决多智能体路径规划的“旋转”难题在仓储物流、自动驾驶、游戏AI等复杂动态环境中让一群智能体机器人、车辆、虚拟角色高效、无碰撞地到达各自目标点同时还要处理诸如旋转、转向等精细动作这是一个经典的多智能体路径规划问题。传统的MAPF方法无论是基于搜索的A*、CBS还是基于规则的启发式算法在面对“终身”任务——即智能体在完成一批任务后立刻无缝衔接下一批新任务——时往往显得力不从心。它们要么计算开销巨大难以实时响应要么缺乏泛化能力环境布局一变就得重新规划。最近我和团队在攻克一个实际项目时就遇到了这个痛点。我们需要在模拟的自动化仓库中调度数十台AGV自动导引车进行物料搬运。这些AGV不仅需要直线移动在货架巷道尽头还需要执行90度或180度的旋转来调整方向。单纯使用强化学习训练收敛慢且在复杂冲突下容易陷入局部最优单纯使用搜索算法又无法适应持续到来的新任务流。于是我们探索并实现了一套“搜索辅助的联合智能体-环境强化学习”框架。这个框架的核心思想很直观让经典的搜索算法为强化学习提供“即时教练”和“高质量示范”同时让强化学习学会泛化的策略反过来加速搜索并处理搜索难以建模的复杂约束如旋转动力学。最终我们实现了在动态、终身任务场景下既保持高求解质量又具备强大鲁棒性的多智能体路径规划。2. 核心思路拆解为什么是“搜索”与“强化学习”的联姻2.1 传统方法的瓶颈与融合动机在深入我们的方案前有必要先看看“孤军奋战”时双方的问题。基于搜索的MAPF例如冲突搜索其优势在于完备性和最优性在有限搜索空间内。它能给出严格无冲突的路径。但在终身MAPF场景下问题接踵而至计算爆炸随着智能体数量增加搜索空间呈指数级增长实时性难以保证。缺乏重用性每次任务都是全新的求解过程即使环境布局只变了一点也得从头再来。难以处理连续动作与复杂动力学搜索通常工作在离散的网格空间。对于“旋转”这类动作如果精细建模如将每个角度离散化会进一步加剧计算负担如果粗略处理则规划出的路径可能无法被实际控制器执行。基于强化学习的MAPF特别是多智能体强化学习其优势在于学习泛化策略。一个训练好的策略网络可以快速响应新的状态实现毫秒级决策。但它也有阿喀琉斯之踵稀疏奖励与探索困难在MAPF中只有所有智能体都到达目标才有高额奖励这导致探索效率极低。信用分配难题在多智能体系统中成功或失败是集体行为的结果很难区分每个智能体的贡献或过失。训练不稳定与收敛慢需要海量的环境交互样本训练成本高。我们的融合思路正是取长补短。搜索算法就像一个拥有完备领域知识但计算缓慢的“老专家”它可以为强化学习在关键决策点提供近乎最优的短期指导即“搜索辅助”。而强化学习则像一个善于总结规律、快速反应的“学生”它从这些指导中学习最终形成自己能应对各种局面的策略甚至能处理“老专家”不擅长的连续旋转动作。2.2 “联合智能体-环境”学习的内涵“联合智能体-环境”是另一个关键。在标准RL中智能体学习如何在一个固定的环境模型中行动。但在终身MAPF中环境是动态变化的其他智能体在移动新任务在发布。我们将其他智能体的策略和环境动态共同视为一个“联合环境”。我们的学习目标是让每个智能体学会在这个非平稳的联合环境中稳健行动的策略。具体实现上我们采用了“集中式训练分布式执行”的范式并引入了注意力机制。在训练时一个中央评论家网络可以获取所有智能体的观测信息来更准确地评估联合状态的价值从而更好地指导每个智能体行动者网络的更新。这有助于解决多智能体信用分配难题。注意力机制则让智能体学会在决策时“关注”与之可能发生冲突的邻近智能体而不是对所有智能体一视同仁这大大提升了策略的效率和可解释性。注意这里的“联合”并非指智能体共享参数或有一个中央控制器而是在训练阶段利用全局信息进行学习优化执行时每个智能体仍完全独立、基于局部观测做出决策这保证了系统的可扩展性和去中心化部署能力。3. 框架设计与核心组件解析我们的框架主要包含三个核心循环内层强化学习训练循环、中层搜索辅助循环以及外层终身任务执行循环。3.1 整体架构与工作流程整个系统的运行可以概括为以下几个阶段初始化构建模拟环境初始化所有智能体的策略网络、价值网络以及经验回放缓冲区。终身任务循环接收一批新的起点-目标点对。进入搜索辅助的强化学习决策循环直到本批任务完成或达到最大步数。搜索辅助决策在每个时间步对于每个智能体系统会进行判断。如果当前状态处于“关键决策点”例如前方出现多个路径分支、与其他智能体潜在冲突则调用轻量级搜索算法如窗口限制的A*为该智能体规划一条短视距的优化路径。强化学习整合与执行将搜索得到的路径片段转化为一系列动作包括前进、左转、右转、等待并将这些动作作为专家示范以额外的奖励或直接的行为克隆方式注入到对应智能体的强化学习训练过程中。智能体最终执行的动作是其策略网络输出与搜索建议的混合例如以一定概率遵循搜索建议。经验收集与学习智能体执行动作后环境转移到新状态并产生奖励如到达目标的正奖励、碰撞的负奖励、等待的微小负奖励。这些经验被存入回放缓冲区。集中式训练定期从缓冲区采样批次数据使用多智能体强化学习算法我们采用了MADDPG并集成了注意力机制可称为一种简化版的Actor-Attention-Critic更新网络。评论家网络利用所有智能体的观测和动作来学习联合价值函数从而更好地指导行动者网络的策略更新。任务切换与策略继承当一批任务完成后策略网络参数被保留作为下一批任务的初始策略。这使得智能体能够积累跨任务的泛化经验。3.2 针对“旋转”动作的特殊设计“旋转”是引入连续动作空间和复杂动力学的关键。我们放弃了将旋转离散为“左转90度”、“右转90度”的简单做法而是采用了更符合物理实际的设计。动作空间每个智能体的动作是一个二维连续向量[v, ω]。其中v是线速度前进/后退ω是角速度逆时针/顺时针旋转。通过设定v0且ω≠0智能体就可以执行原地旋转。状态空间除了智能体自身的坐标(x, y)我们还将朝向角θ作为状态的一部分。这比只用离散方向东、南、西、北包含了更多信息。奖励函数设计这是教会智能体高效旋转的关键。我们设计了分层奖励基础导航奖励朝向目标方向时给予小额正奖励背离时给予小额负奖励。这鼓励智能体尽早对准目标。旋转惩罚执行旋转动作ω绝对值较大时施加一个微小的负奖励。这防止智能体无意义地“转圈”鼓励其在必要时才旋转。平滑性奖励鼓励连续时间步间动作变化平缓避免急转这有利于实际控制。稀疏成功奖励只有到达目标位置且朝向与预设目标方向一致例如在货架前需要正面朝向货架时才给予高额奖励。搜索算法的适配为了给包含旋转的连续动作提供指导我们对搜索算法进行了扩展。在搜索时我们将连续状态离散化到一个更精细的(x, y, θ)状态网格。搜索算法规划的是一条通过这个三维状态空间的路径其中就包含了在特定位置进行旋转的指令。这条路径随后被转化为一系列[v, ω]的参考动作供强化学习智能体模仿。4. 实操要点与核心实现细节4.1 环境搭建与智能体建模我们使用PyTorch作为深度学习框架在OpenAI Gym风格的自定义环境中进行开发。环境是一个二维网格世界但智能体的状态和动作是连续的。import torch import torch.nn as nn import numpy as np class ContinuousMAPFEnv: def __init__(self, grid_size, num_agents): self.grid_size grid_size self.num_agents num_agents self.agents [] # 初始化智能体每个智能体有连续坐标和朝向 for i in range(num_agents): self.agents.append({ pos: np.random.rand(2) * grid_size, # [x, y] theta: np.random.rand() * 2 * np.pi, # 朝向 goal_pos: ..., goal_theta: ..., radius: 0.5 # 碰撞半径 }) self.max_steps 500 def step(self, actions): # actions: list of [v, ω] for each agent new_states [] rewards [] dones [] # 1. 根据动力学模型更新状态 (简化欧拉积分) for i, agent in enumerate(self.agents): v, w actions[i] dt 0.1 agent[theta] w * dt agent[pos][0] v * np.cos(agent[theta]) * dt agent[pos][1] v * np.sin(agent[theta]) * dt # 2. 计算奖励 reward self._calculate_reward(i, actions[i]) rewards.append(reward) # 3. 检查是否到达目标 (位置和朝向都需满足) done self._check_goal(i) dones.append(done) new_states.append(self._get_observation(i)) # 4. 检查碰撞 self._handle_collisions(rewards) return new_states, rewards, dones, {} def _calculate_reward(self, agent_id, action): agent self.agents[agent_id] reward 0.0 # 朝向奖励 vec_to_goal agent[goal_pos] - agent[pos] desired_theta np.arctan2(vec_to_goal[1], vec_to_goal[0]) theta_diff abs((agent[theta] - desired_theta np.pi) % (2*np.pi) - np.pi) reward 0.01 * (np.pi - theta_diff) / np.pi # 越对准目标奖励越高 # 旋转惩罚 reward - 0.001 * abs(action[1]) # ω的绝对值惩罚 # 动作平滑惩罚 (需记录上一动作) reward - 0.0005 * np.linalg.norm(action - self.last_actions[agent_id]) self.last_actions[agent_id] action return reward4.2 集成注意力机制的Actor-Critic网络我们为每个智能体设计了一个行动者网络和一个评论家网络。评论家网络的关键在于使用了注意力机制来聚合其他智能体的信息。class AttentionCritic(nn.Module): def __init__(self, obs_dim, act_dim, num_agents, hidden_dim128): super().__init__() self.obs_dim obs_dim self.act_dim act_dim self.num_agents num_agents # 编码每个智能体的观测-动作对 self.encoder nn.Sequential( nn.Linear(obs_dim act_dim, hidden_dim), nn.ReLU(), ) # 注意力层计算查询智能体与其他智能体的相关性 self.query nn.Linear(hidden_dim, hidden_dim) self.key nn.Linear(hidden_dim, hidden_dim) self.value nn.Linear(hidden_dim, hidden_dim) # 最终输出Q值 self.output nn.Sequential( nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, 1) ) def forward(self, obs, acts): # obs: [batch_size, num_agents, obs_dim] # acts: [batch_size, num_agents, act_dim] batch_size obs.size(0) # 拼接观测和动作 inputs torch.cat([obs, acts], dim-1) # [batch, num_agents, obs_dimact_dim] encoded self.encoder(inputs) # [batch, num_agents, hidden_dim] # 计算注意力 (为每个智能体计算) q self.query(encoded) # [batch, num_agents, hidden_dim] k self.key(encoded) # [batch, num_agents, hidden_dim] v self.value(encoded) # [batch, num_agents, hidden_dim] scores torch.matmul(q, k.transpose(-2, -1)) / (self.hidden_dim ** 0.5) # [batch, num_agents, num_agents] attn_weights torch.softmax(scores, dim-1) # 注意力权重 context torch.matmul(attn_weights, v) # [batch, num_agents, hidden_dim] # 将上下文信息与智能体自身编码信息结合 (例如相加) combined encoded context # 为每个智能体输出Q值 q_values self.output(combined).squeeze(-1) # [batch, num_agents] return q_values行动者网络则相对标准输入当前智能体的局部观测输出连续动作[v, ω]并通过tanh激活函数将输出限制在[-1, 1]范围内再映射到实际的速度和角速度范围。4.3 搜索辅助模块的实现搜索辅助模块并非在每个时间步为所有智能体运行全局搜索那样代价太高。我们实现了一个触发式的局部搜索。class SearchAidModule: def __init__(self, env, search_window10): self.env env self.window search_window # 搜索视野步数 def get_advice(self, agent_id, current_state): 判断是否需要并给出搜索建议。 current_state: 包含自身位置、朝向、目标、以及其他智能体的预测位置。 # 触发条件判断 if not self._need_search(agent_id, current_state): return None # 构建局部搜索问题 # 1. 离散化状态: 将连续位置和朝向离散到网格 start_grid self._continuous_to_grid(current_state[pos], current_state[theta]) goal_grid self._continuous_to_grid(current_state[goal_pos], current_state[goal_theta]) # 2. 将其他智能体在未来几个时间步内的预测位置作为动态障碍物 dynamic_obstacles self._predict_other_agents_trajectories(agent_id, self.window) # 3. 运行受限的A*搜索 (在状态空间 (x_grid, y_grid, theta_discrete) 中) path self._run_astar(start_grid, goal_grid, dynamic_obstacles, max_stepsself.window) if path is None or len(path) 2: return None # 搜索失败或无需移动 # 4. 将搜索得到的路径片段转化为一系列参考动作 advised_actions self._path_to_actions(path, current_state) return advised_actions # 例如未来5个时间步的建议动作列表 def _need_search(self, agent_id, state): # 触发搜索的启发式条件 # 1. 智能体接近一个决策点如十字路口 # 2. 与其他智能体的预计最短距离在未来几步内小于安全阈值 # 3. 智能体在一段时间内未向目标靠近可能陷入僵局 # 满足任一条件则返回True pass在训练时如果某个智能体获得了搜索建议advised_actions我们会采取两种方式利用它行为克隆损失在行动者网络的损失函数中增加一个与搜索建议动作的均方误差损失项鼓励智能体模仿好的短期决策。奖励塑造如果智能体执行的动作与搜索建议的动作接近则给予一个额外的正奖励引导其学习。5. 训练流程、调参心得与避坑指南5.1 分层训练策略直接在整个复杂环境中训练非常困难。我们采用了分层训练策略单智能体无旋转训练先在一个简单空旷环境中训练单个智能体从随机点移动到随机目标点不涉及旋转和避障。目的是让智能体学会基本的导航和利用朝向奖励。单智能体带旋转训练引入旋转动作和朝向目标要求。调整旋转惩罚的系数直到智能体学会在必要时才进行精确旋转。多智能体静态障碍训练增加多个智能体但初始目标不冲突环境中放置静态障碍。使用基础的MADDPG训练协作避障。引入搜索辅助在策略有一定基础后引入搜索辅助模块。开始时设置较高的搜索触发概率和模仿学习权重让智能体严重依赖搜索指导。随后随着策略网络性能提升逐渐降低搜索频率和模仿权重让策略网络学会自主做出类似搜索的优质决策。终身任务训练最后在终身任务设置下进行最终微调让智能体适应任务流的切换。5.2 关键超参数与调参经验搜索触发条件阈值这是平衡性能与计算开销的关键。阈值太松搜索调用频繁拖慢速度阈值太紧智能体得不到关键指导。我们通过观察验证集上的冲突次数和求解时间来确定。一个实用的方法是开始时设置较松的阈值确保学习到好的行为训练后期逐步收紧阈值鼓励策略网络自主决策。模仿学习权重 vs RL 损失权重在行动者总损失中模仿损失和策略梯度损失的权重需要动态调整。初期模仿权重大后期RL权重大。我们使用了一个线性衰减的模仿权重。奖励函数中各部分的系数这是调参的难点。我们的经验是稀疏成功奖励必须足够高以覆盖整个回合的累计负奖励。朝向奖励的系数要小它只是引导不能盖过最终目标。旋转惩罚和平滑惩罚的系数要非常小如0.001量级它们的目的是消除无意义动作而不是阻止必要动作。需要反复测试观察智能体是否“愿意”在路口执行必要的90度转弯。注意力机制的维度隐藏层维度不宜过大否则容易过拟合。对于20-50个智能体的场景128维通常足够。5.3 常见问题与排查实录在实际开发和训练中我们遇到了不少“坑”以下是部分记录问题1智能体在原地“转圈”或抖动。现象智能体不断左右快速旋转不向目标移动。排查首先检查奖励函数。通常是旋转惩罚系数过大导致智能体认为任何旋转都代价高昂于是试图通过微小正反旋转来调整朝向累积起来就成了转圈。其次是朝向奖励设计有误可能计算出的期望朝向不连续如在角度从-pi到pi跳变时导致奖励信号震荡。解决降低旋转惩罚系数例如从0.01降到0.001。确保朝向奖励的计算是平滑的使用角度差的最小值。问题2搜索辅助后性能反而下降。现象引入搜索建议后智能体的碰撞次数增加或任务完成时间变长。排查检查搜索算法本身是否正确。动态障碍物预测是否准确如果预测不准搜索出的“无冲突”路径实际执行时就会碰撞。另外检查搜索建议动作的转换是否正确从离散路径到连续动作[v, ω]的映射可能存在误差。解决简化动态障碍物预测模型例如假设其他智能体保持当前速度匀速直线运动。在动作转换时加入PID控制器来平滑跟踪路径点而不是直接给定速度。问题3训练后期策略不稳定时好时坏。现象训练曲线波动大有时成功率高有时又暴跌。排查这可能是多智能体强化学习的典型问题——非平稳性。一个智能体策略的改进会改变其他智能体的环境导致其旧经验失效。另外经验回放缓冲区中旧的经验来自早期弱策略可能会干扰当前策略的学习。解决1) 采用重要性采样或定期清空部分旧经验。2) 降低策略网络的学习率并增加目标网络的软更新参数τ使其变化更平滑。3) 在评论家网络中除了当前联合动作也输入下一个状态的联合动作如DDPG中那样以稳定Q值估计。问题4智能体在狭窄通道口形成死锁。现象两个智能体在通道口面对面都不愿后退陷入僵局。排查这是MAPF的经典问题。纯强化学习策略可能缺乏解决此类对称困境的能力。解决这是搜索辅助可以大显身手的地方。在搜索触发条件中加入“检测到死锁状态”的判定。一旦触发搜索算法可以为其中一个智能体规划一个包含“主动后退”动作的短路径打破对称。同时在奖励函数中为“礼貌”的避让行为如短暂后退让路设计一个中期奖励让强化学习策略也能学会这种高级社交行为。6. 效果评估与未来扩展思考我们在一系列标准MAPF测试场景和自定义的自动化仓库场景中评估了我们的框架。与纯基于搜索的CBS算法和纯多智能体强化学习方法相比我们的“搜索辅助联合学习”框架在终身任务设置下展现出显著优势求解成功率在动态任务流中接近CBS的完备性远高于纯RL方法。平均任务完成时间比CBS更短因为学习到的策略能做出更快的实时反应减少了搜索开销。泛化能力在训练未见过的、更大规模或更复杂布局的环境中性能下降幅度远小于纯搜索方法需要重新规划和纯RL方法严重过拟合。从工程实践角度看这个框架最大的价值在于它提供了一种兼顾最优性与实时性、兼顾精确规划与泛化学习的可行路径。搜索模块像一个“安全网”和“导师”确保了系统的基本性能和收敛稳定性而强化学习模块则致力于学习更高效、更适应动态环境的泛化策略。我个人在实际操作中的体会是成功的关键在于把握好搜索与学习之间的“度”。初期要敢于让搜索多介入提供高质量的示范数据后期则要相信学习到的策略逐步撤掉“辅助轮”。这其中的调度逻辑如何触发搜索、如何混合建议动作本身也可以被建模成一个元学习问题这是我们下一步探索的方向。此外将注意力机制进一步扩展为可解释的图神经网络让智能体明确地推理彼此间的空间关系可能会在更复杂的交互场景中带来性能提升。这个框架的潜力远不止于路径规划任何需要结合经典规划与数据驱动学习的序贯决策问题或许都能从中获得启发。
返回列表