想象你是一家火爆餐厅的老板,后厨出菜口像流水一样涌出菜品,十来个传菜员端着热腾腾的盘子穿梭在几十张餐桌之间。你不允许他们撞在一起把菜打翻,又希望每道菜都能以最快速度送到客人面前。如果只靠喊,场面会乱成一锅粥;如果让每个人凭感觉走,又会有人绕远路、有人堵在过道里。你需要一套聪明的规则——这就是 AGV 调度优化要做的事。 在现代智慧仓库里,传菜员换成了自动导引车(AGV),餐桌换成了货架与拣货站,菜品换成了订单包裹。调度算法就是那位看不见的“交通指挥官”:它决定哪台车去执行哪个任务、走哪条路、什么时候让行、遇到突发状况如何重新安排。本文会带你像看餐厅后厨一样,看懂 AGV 调度优化的全流程。

岗位关联

学会 AGV 调度优化,你就掌握了智能仓储中“多机器人协同作战”的顶层设计能力,这是 AI 技术从实验室走向物流生产线最直接、回报率最高的切入点之一。

目录
  1. 可视化演示
  2. AGV系统基础
  3. 任务分配策略
  4. 路径规划方法
  5. 冲突消解机制
  6. 实时重调度
  7. 系统协同架构
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态展示AGV调度问题定义、任务分配与调度策略、路径规划与冲突消解、死锁预防与实时重调度机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

AGV系统基础

餐厅要开业,你首先得清楚自己的传菜员是什么样的:他们跑多快、一次端几盘菜、在哪充电、过道多宽。AGV 系统也一样,硬件组成、运行环境、调度目标三件事不摸清,调度就是空中楼阁。

AGV(Automated Guided Vehicle,自动导引车)是仓储物流里的移动机器人,靠磁条、二维码或激光雷达沿着预设路径行驶。它的硬件包括车体、驱动轮、导航传感器、安全避障雷达与车载控制器,相当于传菜员的“腿、眼睛和大脑”。而运行环境要提前规划出车道、交叉口、充电区和装载区——就像餐厅要画好桌椅摆放图,才能让传菜路线合理。

调度目标通常有三个:最大化吞吐量(单位时间完成的订单数)、最小化平均任务完成时间、保证不碰撞不堵塞。其中“利用率”是衡量车队是否“人尽其才”的关键指标:

就像你不会让一个服务员闲着刷手机、也不会让他忙到累趴——利用率就是那张“是否人尽其才”的考勤表。调度系统的第一步,就是先想明白团队的家底和目标。

U=TworkTtotal\displaystyle U = \frac{T_{work}}{T_{total}}
利用率 = 有效干活时间 / 总时间。数值越高,说明车队越“物尽其用”,但过高也意味着没有余量应对突发。
  1. 利用率 U表示一台 AGV 真正搬运货物的时间占比,是衡量调度质量的基础指标。
    U\displaystyle U
  2. 有效工作时间 T_workAGV 执行取货、送货、卸货的累计时长,相当于传菜员端盘子的时间。
    Twork\displaystyle T_{work}
  3. 总时间 T_total统计周期内的全部时间,包含充电、等待、空闲,对应服务员从上班到下班的全时长。
    Ttotal\displaystyle T_{total}

任务分配策略

领班面前堆着一摞新订单,五个服务员有的刚送完菜闲下来、有的还在后厨等餐。把哪张单子派给谁?这就是任务分配。只靠“谁近给谁”的直觉,很快会出现“忙的忙死、闲的闲死”。

物流场景中,订单到达是离散随机的,每台 AGV 的位置和状态各不相同。调度系统需要在每个决策时刻把任务指派给合适的车辆。工业界常用“优先级评分 + 匹配算法”的组合:先给任务打分,再用贪心、匈牙利算法或拍卖机制完成分配。打分时考虑等待时长、紧急程度和是否有关联订单约束。

一个经典的优先级评分公式如下,用两个维度综合判断“谁更该先做”:

领班不是只把单子塞给最近的传菜员,他还会看“这桌客人等了多久”和“谁回来顺路”。加权派单的智慧,就是在多目标之间找到平衡,让整个餐厅的翻台率最高。

