3. 多工序约束表达

多工序排产的核心难点,不在于单个工序何时开始,而在于工序之间“谁等谁、谁和谁能同时做、做完之后要花多久才能进入下一台设备”。如果只把每道工序当成独立任务来排,得到的计划往往在时间上可行、在物理上不可行。本节围绕四类约束展开:工序先后关系、设备能力匹配、工序重叠与并行、转移时间与等待时间,并给出可直接落到模型里的表达方式。

一、工序先后关系:用有向约束而非“顺序号”表达

工序先后关系最容易被简化成“按工序号从小到大排”,但真实工艺路线中存在分支、合流和可选路径。更稳妥的做法是把工艺路线表达为有向无环图(DAG):节点是工序,有向边表示“前序完成后序才能开始”。对于同一工件的工序 O_ij(工件 i 的第 j 道工序),若存在工艺边 O_ij → O_i,j+1,则约束为:

start(O_i,j+1) ≥ end(O_ij) + transfer(O_ij → O_i,j+1)
end(O_ij) = start(O_ij) + duration(O_ij, M_k)

其中 transfer 是工序间转移时间,duration 依赖所选设备。注意:先后关系是“不早于”约束,不是“必须紧接”。如果强行写成等式,会把等待时间压成零,导致计划不可执行。因此先后关系应表达为不等式,等待时间由后续约束自然产生。

二、设备能力匹配:候选设备集合与加工时间矩阵

设备能力匹配要回答两个问题:某工序能在哪些设备上做?在不同设备上做多久?工程上通常用“候选设备集合 + 加工时间矩阵”表达。例如某工序 O_23 可在 M1、M3、M4 上加工,对应时间分别为 40、32、55 分钟。此时引入 0-1 分配变量 x(O_23, M_k),并满足:

Σ_k x(O_23, M_k) = 1                     (每道工序只选一台设备)
duration(O_23) = Σ_k x(O_23, M_k) · t(O_23, M_k)
start(O_23) ≥ end(前序) + transfer
同一设备上任意两工序不重叠

设备能力匹配不只是“能不能做”,还包括精度、模具、工装、人员资质等硬约束。建模时应把“不可用”直接排除在候选集合之外,而不是给一个很大的加工时间——后者会让求解器误以为“可以做但很慢”,从而产生看似可行、实际违规的方案。

三、工序重叠与并行:重叠量、并行分支与资源竞争

工序重叠指同一工件的相邻工序部分并行,常见于“分批转移”:前序完成一批后,后序即可开始,而不必等整批完成。设批量为 Q、转移批量为 q,则重叠可表达为:

start(O_i,j+1, 第1批) ≥ start(O_ij) + duration(O_ij) · (q / Q) + transfer
后续批次按 q 的节奏依次释放

并行则指不同工件或不同分支在同一时间段竞争同一设备。并行本身不违反工艺约束,但会触发设备占用约束。建模时要把“并行”与“重叠”分开:重叠改变的是同一工件内部的时序关系,并行改变的是设备上的排队关系。二者混在一起,容易出现“看起来能并行、实际设备冲突”的假计划。

多工序约束关系图:先后 · 能力 · 重叠 · 转移与等待 工件 A 工艺路线(DAG) A-O1 粗加工 M1/M2 · 40/48min A-O2 精加工 M3/M4 · 32/55min A-O3 检测 M5 · 18min 转移 5min 转移 3min 工件 B 分支与合流 B-O1 下料 M1 · 25min B-O2a 车削 M2 · 30min B-O2b 铣削 M4 · 36min B-O3 装配 M6 · 20min 转移 4min 转移 4min 设备占用与等待(示意) 0 60 120 min A-O1 M1 B-O1 M1 A-O2 M3 B-O2a M2 B-O2b M4 等待 等待 约束要素与建模含义 先后关系:start ≥ 前序 end + 转移时间 能力匹配:候选设备集合 + 加工时间矩阵 等待时间:设备被占用或前序未完成产生的空档 重叠/并行:分批转移 + 设备不重叠约束 关键不等式(同一工件 i,相邻工序 j → j+1) start(O_i,j+1) ≥ end(O_ij) + transfer(O_ij → O_i,j+1) end(O_ij) = start(O_ij) + Σ_k x(O_ij,M_k) · t(O_ij,M_k) 同一设备 M_k 上:start(O_b) ≥ end(O_a) 或 start(O_a) ≥ end(O_b) 等待时间 = 后序实际开始 − 前序结束 − 转移时间(≥ 0)

四、转移时间与等待时间:把“空档”显式建模

转移时间是从前序工序结束到后序工序可开始之间的物理搬运、冷却、检验或换模时间。它通常与设备对、工件、批次有关,不能简单用一个全局常数代替。等待时间则是后序实际开始时间减去“前序结束 + 转移时间”的差值,反映的是设备排队、人员未到位或前序延迟造成的空档。

建模时建议把等待时间作为派生量而非独立变量:

wait(O_i,j+1) = start(O_i,j+1) − end(O_ij) − transfer(O_ij → O_i,j+1)
wait(O_i,j+1) ≥ 0

这样做的价值在于:当排产结果出现大量等待时,可以定位是设备能力不足、转移时间过长,还是前序工序本身延迟。若把等待时间直接写成固定值,就失去了这种诊断能力。

五、一个可执行的教学示例

假设工件 A 的工艺路线为 A-O1(M1 或 M2,40/48 分钟)→ A-O2(M3 或 M4,32/55 分钟)→ A-O3(M5,18 分钟),转移时间分别为 5 分钟和 3 分钟。若选择 M1 和 M3,则 A-O1 在 0 时刻开始,40 分钟结束;A-O2 最早可在 45 分钟开始,若 M3 空闲则 45 分钟开始、77 分钟结束;A-O3 最早 80 分钟开始、98 分钟结束。若 M3 在 45 分钟时仍被工件 B 占用,则 A-O2 需等待,等待时间等于 M3 释放时刻减去 45 分钟。

这个例子说明:先后关系决定“最早能开始”,设备能力决定“用哪台、做多久”,设备占用决定“实际何时能开始”,转移时间决定“中间必须留出的空档”。四类约束缺一不可。

建模检查清单:① 每道工序是否有明确的候选设备集合与加工时间?② 先后关系是否写成不等式而非等式?③ 转移时间是否按设备对/工件分别定义?④ 等待时间是否作为派生量可观测?⑤ 重叠与并行是否分别处理,且设备不重叠约束是否覆盖所有并行分支?