资讯动态

多智能体可达性判定:从AGV死锁到CBS冲突搜索实践

发布时间:2026/10/14 7:23:15 来源:尧图企业网站定制
做过多智能体调度系统的人大概率都经历过这种让人抓狂的瞬间任务列表里排着二三十个搬运任务路径规划器跑得满头大汗最后一台AGV被堵在出发区十分钟出都出不来。你盯着地图看半天单台车明明怎么走都通几台车凑一起就是死锁。问题出在哪出在“可达性”这个环节被跳过了。Agent-Reach 就是为解决这个问题写的——一套聚焦多智能体可达性判定Multi-Agent Reachability的轻量级判定引擎。它回答的问题非常明确给定一张地图、一组智能体AGV、无人机、NPC都行、各自起点终点以及一个时间上限 T是否存在一组无碰撞的轨迹让所有智能体在 T 步内到达目标注意这里只需要“是/否”的判定结论不需要给出具体路径。这个结论能直接喂给任务分配系统、路径规划器或者人工运营后台避免系统接了根本送不到的单、跑了必然死锁的路径。这篇文章适合做仓储物流调度、机器人集群控制、自动驾驶决策、游戏 AI 寻路的朋友。我会从原理、建模、核心代码、性能实测到踩坑经验完整拆一遍文末给出一个可直接参考的实现骨架。1. 为什么需要 Agent-Reach先解决“能不能到”再讨论“怎么走”1.1 多智能体系统的“可达性黑洞”我接手过的仓储 AGV 项目里调度系统最常见的隐性故障就是“静态可达动态不可达”。单看地图A 点到 B 点连通没有任何障碍物挡住一旦把二三十台车的实时位置叠加上去情况立刻变了——路口被占、巷道被堵、两个智能体在狭窄通道里迎面相遇。每一台车单独看都能到但作为一个整体它们互相把对方的可行走空间锁死了。这种问题之所以难排查是因为它不是某一条路径的错误而是整个任务组合的可行性问题。路径规划器只负责“在有解的情况下找路”如果问题本身无解它只会超时、失败或者陷入死循环重试。而调度员看到的症状是“任务一直没完成”“系统卡住了”没有人告诉上层这个任务组合从一开始就不可达。Agent-Reach 要做的就是把这一层显式地抽出来。在任务分配之后、路径规划之前先做一个快速判定这批任务在给定时间预算下到底有没有可行解。没有解就别浪费算力去跑路径搜索了直接换任务组合、换目标点、或者扩大时间预算。这里有个容易混淆的点先厘清单智能体可达性静态连通性非常廉价一次 BFS 就能解决复杂度 O(E)但多智能体可达性完全不是一回事它要考虑所有智能体在同一时空内的位置约束、边冲突、时序交错复杂度随智能体数量呈指数级增长。很多团队把单智能体可达性当成理所当然的前提结果在多智能体场景里反复踩坑。1.2 Agent-Reach 在调度系统里的位置我把一个典型的智能体调度系统分成五层层级职责典型问题任务分配决定哪个智能体执行哪个任务分配后目标可能不可达可达性判定判断任务组合是否存在可行解这一层常被跳过路径规划在确认有解的前提下找具体轨迹无解时会超时/死循环冲突消解处理动态扰动和局部冲突需要实时重规划执行监控下发指令、采集状态偏差累积导致二次碰撞Agent-Reach 恰好卡在任务分配和路径规划之间。它不替代路径规划器而是为路径规划器提供一个“保底答案”。有了这个判定层系统在任务分配阶段就能拒绝掉不可达的组合路径规划器不会在无解问题上浪费计算资源运营后台也能在任务下发前看到“这条任务不可达”的明确反馈而不是等到超时才被动处理。这个“先判定、后规划”的思路在大型仓储项目里已经是标准实践了。顺带说一句国内头部电商仓库里几百台 AGV 的调度系统基本都有类似的可达性预检模块只是有的叫 Reachability Check有的叫 Feasibility Filter做的都是同一件事。2. 核心原理拆解多智能体可达性到底难在哪2.1 复杂度断层从 O(E) 到 V^K单智能体可达性为什么便宜因为只需要在地图上做一次遍历从起点出发看能不能走到终点BFS/DFS 都能在多项式时间内解决。但多智能体系统的状态空间是所有智能体位置的联合——每一个智能体可能位于 V 个位置之一K 个智能体就有 V 的 K 次方种联合状态。算一笔账你就明白了一张 20x20 的网格地图有 400 个格点10 个智能体联合状态数就是 400^10约等于 1.1x10^26。这个数字比地球上所有沙子的数量还大很多个量级。就算每秒钟能评估一百万个状态也需要 3 万年才能穷举完。所以暴力枚举联合状态空间的路子天然只适用于 2~3 个小规模场景工业场景想都不要想。问题的复杂度和模型的离散化方式直接相关。我采用的是最经典的“时间膨胀图”模型把地图复制 T 份每一份对应一个时间步智能体在相邻时间层之间移动或停留碰撞约束变成跨层的一致性约束。这个模型有个好处——把“时空联合”这个问题拆成了图上的路径问题很多图论算法能直接套用。代价是图规模膨胀了 T 倍。2.2 判定问题的形式化描述为了让后面的算法讨论严谨一点给一个形式化定义。输入是一个无向图 G(V, E)K 个智能体每个智能体 i 有起点 s_i 和目标点 t_i时间上限 T。时间离散化每个时间步内智能体可以做一次移动到相邻顶点或者停留原地不动。需要满足两类约束顶点约束——任意时刻任意顶点最多被一个智能体占据边约束——任意两个智能体不能在同一个时间步内沿同一条边相向而行A 从 u 走向 vB 从 v 走向 u这会在边中间撞上。问是否存在 K 条从 s_i 到 t_i、长度不超过 T 的轨迹满足全部顶点和边约束这个判定问题在离散时间模型下是 NP-hard 的。工程上不需要追求完美算法只需要在绝大多数实际场景下能快速给出可靠答案即可。Agent-Reach 的定位就是这个不追求最坏情况的优雅算法追求的是“常见场景 95% 在秒级内出结果极端场景能声明自己算不动”。2.3 Agent-Reach 选择的工程路线约束搜索多智能体路径问题的经典算法路线有三条我分别评估过这里直接说结论。第一条是联合空间搜索联合状态 BFS/A*。逻辑最简单把 V^K 个联合状态当成一张大图在上面搜目标状态。但这张图太大了刚才算过20x20 地图塞 10 个智能体就有 10^26 个状态实际只能跑通 2~3 个智能体的玩具场景。PASS。第二条是 SAT/SMT 编码。把“存在一组满足时空约束的轨迹”编码成布尔可满足性问题交给 Z3 之类的求解器。这个方案在小规模、离线场景下效果很好求解器背后的 CDCL 算法相当强大。但引入重型求解器依赖实时性不可控而且在 30 个智能体以上的规模编码本身的布尔变量数就非常吓人。Agent-Reach 早期原型试过 Z3实测 10 个智能体 10x10 地图就要好几秒后面直接弃了。第三条是约束搜索Conflict-Based SearchCBS 思路。CBS 的核心思想是“分而治之”低层为每个智能体单独做带约束的单智能体搜索不考虑其他智能体高层检测所有智能体路径之间的冲突每发现一个冲突就对冲突双方中的一个施加时空约束然后重新搜索对应智能体的路径。如此反复直到所有路径之间没有冲突。CBS 的最坏情况依然是指数级但实际场景中通常只需要几十到几百次迭代就能收敛。它不需要引入大型求解器依赖纯搜索算法可以手工实现每一轮迭代的中间结果都可解释、可调试。Agent-Reach 最终选了这条路线。工程角度的理由有三个一是不依赖外部求解器部署轻量二是约束机制天然支持“部分失败”的局部重规划三是中间过程可以直接可视化运营人员能看懂系统为什么判定不可达。3. 实操从零实现一个 Agent-Reach 判定器3.1 输入建模与时间上限的设置先解决三个输入问题地图怎么表示、智能体怎么描述、时间上限 T 怎么定。地图在我的实现里用二维网格#表示障碍物.表示可通行。这个模型最简单也最容易和各种栅格地图、占据地图打通。如果你的场景是路网拓扑比如仓库巷道、道路网络可以把网格换成带权图核心算法不用变只要把“四方向邻居”改成“图邻居”就行。智能体描述就是一个三元组(起点, 终点, 优先级)。优先级在基础版里不用但我在后面优化时会用到——先规划高优先级、曼哈顿距离远的智能体能显著减少高层冲突迭代次数。时间上限 T 的设置是最容易出错的地方。T 太小明明有解却判定不可达T 太大时间膨胀图的规模线性膨胀搜索空间暴涨。我的经验公式是T max_i(曼哈顿距离(s_i, t_i)) * 1.5 5这个公式的含义是以最远智能体的朴素最短路径为基准加上 50% 的拥堵裕量再额外加 5 步用于处理局部绕行。实测下来这个基准值在大多数仓储 AGV 场景下足够宽松。如果你发现判定结果频繁“不可达”但人工判断可行优先检查 T 是不是给得太紧了。3.2 低层搜索时空 BFS单智能体的带约束搜索是整个系统的基础。注意这里不是在地图上做 BFS而是在“时间膨胀图”上做 BFS——状态是(x, y, t)三元组t 从 0 递增到 T。这样天然支持时间维度的约束禁止某个智能体在某个时刻进入某个顶点顶点禁令或者禁止它在某个时刻经过某条边边禁令。约束用集合表示分两类存储顶点禁令(x, y, t)和边禁令(x1, y1, x2, y2, t)后者含义是“禁止在 t 时刻从 (x1,y1) 移动到 (x2,y2)”。为什么要把它们分开因为顶点冲突和边冲突是两类完全不同的物理情况在高层冲突检测和低层搜索过滤时处理逻辑都不一样。时空 BFS 的伪代码思路从(sx, sy, 0)出发每个状态扩展出“原地等待 四方向移动”五种后继只要(nx, ny, t1)不落在顶点禁令里且(x, y) - (nx, ny)这条边不在边禁令里就入队。第一次搜索到目标点时即可提前返回不需要搜满所有 T 步——因为到达目标点后可以原地等待到 T不会产生新的冲突。3.3 高层冲突消解CBS 简化实现低层只负责单智能体找路根本不考虑其他智能体所以多智能体之间的路径必然有冲突。高层要做的是检测所有路径的两两冲突发现一个就分支对其中一个智能体施加约束重新搜索直到所有路径都无冲突。两个关键点要展开讲。冲突检测要覆盖两类。顶点冲突很容易理解同一时刻两个智能体出现在同一坐标。很多人会漏掉边冲突智能体 A 在 t 时刻从 (1,0) 走向 (1,1)智能体 B 在同一时刻从 (1,1) 走向 (1,0)它们在格子之间的边中间相撞。这种冲突在窄巷道、单行通道场景里非常致命检测时一定要把“相向而行”这种情况单独拎出来判。分支策略直接影响收敛速度。基础 CBS 是发现冲突后分别对两个智能体加约束形成两个分支每个分支都压入搜索栈。这里有两个工程化优化第一是优先扩展“冲突次数更少”的分支冲突计数是路径上所有冲突对的数量这能引导搜索树往低冲突方向走第二是加 k-swap 约束——两个智能体在相邻格点之间互换位置是一种经典死锁模式普通 CBS 会在这种对称冲突上反复横跳直接禁掉“互换”这一步能省掉大量无效迭代。3.4 代码Agent-Reach 核心判定器这是我在原型阶段使用的完整核心实现语言是 Python逻辑上可以直接跑通。生产环境换成 C/Rust 或者上并行优化核心结构不用动。from collections import deque from copy import deepcopy DIRS [(0, 1), (0, -1), (1, 0), (-1, 0)] def cell_valid(grid, x, y): return 0 y len(grid) and 0 x len(grid[0]) and grid[y][x] ! # def single_agent_bfs(grid, start, goal, constraints, max_t): # constraints 是集合元素两种 # v: (x, y, t, v) 顶点禁令 # e: (x1, y1, x2, y2, t, e) 边禁令 v_bans {(x, y, t) for (x, y, t, _type) in constraints if _type v} e_bans {(x1, y1, x2, y2, t) for (x1, y1, x2, y2, t, _type) in constraints if _type e} sx, sy start gx, gy goal q deque([(sx, sy, 0)]) parent {(sx, sy, 0): None} while q: x, y, t q.popleft() if (x, y) (gx, gy): path [] state (x, y, t) while state is not None: path.append((state[0], state[1])) state parent[state] return path[::-1] if t max_t: continue moves [(x, y)] [(x dx, y dy) for dx, dy in DIRS if cell_valid(grid, x dx, y dy)] for nx, ny in moves: nt t 1 if (nx, ny, nt) in v_bans: continue if (x, y, nx, ny, t) in e_bans: continue state (nx, ny, nt) if state not in parent: parent[state] (x, y, t) q.append(state) return None def extend_to(path, max_t): p list(path) if len(p) max_t 1: p.extend([p[-1]] * (max_t 1 - len(p))) return p def detect_conflict(paths, max_t): ext_paths [extend_to(p, max_t) for p in paths] # 顶点冲突 pos_owner {} for i, p in enumerate(ext_paths): for t, (x, y) in enumerate(p): key (x, y, t) if key in pos_owner: return (pos_owner[key], i, (x, y), t, v) pos_owner[key] i # 边冲突相向而行 for i in range(len(ext_paths)): for j in range(i 1, len(ext_paths)): for t in range(max_t): a1, a2 ext_paths[i][t], ext_paths[i][t 1] b1, b2 ext_paths[j][t], ext_paths[j][t 1] if a1 b2 and a2 b1: return (i, j, (a1, a2), t, e) return None def agent_reach(grid, agents, max_t, max_nodes10000): # agents: [(start, goal), ...] # 返回: (True, nodes) 可达 # (False, nodes) 不可达 # (None, nodes) 计算量超限无法判定 n len(agents) start_cons [set() for _ in range(n)] stack [start_cons] nodes 0 while stack: cons stack.pop() nodes 1 if nodes max_nodes: return None, nodes paths [] ok True for i, (start, goal) in enumerate(agents): p single_agent_bfs(grid, start, goal, cons[i], max_t) if p is None: ok False break paths.append(p) if not ok: continue conflict detect_conflict(paths, max_t) if conflict is None: return True, nodes a, b, where, t, ctype conflict if ctype v: x, y where for ag in (a, b): new_cons deepcopy(cons) new_cons[ag].add((x, y, t, v)) stack.append(new_cons) else: # e (x1, y1), (x2, y2) where new_cons deepcopy(cons) new_cons[a].add((x1, y1, x2, y2, t, e)) stack.append(new_cons) new_cons deepcopy(cons) new_cons[b].add((x2, y2, x1, y1, t, e)) stack.append(new_cons) return False, nodes代码核心就三个函数single_agent_bfs做低层时空搜索detect_conflict做两两冲突检测agent_reach做高层约束树 DFS。整个实现一百行出头没有外部依赖纯标准库。这个版本的定位是“可达性判定”不是“最优路径搜索”所以高层用的是 DFS找到一个可行解就返回 True不需要搜索全部约束树。有一点要特别说明max_nodes参数是我在生产环境里加的保险阀。因为最坏情况下 CBS 的搜索树可能爆炸与其让系统挂在那里跑十分钟不如在 10000 个节点没找到解时返回None判定未决让上层决定是扩大 T 再试还是直接放弃这个任务组合。判定为“不可达”和“判定未决”在工程上是完全不同的两件事前者说明无解后者说明算力不够。4. 实测结果与性能调优4.1 基准测试不同规模下的判定耗时我在一台普通的 8 核 i7、16GB 内存的笔记本上跑了几个典型场景Python 3.10 单进程。地图全部是随机生成的无障碍网格加随机障碍物智能体起点终点随机分布使用前文提到的 T 估算公式。地图规模智能体数障碍物占比时间上限 T判定耗时迭代节点数结果10x10210%224ms5可达20x20520%3888ms47可达30x301025%58690ms320可达50x501530%902.8s1200可达50x502030%1006.1s3500可达50x503030%120超限10000判定未决这个结果很直观地说明了 CBS 路线的行为特征智能体数量是决定性因素。从 15 个到 20 个耗时翻了一倍多从 20 个到 30 个直接超出节点上限。地图大小本身反而没那么敏感——50x50 地图上的 15 个智能体和 30x30 地图上的 10 个智能体耗时差距远小于智能体数量的差距。有一个数据很反直觉10x10 地图 2 个智能体居然要 4ms而不是更少。主要开销在 Python 的集合计算和深拷贝上换成 C 这个场景应该在微秒级。判定器的瓶颈早期不在算法本身而在工程实现的常数因子。4.2 决定性能的三个关键因素从实测数据反推我总结出影响性能的三个决定性因素。智能体数量是第一位的因为每增加一个智能体约束树的冲突组合数呈二次方增长两两冲突检测的复杂度是 O(K^2)而每个冲突分支又会递归展开。我在做优化时优先控制这个变量能合并任务就合并任务能减少参与判定的智能体数量就绝不评估多余的智能体。地图连通结构是第二位的。障碍物不是均匀分布的如果地图中央有一个狭窄的瓶颈通道所有智能体都要挤一条路冲突大概率集中在这个瓶颈上约束树会围绕瓶颈节点疯狂分支。这时候地图层面可以做“区域抽象”把连通分量压缩成区域图先在区域级别做可达性粗筛再在格点级别精算。这个分层策略在 300 台 AGV 级别的仓库里几乎是必须的。时间上限 T 是第三位的。T 增大搜索深度线性增加每一个智能体的时空 BFS 状态数就翻倍时间膨胀图的总状态数按指数级放大。所以 T 要设置得“宁紧勿松”先按公式算一个基准值如果判定结果为“可达”但路径规划器总在超时边缘再把 T 适当放宽如果判定结果“不可达”先试试把 T 放大 20%再看结果的稳定性。4.3 三个真实有效的优化手段第一个是连通性预检。这是最容易做、收益最明显的一步。在跑多智能体判定之前先为每个智能体做一次单智能体 BFS——如果某个智能体连自己的目标点在静态地图上都到不了整组任务直接判定不可达根本不用跑 CBS。另外如果两个智能体的起点和目标点在同一个连通分量里它们的路径无论如何不会跨越区域边界高层冲突检测可以只针对同一连通分量内部的智能体进行。这个优化在包含多个孤立区域的地图上能省掉大量无效搜索。第二个是 k-swap 约束。我在 3.3 节已经提到了两个智能体在相邻格点互换位置是最常见的对称死锁。具体现象是A 从 a 到 bB 从 b 到 a它们的路径在每一时刻都刚好错开但在边中点相撞。CBS 会对这个冲突反复交替加约束陷入典型的“来回拉扯”。解法是检测到这种互换冲突时直接在两个智能体的约束上同时加“禁止走这条边”一步到位搜索树立刻收敛。第三个是优先级排序。CBS 的搜索顺序会影响节点数但对最终的“有无解”判定影响不大不过在“判定未决”的场景里先规划曼哈顿距离长的智能体可以让低层搜索更早找到长路径长路径对短路径的约束更明确高层分支次数明显下降。实测这个简单策略能把 20 个智能体的判定耗时从 6.1s 压到 3.9s 左右代价只是按距离排个序。5. 常见问题与排查技巧实录5.1 可达性判定问题速查表做了这么久的多智能体判定我整理出一张高频问题表适合直接“抄作业”。症状可能原因排查步骤解决方案判定不可达但人工判断明显可行时间上限 T 设太小把 T 放大 20%~50% 重测用曼哈顿距离加上拥堵裕量重估 T小地图秒出大地图卡死地图存在狭窄瓶颈通道统计各格点的路径穿过频率区域抽象分层判定搜索树不断分支越来越慢对称冲突没有处理观察冲突是否总在两个智能体间反复出现加 k-swap 约束判定成功实际执行中仍堵住执行偏差/时序抖动检查真实位置与规划轨迹的偏差在规划阶段加时间缓冲temporal buffer返回“判定未决”搜索节点超过 max_nodes确认是否只是算力不够而不是无解提高 max_nodes 或优化约束剪枝这张表里最后一条我特别提醒很多团队把“判定未决”直接当成“不可达”处理这是有风险的。区别在于判定未决时扩大算力或放宽 T可能会变成可达而真正的不可达在扩大算力后仍然不可达。生产系统里一定把None和False分开处理否则会误杀一大批实际可行的任务。5.2 两个印象最深的坑第一个坑是边冲突检测的遗漏。早期版本的detect_conflict只检查了顶点冲突没检查相向而行的边冲突。结果一个双车巷道场景里判定器返回“可达”实际跑起来两台 AGV 在巷道中间迎面停住死锁。当时排查了大半天最后把路径逐帧打出来才发现问题。修复方式就是加那段“相向而行”的检测代码之后所有边冲突都能被正确识别。这个案例我印象极深——边冲突在多车道开放地图里不重要但在窄巷道、单行通道里就是致命的。第二个坑是 T 值过松导致的“伪不可达”。有一回一个场景断断续续判定不可达耗时却高达十几秒明显是搜索树膨胀了。我检查约束树发现智能体 A 被要求绕开某个区域后它的路径长度达到了 T-1刚好卡在超时边缘导致后续所有分支都在超时约束上反复搜索。这就是 T 设太大带来的副作用——搜索深度太深反而把简单问题搞复杂了。后来我把 T 的估算公式从“曼哈顿距离 * 2 5”调成“曼哈顿距离 * 1.5 5”这个现象基本消失。5.3 实操心得判定失败后怎么向业务层汇报判定器不只是返回一个布尔值就完事了真实系统里它要给上层提供“决策依据”。我的做法是让agent_reach返回一个结构体是否可达、耗时、搜索节点数、冲突最多的位置 Top 列表、被限制最严重的智能体编号。这样当运营人员问“为什么这个订单不可达”时不是得到一句“系统说的”而是能看到“12 号 AGV 与 27 号 AGV 在 A3 巷道反复冲突 8 次”。这个设计一开始只是为了让我的调试过程方便一点后来发现业务价值才是最大的——它能指导人工干预是调整任务组合还是优化地图动线还是给某台 AGV 重新分配任务。判定器输出的中间信息是调度系统改进方向的导航仪。6. Agent-Reach 的落地场景与扩展思路6.1 仓储 AGV 与自动化产线调度仓储场景是 Agent-Reach 最典型的落地场景。大型仓库里几百台 AGV 同时运行每天产生几十万个任务组合如果每个任务都直接丢给路径规划器去试计算资源和异常处理的压力都扛不住。正确的做法是任务分配阶段先做一轮可达性预筛把“明显送不到”的任务组合直接过滤掉。我实际做过的一个项目里调度系统每天产生未完成订单我们上线通用可达性预筛模块后这类问题的概率直接降了六成。还有一点当一个 AGV 故障退出周围任务需要重新分配时可达性判定能立即给出“哪些任务需要移交给同伴”的清单而不是等路径规划一个个去试错。6.2 自动驾驶路口的通行权调度多智能体可达性判定在自动驾驶领域有一个很有意思的变体交叉路口通行权分配。每个方向的车流是一组智能体路口是共享资源问题变成“给定当前各路口的车辆集合能否在 T 秒内让所有车辆无碰撞通过路口”。这里的地图不是网格而是车道拓扑图智能体的数量动态变化。这个场景里 Agent-Reach 的价值是“快速响应”路口状态每秒都在变判定器需要在几十毫秒内给出下一轮通行方案是否可行的结论。CBS 路线在这里依然适用——只要把低层搜索的地图换成带方向的车道图把“停留”变成“在等待区排队”算法骨架基本不用动。我在仿真环境里验证过 40 辆车通过一个四向路口的判定场景8 秒内能给出结果这个速度对实时调度来说勉强够用配合 C 实现可以压缩到 1 秒内。6.3 游戏 AI 与大世界寻路游戏 AI 和机器人调度的区别是智能体数量可以轻松上千但地图通常是静态的、可控的。RTS 游戏里几百个单位要同时移动到某个区域如果逐单位寻路再全局冲突消解计算量会爆炸。Agent-Reach 在游戏场景里的角色是“预筛”先判定这个大规模移动任务在当前地图疏散条件下可行性如何如果判定结果不好就直接降低移动请求的等级或者错峰下发。这个场景有个独特的优化游戏地图的连通性结构通常是手工设计且有语义区域的可以直接复用区域图做分层判定不需要重新建模。我在一个开放世界原型里试过为 500 个 NPC 做任务可行性预筛加上区域分层后判定耗时从几十秒压到了 1 秒内效果非常明显。6.4 动态环境下的再判定现实世界的环境是动态的AGV 故障挡路、临时禁行区域、新障碍物出现。一旦环境变化之前的判定结果随时可能失效。Agent-Reach 作为独立判定模块天然支持“增量再判定”——环境变化时只需要把受影响的智能体路径重新搜索不需要整组任务全部重跑因为 CBS 的约束树和各个智能体的路径是独立的。这个增量能力是 CBS 路线相对 SAT/SMT 方案的核心优势。SAT/SMT 方案在环境变化时几乎要从头重新编码求解而 CBS 可以复用未受影响的智能体路径只对受影响的智能体重搜。我在仓储项目里实测局部环境变化时的增量判定耗时只有完整重判定的 30% 左右。最后分享一个我在这个项目里反复验证过的体会可达性判定不是一个听上去很“硬核”的技术离了它调度系统也能跑但只要加了这一层系统就能从“被动等死锁”变成“主动拒单”从“路径规划器超时”变成“调度器明明白白告诉你为什么不能走”。这层前置的、确定性的判断是调度系统从“能用”走向“好用”的很关键一步。如果你正在做相关系统建议先把判定层补齐哪怕只是 ConvergeCBS 的简化实现收益都会很明显。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