aps-kernel — Metis 谋序(APS 标准版)
运筹帷幄,谋定后动 —— 同衡·谋序·同枢,智造同频。 One Truth. One Plan. One Rhythm.
可嵌入的确定性排产内核:CP-SAT 精确求解、独立复核器、 工序-资源适配数据模型、设备槽位与班次日历、ε-约束 trade-off、headless CLI。
标准版 vs 专业版:本包只含可嵌入内核(无 UI / 无服务 / 无 LLM)。 甘特图前端、Web 控制台、AI 编排层、多租户 RLS、审批与 IM 通道 属专业版(Docker 镜像 + docker compose)。
🌐 官网:https://aps.zhinengti.online 家族:Nereus 同衡(数字孪生)· Metis 谋序(智能排产)· Hermes 同枢(物流调度)
⭐ 求解能力(横向基准,非自说自话)
在 16 个标准 FJSP 实例(ft/la/abz/orb/swv/ta/yn,来源 job_shop_lib MIT,
含文献公认最优值)上的实测:
| 实例 | 工单×机器 | SPT 基线 | 规则链 | CP-SAT | 文献最优 | vs 最优 |
|---|---|---|---|---|---|---|
| ft06 | 6×6 | 94 | 92 | 55 | 55 | +0.0% OPTIMAL |
| ft10 | 10×10 | 1530 | 1310 | 930 | 930 | +0.0% OPTIMAL |
| ft20 | 20×5 | 1513 | 1565 | 1165 | 1165 | +0.0% OPTIMAL |
| la01-05 | 10×5 | ~1000 | ~940 | 最优 | — | +0.0% OPTIMAL |
| abz5/6 | 10×10 | ~1700 | ~1600 | 1234/943 | 同 | +0.0% OPTIMAL |
| orb01 | 10×10 | 1489 | 1631 | 1082 | 1059 | +2.2% FEASIBLE |
| swv01/02 | 20×10 | ~2100 | ~2100 | 1495/1562 | 1407/1475 | +6% FEASIBLE |
| ta01/02 | 15×15 | ~2100 | ~2040 | 1233/1248 | 1231/1244 | +0.3% FEASIBLE |
| yn1 | 20×20 | 1547 | 1509 | 944 | 884 | +6.8% FEASIBLE |
11/16 达到文献最优,其余为大规模实例(20 秒预算不足,已如实标 gap)。 全部 8/8 独立复核通过。
python benchmarks/run_standard_bench.py --time-limit 30
当前状态
v1.0.0 —— 公开 API 冻结。P0~P5 全部交付,303 tests passed
| 模块 | 状态 | 关键能力 |
|---|---|---|
| 数据模型 P0 | ✅ | 工序-资源适配、空适配 ≠ 全设备可用、槽位 |
| 输入校验 P0 | ✅ | 三项 P0 准则 + 5 类检查 |
| 规则引擎 P1 | ✅ | 7 条规则(CR/EDD/SPT/WKWR/ATC/加权优先级/FIFO)+ 8 条链 |
| 日历与齐套 P2 | ✅ | 三日历求交、班次×资源×位置、工单级齐套布尔判定 |
| 换型规则链 P2 | ✅ | frePPLe 语义、无匹配 = 硬约束禁止、参数配置化 |
| CP-SAT 求解 P3 | ✅ | 字典序三级目标、容量池用 AddCumulative、冻结窗口 |
| 独立复核器 P4 | ✅ | 8 项真检查(含日历可行)、用输入重算不信任求解器 |
| Provenance P4 | ✅ | 快照 hash + 配置/源码/求解器版本 |
| CLI + 基准 P5 | ✅ | solve / benchmark / explain / chains |
| 冲突诊断 | ✅ | aps explain —— 最小冲突集 + 排不下原因 |
| ε-约束 trade-off | ✅ | 钉住交期预算,问 makespan 能压到多少 |
| 数据体检 | ✅ | aps health —— 四张底账逐项核对 + 可执行率估计 |
三个设计立场
1. 诚实高于漂亮
OPTIMAL 只在真正证明最优时才标;FEASIBLE 必带真实 gap;
超时回退贪心解时 diagnostics["solver_fallback"] 明确标注来源;
全部未排时标 INFEASIBLE 而非 OPTIMAL(避免"看起来排好了")。
这直接对应论文《Formalize, Don't Optimize》的三个统计口径: 返回结果率 / 验证通过率 / 已返回中通过比例 —— 分母不同,不可混比。
2. 复核器是必需品,不是锦上添花
validator.independent_validate() 用输入数据重算(时长、槽位、日历、
换型、设备资格),不信任求解结果自报的值。这不是防御性冗余 ——
开发中它抓到过槽位重叠 48 处而求解器报
OPTIMAL、 makespan = 2.3e18 的垃圾值(UNKNOWN时仍读未赋值变量)。
3. 基准必须公平
所有基线必须在相同约束集下比较。曾实现一个无视日历/工序先后的 SPT 基线, 得出「SPT 比 CP-SAT 还优」的颠倒结论(vsSPT = -203%)。
非法基线比没有基线更糟 —— 它会得出完全相反的结论。
🏗 分层架构:本包的位置
博客园《CP-SAT 排产、排程、排班》:
「APS(长周期规划)+ RTS/RTD(实时派工)双层架构是业界最佳实践」 「前一天做的排程,第二天全乱套」—— 排程 ≠ 派工 是经典误区
┌─────────────────────────────────────────────────┐
│ 上层(aps-platform / 本包之外) │
│ · MRP / 采购 / 库存 │
│ · APS 长周期计划(天/周) │
│ · RTS / RTD 实时派工(分钟级) ← 不在本包 │
│ · MES 执行回写 / 甘特图 UI │
└─────────────────────────────────────────────────┘
↕ ScheduleInput / ScheduleResult
┌─────────────────────────────────────────────────┐
│ aps-kernel(本包)—— 求解内核,不含流程 │
│ ✅ 数据模型 / 输入校验 │
│ ✅ 规则引擎(7 规则 + 8 链) │
│ ✅ CP-SAT 精确求解 + 贪心兜底 │
│ ✅ 冻结窗口(支持增量重排) │
│ ✅ 独立复核器(8 项) │
│ ✅ ε-约束 trade-off / 冲突诊断 / 基准 │
│ ❌ 不做派工、不做 UI、不做持久化、不含 LLM │
└─────────────────────────────────────────────────┘
⚠️ 为什么派工不在本包:派工是高频决策(分钟级刷新), 需要实时状态推送与人工干预;本包是低频决策(计划级), 追求确定性与可审计。把两者混在一个包里会同时失去两者。
⚠️ 本包负责「证明这个计划可执行」,不负责「生成甘特图」:
「排产的难点从来不是生成一个计划,而是证明这个计划在约束下可执行。」 —— 《LLM 不会给你最优排产,求解器会》
版本与兼容性
| 当前 | 1.0.0 —— 公开 API 冻结,破坏性变更只发生在 2.0.0 |
| 含义 | 「API 形状不会随便改」,不是「功能覆盖完整」 |
| 变更记录 | CHANGELOG.md —— 含破坏性变更与迁移动作 |
快速开始
pip install aps-kernel
# 0) ⭐ 上线前先体检(核对工时/BOM/日历/换型矩阵四张底账)
aps health input.json --bom bom.json --inventory stock.json
# 1) 看内置规则链
aps chains
# 2) 求解(贪心,快)
aps solve input.json --chain default
# 3) 求解(CP-SAT,可证 OPTIMAL)
aps solve input.json --solver cpsat --time-limit 30
# 4) 排不下时诊断原因(最小冲突集)
aps explain input.json
# 5) 基准验证(规则链 vs SPT vs CP-SAT)
aps benchmark --sizes 5,8,10 --chains default
aps health的退出码可直接接 CI:0可上线 /1需补数 /2阻断。
from aps_kernel import schedule, solve, CpSatOptions, independent_validate
# 贪心(快,不证明最优)
result = schedule(data, chain="default")
# CP-SAT(可证 OPTIMAL)
result, stats = solve(
data, options=CpSatOptions(time_limit_seconds=30, workers=8),
)
# 独立复核 —— 不信任求解器自报
checks = independent_validate(data, result)
assert all(ok for _, ok, _ in checks)
已知局限(诚实列出)
| 局限 | 说明 |
|---|---|
Job.due_date 只能表达天 |
✅ 已修复(v0.10.0):改为 `date |
| 交期需整日或整时 | 建议传 datetime;传 date 时按当天 00:00 算,不是「当天结束」—— 与部分 APS 的约定不同,转换时请留意 |
| 大规模 gap 仍大 | 20 工单以上、30 秒预算只能到 FEASIBLE,gap 5~7% |
| 换型为静态规则,非序列相关 | frePPLe 语义已实现,但不支持「A→B→C 链式换型」的组合优化 |
| 无持久化状态 | 每次求解无状态,冻结窗口需由调用方传入 |
| 合成 demo 交期偏宽 | demo 默认交期 = horizon+5 天 ≫ makespan → 拖期恒为 0;验证拖期逻辑需改用紧交期 |
| 体检的可执行率是估计值 | 基于静态校验,不检查「现场是否会临时变更」。cp_sat_demo 实测 44%,本估计通常偏乐观 |
安装与依赖
- Python ≥ 3.11
- 运行时依赖:
ortools >= 9.12、PyYAML - 仅发 wheel(
py3-none-any),不发 sdist
License
MIT
Metadata
Release files for aps-kernel 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aps_kernel-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / aps_kernel-1.0.0-py3-none-any.whl
| Download URL | aps_kernel-1.0.0-py3-none-any.whl |
|---|---|
| Size | 133.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
92cf1385b780802d53100364108f262160f5d4c3296d4fb1446f7a83af710b2b
|
|
BLAKE2b-256 checksum How to use checksums |
1a6b13b129ddb1f9c9b951884438305937d323b1f0b853e6b40d310f66657901
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|