Pi=w1×τi+w2×Di\displaystyle P_i = w_1 \times \tau_i + w_2 \times D_i
优先级 = 等待权重 × 已等待时长 + 距离权重 × 到取货点距离。等得越久、离得越近的任务,越优先执行。
  1. 任务优先级 P_i第 i 个任务的调度优先级得分,数值越大越先被派单。
    Pi\displaystyle P_i
  2. 等待时长 τ_i任务从下单到现在已等待的时间,等得越久越“着急”,类似客人催单。
    τi\displaystyle \tau_i
  3. 距离成本 D_i当前空闲 AGV 到取货点的移动距离,越近执行成本越低。
    Di\displaystyle D_i
  4. 权重系数 w₁ 与 w₂用于平衡“着急程度”和“路程成本”两个目标的相对重要性。
    w1×τi+w2×Di\displaystyle w_1 \times \tau_i + w_2 \times D_i

路径规划方法

传菜员端着热汤,不能穿过客人头顶走。他要在桌椅之间找一条不碰不撞、又快又稳的路。地图画得准、搜索算法好,才能少绕远路、少惊扰客人。

路径规划分两步:地图建模与路径搜索。地图建模常用栅格地图(把仓库切成小方格,标出障碍物)或拓扑图(用节点和边表示通道关系);路径搜索最经典的是 A* 算法,它在启发式函数引导下高效寻找最短路径,而不是傻乎乎地把每条路都试一遍。

A* 的核心是一条代价公式:

就像传菜员先目测“直走再拐弯”有多远,再结合“那边有客人在起身”的实时信息综合选路——A* 就是那套“先粗估、再细算”的寻路直觉,而且它用数学保证了最短路。

f(n)=g(n)+h(n)\displaystyle f(n) = g(n) + h(n)
A* 的总代价 = 从起点到当前点已花代价 + 从当前点到终点的乐观估计。每次选总代价最小的节点扩展,保证找到最短路径。
  1. 当前节点 n搜索过程中正在评估的某个地图格点,好比传菜员正站在某个餐桌旁。
    n\displaystyle n
  2. 真实代价 g(n)从起点走到该节点已经消耗的移动距离或时间。
    g(n)\displaystyle g(n)
  3. 启发估计 h(n)从该节点到终点的“乐观估计”距离,常用曼哈顿距离计算,它保证不低估,A* 才能找到最优解。
    h(n)\displaystyle h(n)
  4. 总代价 f(n)两项相加后,算法每次优先展开 f 最小的节点,逐步“逼近”终点。
    f(n)=g(n)+h(n)\displaystyle f(n) = g(n) + h(n)

冲突消解机制

两个传菜员在窄过道迎面相遇,都端着菜,谁退谁让?如果俩人同时左右闪,反而会“鬼打墙”。好的餐厅会定下规矩:端大菜的先走、空手的让路。AGV 车队在路上也需要这样的“社交礼仪”。

多台 AGV 共用通道网络时,冲突不可避免。常见的冲突类型有三种:迎面相遇、同向追尾、十字交叉。消解策略也分三层:等待让行最简单,适合短暂冲突;局部绕行让车辆改走邻近通道,牺牲一点点路程换取整体通顺;如果冲突扩散成死锁——多车互等、谁也动不了——就需要更复杂的死锁检测与恢复机制。

等待让行的等待时间可以粗略估算:

餐厅里“你先过,我等你”的默契,在 AGV 世界里被算法量化成一张等待时间表。有了它,机器人就不会在过道里“鬼打墙”,也不会因为谁都不让步而僵持到天荒地老。

twait=δv1+v2\displaystyle t_{wait} = \frac{\delta}{v_1 + v_2}
等待时间 = 两车到冲突点的距离差 ÷ 相对靠近速度。高优先级车越快通过,低优先级车的等待越短。
  1. 预计等待时间 t_wait低优先级 AGV 在让行时需要原地等待的时长。
    twait\displaystyle t_{wait}
  2. 相对距离差 δ两辆 AGV 分别到冲突点的距离之差,差距越小越需要及时让行。
    δ\displaystyle \delta
  3. 速度之和 v₁ + v₂两车相互靠近的速度,决定了高优先级车清空冲突区需要多久。
    v1+v2\displaystyle v_1 + v_2

实时重调度

