# Round 89: optimize 原生 CP-SAT 求解器接入 更新时间:2026-09-16 ## 1. 本轮目标 把 `OptimizeEngine` 从「选规则 + 复用 PoolEngine 物化」推进到真正的 V2 原生求解: 输入 `SchedulingProblemV2`,由 OR-Tools CP-SAT 决定资源分配与时序,输出 `SchedulingSolutionV2`,并且必须通过 APS 独立的 `SchedulingValidator`。 上游依据:`docs/round-85-optimize-integration-shape-plan.md` 第 14 节明确记着 「CP-SAT 的 V2 原生求解器仍应作为后续轮次接入,本轮不把 PoolEngine 适配器冒充为 CP-SAT 最优证明」。本轮就是那一轮。 ## 2. 现状(本轮开始时的事实) - `OptimizeEngine.solve_flex()` 只做算法选择 + provenance 标注,实际物化交给 `PoolEngine`(贪心占槽)。七种派工规则已跑通,但它们不是 CP-SAT。 - `server/engines/cp_engine.py` 是**经典轨**(operations/routings/workstations) 的 CP-SAT,不是 flex 闭环 V2 原生;`solver_process.py` 是它的子进程安全边界。 - 集成环境限制:项目 `.venv` 里的 NumPy 以 X86_V2 为基线构建,而本机 CPU (sd-server,Family 6 Model 15)不支持该指令集,`ortools.sat.python.cp_model` 导入即失败。这与 `round-85` 记录的全量 CP/Excel 测试受限是同一个原因。 ## 3. 本轮范围 ### Slice 1(本轮完成) - 新增 `server/engines/optimize_cpsat.py`:`SchedulingProblemV2 -> CpsatOutcome`, 内含解与可审计元数据(solverId/solverVersion/OR-Tools 状态/耗时/种子/规模)。 - 模型:每道工序在合格设备中选一台(`AddExactlyOne` + 可选定长区间),同设备 `AddNoOverlap`,设备日历与维保之外的时间作为阻塞区间一并进入 NoOverlap,工序链按 `predecessorActivityIds` 串行,目标为最小化总拖期。 - provenance 与 problem hash 绑定,与 `flex_version_to_solution_v2` 同一套口径。 - 新增 `tests/golden/test_optimize_cpsat_native.py`:解通过独立 V2 校验;总拖期不劣于 同口径 EDD 基线。 ### Slice 2(下一轮) - `OptimizeEngine.solve_flex` 增加 CP-SAT 算法路径(`algorithmId=optimize.cpsat`), 物化到 flex* 行,落版本、证据链,走 `/api/flex/schedule` 端到端。 - 目标函数与 PoolEngine `totalTardiness` 口径对齐(当前两者定义不同,不能直接比较)。 - 时间离散化(分钟 -> 5/15 分钟桶)、派工解热启动、缩短求解时间。 - 冻结/在制/模具寿命/班组与工装累计容量接入模型。 ### 明确不做 - 不改 WorldStore 权威语义、审批门禁和审计链。 - 不新建第二套订单/资源/版本模型。 - 不声称 PoolEngine 适配器结果是 CP-SAT 最优证明。 ## 4. 验收 - `pytest tests/golden/test_optimize_cpsat_native.py`:在具备可用 OR-Tools 的环境 通过;在 NumPy/OR-Tools 不可用的环境按既有策略 skip,不得 error。 - 解必须 `validate_solution(...).valid is True` 且无 hard violation。 - 现有回归不受影响:`tests/golden/test_optimize_simulation_world_pack.py`、 `tests/golden/test_optimize_engine.py`。 - 报告必须区分证据等级:代码、测试、真实运行;环境性跳过要写清原因。 ## 5. 停止条件 - V2 契约无法表达所需约束,且无法通过局部兼容字段解决。 - 需要放宽校验才能让测试通过。 - 需要新增生产依赖或许可而没有明确运行环境。 ## 6. Slice 1 证据(2026-09-16) - 隔离解释器(CPython 3.11.15 + NumPy 1.26.4 + OR-Tools 9.11.4210): `2 passed`;模拟数据包 72/72 工序全部排入、`validate_solution` valid、 总拖期 1,782,876 分钟不劣于同口径 EDD 基线。 - 项目 `.venv`:`1 skipped`(OR-Tools 因 NumPy 基线与 CPU 不兼容不可用)。 - 已知限制:`INFEASIBLE` 曾因拖期变量上界未包含「历史欠交」而误判,已修( 交期早于计划起点的部分必须计入上界);当前只做到 FEASIBLE,未证明最优。