客人临时加菜,或者地上一摊水挡住了最快的传菜路线。一个合格的领班绝不会按原计划傻等,而是立刻调整传菜顺序和路线。真实的仓库每天都在上演这种“计划赶不上变化”。

现实中,订单会取消、货架会被挡住、AGV 会故障。调度系统必须能快速响应异常。触发重调度的典型事件包括:新订单插入、订单取消、任务超时、AGV 离线、通道拥堵。处理方式分为两级:局部重规划只修改受影响车辆的路径,成本低、响应快;全局重调度则把剩余任务和所有车辆重新匹配一次,通常用“滚动时域”来控制——每过一小段时间窗口,就把全局重新算一遍。

是否值得重算,要有一个判断门槛:

领班只有在“再等下去要误大事”时才重排全场——阈值调太小会手忙脚乱,调太大又反应迟钝。滚动时域就是“每隔几分钟看一次全局,没事不折腾,有事立刻办”。

ΔT=Tnew−Tplan>Tthreshold\displaystyle \Delta T = T_{new} - T_{plan} > T_{threshold}
只有当新方案相比原方案的完成时间偏差超过阈值时,才触发重调度。阈值太小会频繁抖动,太大则反应迟钝。
  1. 新计划完成时间 T_new重新规划后任务预计完成的时间。
    Tnew\displaystyle T_{new}
  2. 原计划完成时间 T_plan重调度之前已排定的预期完成时间。
    Tplan\displaystyle T_{plan}
  3. 时间偏差阈值 T_threshold可容忍的延误上限,超过它才允许“推倒重来”。
    ΔT=Tnew−Tplan>Tthreshold\displaystyle \Delta T = T_{new} - T_{plan} > T_{threshold}

系统协同架构

一家大餐厅若只靠领班一个人大喊大叫,肯定顾不过来;若每个服务员完全各干各的,又会频繁撞车。真正的解法是分层协同:总控台定大方向,基层处理细节。

AGV 调度系统的架构有三种典型模式:中央集中式由调度中心掌握所有车辆与任务的全局视图,能算出全局最优,但中心一旦故障全系统瘫痪;分布式让每台 AGV 自行协商,鲁棒性好、易扩展,但很难保证全局最优;分层混合式是当前工业主流——上层中央调度负责任务分配和宏观路径,下层 AGV 控制器负责局部避障与队列保持,通信一般用 WIFI 或 5G,交换位置、状态、任务和地图四类数据。

分层架构的最终效果,可以用吞吐量来度量:

就像“中央厨房 + 前台自主”的餐厅,AGV 系统也不能把所有决策都压在一个节点上。层与层分工明确,既高效又抗风险——这样的车队,才能在大促洪峰中稳稳接住每一张订单。

Q=NtasksTwindow\displaystyle Q = \frac{N_{tasks}}{T_{window}}
吞吐量 = 时间窗口内完成的任务数 ÷ 窗口时长。它是衡量整套系统协同效率的“总成绩单”。
  1. 系统吞吐量 Q单位时间内整个仓库完成的任务数量,是调度系统的核心 KPI。
    Q\displaystyle Q
  2. 完成任务数 N_tasks在统计窗口内实际完成的订单或搬运任务总数。
    Ntasks\displaystyle N_{tasks}
  3. 时间窗口 T_window统计采用的时长区间,可以是 1 小时、1 班次或 1 天。
    Twindow\displaystyle T_{window}

AI 应用场景

电商大促仓的智能调度

阶段:智能决策 → 实时任务分配与路径调度

解决的问题:传统人工叉车模式下,大促订单洪峰让调度靠经验、响应慢,仓库通道经常堵成“停车场”,出库时效大幅下滑。

具体案例:华东某电商仓在双十一期间将 AGV 从 200 台增至 500 台。AI 调度系统把订单按时效分档,加急订单优先分配;结合 SKU 热度,把热卖品区域的 AGV 密度动态调高;地图上实时预测拥堵路段并引导车辆绕行。最终出库时效提升 35%,AGV 相互等待时间下降 40%。

汽车总装车间线边物流

阶段:生产物流协同 → 拉动式配送调度

解决的问题:产线缺料停线损失每分钟数万元,传统定时配送和人工调度无法精确匹配生产节拍。

具体案例:某汽车总装厂将 AGV 调度系统与 MES 制造执行系统直连。工位按下“缺料按钮”后,AI 调度在 1 秒内把任务分配给距离最近且预计到达时刻最匹配的 AGV,路径规划自动避开物流主干道高峰期。导入后产线停线时间减少 60%,线边库存削减 30%。

Python 演示

python98 行
# -*- coding: utf-8 -*-"""AGV 调度模拟: 最近空闲优先 + BFS 路径 + 冲突等待"""from collections import deque  class AGV:    def __init__(self, agv_id, pos):        self.agv_id = agv_id        self.pos = pos        self.state = 'idle'        self.task = None        self.path = []     def assign(self, task, path):        self.task = task        self.path = path        self.state = 'busy' if path else 'idle'     def step(self):        if self.path:            self.pos = self.path.pop(0)            if not self.path:                self.state = 'idle'                self.task = None  class Task:    def __init__(self, task_id, pickup, dropoff, priority=1):        self.task_id = task_id        self.pickup = pickup        self.dropoff = dropoff        self.priority = priority  def manhattan(a, b):    return abs(a[0] - b[0]) + abs(a[1] - b[1])  def build_path(grid, start, goal):    """BFS 搜索最短路径, 返回格点列表"""    rows, cols = len(grid), len(grid[0])    q = deque([(start, [start])])    visited = {start}    while q:        (r, c), path = q.popleft()        if (r, c) == goal:            return path        for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):            nr, nc = r + dr, c + dc            if (0 <= nr < rows and 0 <= nc < cols and                    grid[nr][nc] == 0 and (nr, nc) not in visited):                visited.add((nr, nc))                q.append(((nr, nc), path + [(nr, nc)]))    return []  def run_simulation(grid, agvs, tasks):    """主循环: 分配任务 -> 预判冲突 -> 移动"""    pending = sorted(tasks, key=lambda t: -t.priority)    waiting = {a.agv_id: 0 for a in agvs}    tick = 0    while pending or any(a.state == 'busy' for a in agvs):        tick += 1        for agv in agvs:            if agv.state == 'idle' and pending:                task = min(pending, key=lambda t: manhattan(agv.pos, t.pickup))                full = build_path(grid, agv.pos, task.pickup)                full += build_path(grid, task.pickup, task.dropoff)[1:]                agv.assign(task, full)                pending.remove(task)        nxt = {a.agv_id: (a.path[0] if a.path else a.pos) for a in agvs}        ids = list(nxt.keys())        blocked = set()        for i in range(len(ids)):            for j in range(i + 1, len(ids)):                if nxt[ids[i]] == nxt[ids[j]]:                    blocked.add(ids[i])        for agv in agvs:            if agv.agv_id in blocked:                waiting[agv.agv_id] += 1            elif agv.state == 'busy':                agv.step()    return tick, waiting  if __name__ == '__main__':    grid = [[0, 0, 0, 0, 0],            [0, 1, 1, 0, 0],            [0, 0, 0, 0, 0],            [0, 1, 0, 1, 0],            [0, 0, 0, 0, 0]]    agvs = [AGV(0, (0, 0)), AGV(1, (0, 4))]    tasks = [Task('t1', (4, 0), (2, 4), 3),             Task('t2', (2, 0), (0, 2), 2),             Task('t3', (4, 4), (2, 2), 1)]    turns, waits = run_simulation(grid, agvs, tasks)    print('总耗时(tick):', turns)    print('AGV 等待次数:', waits)
目的:用 Python 实现一个微型 AGV 调度仿真——两台 AGV 在一个 5×5 的栅格仓库里执行三个搬运任务,采用“最近空闲优先 + BFS 最短路径 + 冲突等待”的策略,输出总耗时与等待次数,直观理解调度算法如何工作。
  1. task = min(pending, key=lambda t: manhattan(agv.pos, t.pickup))为每台空闲 AGV 挑选距离最近的待分配任务,这就是“贪心式就近派单”的实现。
  2. full = build_path(grid, agv.pos, task.pickup)用 BFS 在栅格地图上搜索一条去取货点的最短路径,仓库里的 1 表示障碍物。
  3. nxt = {a.agv_id: (a.path[0] if a.path else a.pos) for a in agvs}预判所有 AGV 下一步将到达的格点,相当于“提前看大家的脚往哪儿迈”。
  4. if nxt[ids[i]] == nxt[ids[j]]:发现两台 AGV 打算踏进同一个格子,这就是冲突预警信号。
  5. blocked.add(ids[i])让编号较小的 AGV 作为让行者,原地等待,模拟低优先级让行策略。
  6. waiting[agv.agv_id] += 1每发生一次让行就记录一次等待事件,最终用等待次数评估调度质量。

常见误区

误区“每台 AGV 装上激光雷达,能自己躲开障碍物,为什么还要中央调度系统?这不多此一举吗?”

正解单机避障只能看到自己“眼前”的障碍物,属于本能反应;中央调度掌握的是全局视野——它知道所有车的意图、任务和路线。就像每个传菜员都能看见眼前的客人,但依然需要领班统一派单,否则大家都会抄近路挤到一起。避障负责“不撞上”,调度负责“不拥堵”,两者缺一不可。

为何常见:混淆了“避障”(低层控制)与“调度”(高层决策)。传感器给人的直觉很直观,而调度的价值是隐性的——直到大促时所有车堵成一团才显现。

误区“任务来了,谁离得近就派谁去,这不就是最高效的吗?距离最短,成本最低啊。”

正解贪心就近会导致“马太效应”——近的 AGV 一直忙、远的永远闲。全局调度要考虑任务优先级、车辆预计完成时刻和充电需求。就像领班知道某个传菜员马上要送完手里这单,就会把顺路的新单子留给他,而不是让一个刚出门的服务员折返。贪心算法是局部最优,不是全局最优。

为何常见:直觉上“近=成本低”符合日常经验,但多机协同中“近”会引发后续不均衡,这种副作用隐藏在统计数据里,不易被直观感知。

误区“给每台 AGV 都规划最短路径,每台车都省时间,系统整体肯定最快。”

正解当所有车都抄最短路径时,同一条通道会挤成一团,冲突等待累计起来反而比绕路更慢。路径规划本质上是系统级的“流量管理”——为了让总体通畅,个别 AGV 走远路是值得的。就像高架堵车时,导航会让你改走地面绕行,虽然单程变长,但整体到达时间更短。

为何常见:单机视角的“最优”在系统视角下可能变成灾难。人的直觉容易忽略路径选择之间的耦合效应,也就是“拥堵的外部性”。

误区“调度系统启动后,按当天排好的计划运行就行,不用整天改来改去,改多了反而容易出bug。”

正解仓储现场是高度动态的:订单插队、货架被挡、AGV 电量告急、车轮打滑、网络抖动……任何意外都会让原计划失效。系统必须持续监测状态,当偏差超过阈值时触发重调度。就像传菜员中途被客人拉住问路,原本 30 秒的路线延迟也会被领班感知并重新安排,而不是等客人退菜才反应。

为何常见:把调度想成一次性“排班表”而不是“实时闭环控制系统”,低估了真实物理环境的不确定性。

面试题

Q1. AGV 调度要解决的核心矛盾是什么?

单选题 · easy

  • A.让单台 AGV 跑得更快
  • B.多车协同避免碰撞
  • C.追求吞吐且不碰撞← 正确答案
  • D.减少车辆维护成本

答案:C。AGV 调度的核心不是把某一台车调快,而是让整个车队在避免碰撞的前提下最大化吞吐量——就像领班要考虑的是整个餐厅的翻台率,而不是某个传菜员的步频。A 是单机视角,B 只说了“不碰撞”这一个约束,D 与调度的核心目标无关。

Q2. 任务优先级公式 P_i = w₁τ_i + w₂D_i 中,τ_i 表示什么?

单选题 · easy

  • A.AGV 到取货点距离
  • B.任务的紧急程度
  • C.任务已等待时长← 正确答案
  • D.货架的货物数量

答案:C。τ_i 在公式中代表任务从下达开始已经等待的时间,等得越久 τ_i 越大,优先级越高——相当于客人催单越久越要先上菜。D_i 才代表 AGV 到取货点的距离,B 和 D 都不是公式中的变量。

Q3. A* 算法中 h(n) 被称为什么?

单选题 · mid

  • A.实际代价函数
  • B.启发式估计函数← 正确答案
  • C.路径平滑因子
  • D.碰撞代价因子

答案:B。h(n) 是从当前节点 n 到终点的启发式估计,通常用曼哈顿距离计算,它是“乐观估计”——相当于传菜员先目测“直走再拐弯还有多远”。g(n) 才是从起点到 n 的实际代价,A 说的是 g(n),C、D 不属于 A* 的组成项。

Q4. 以下哪些属于 AGV 冲突类型?

多选题 · mid

  • A.迎面相遇冲突← 正确答案
  • B.同向追尾冲突← 正确答案
  • C.十字交叉冲突← 正确答案
  • D.电池电量不足

答案:ABC。AGV 共享通道时,典型冲突有三种:窄道迎面相遇、同向快慢不一导致追尾、交叉路口同时抢行,对应选项 A、B、C。电池电量不足是设备状态问题,不属于路径冲突,调度中一般通过充电任务规避。

Q5. “最短路径不一定最快”的主要原因是?

单选题 · mid

  • A.多条车汇聚致拥堵← 正确答案
  • B.最短路径计算更复杂
  • C.最短路径较为耗电
  • D.最短路径无法导航

答案:A。当多台 AGV 都选最短路径时,同一条通道会汇聚大量车辆,冲突等待时间反而超过绕路的时间——就像所有人都走一条捷径,捷径就变成了堵点。B、C、D 都不是核心原因,最短路径恰恰是计算最快、最省电的。

Q6. “死锁”在 AGV 调度中是指什么?

单选题 · hard

  • A.电池耗尽而停车
  • B.车辆陷入物理障碍
  • C.多车互等永不相让← 正确答案
  • D.调度网络中断宕机

答案:C。死锁是多台 AGV 各自占着通道、都在等对方先让路,形成循环等待的僵局,谁也无法前进——就像两个传菜员在窄过道面对面站着,都等对方侧身,结果谁都不动,直到有人打破僵局。A、B、D 都属于单点故障,不是“互相等待”的系统性僵局。

Q7. 实时重调度的触发条件包括?

多选题 · hard

  • A.订单临时被取消← 正确答案
  • B.货架倒塌堵塞通道← 正确答案
  • C.AGV 突发故障离线← 正确答案
  • D.温度小幅波动变化

答案:ABC。订单取消会让原任务失效、货架倒塌会阻断既定路径、AGV 离线会让已分配任务悬空——这三者都属于“计划赶不上变化”,需要立即触发重调度。温度小幅波动对室内仓库的 AGV 运行没有直接影响,不属于调度触发条件。

Q8. 负载均衡指标中,用于衡量忙闲不均程度的量是?

单选题 · easy

  • A.所有 AGV 的总工作量
  • B.最忙 AGV 的工作量
  • C.全部空闲 AGV 的数量
  • D.最忙与平均负载的比值← 正确答案

答案:D。负载均衡的核心是“忙闲是否均匀”,用最忙 AGV 的负载除以平均负载——比值越接近 1 说明越均衡,越大说明“忙的忙死、闲的闲死”。A、B 只描述绝对工作量,C 只看空闲数,都不能反映不均衡程度。

Q9. 分布式调度相对中央调度的优势是?

单选题 · mid

  • A.单点故障影响范围小← 正确答案
  • B.全局最优解更易求得
  • C.系统实现最简洁直观
  • D.完全不需要通信协作

答案:A。分布式调度没有唯一中心,一台车出问题不会让整个车队瘫痪,鲁棒性和扩展性更好——就像餐厅里领班临时不在,每个服务员也能按既定规则继续干活。全局最优恰恰是中央调度的强项,完全无通信的分布式系统在实践中几乎不存在。

Q10. 分层混合调度架构的特点有哪些?

多选题 · extreme

  • A.上层负责全局任务分配← 正确答案
  • B.下层负责局部避障响应← 正确答案
  • C.兼顾全局最优与实时性← 正确答案
  • D.完全放弃中央决策节点

答案:ABC。分层混合架构是工业主流——上层中央调度做任务分配和宏观路径规划,保证全局最优;下层 AGV 控制器做局部避障和队列保持,保证实时响应。这种“大权集中、小权下放”的组合既避免了中央瘫痪的致命风险,也避免了纯分布式的全局短视。D 恰恰是分层架构明确反对的。