滤棒智能排产CP-SAT建模说明
当前阶段仅输出建模与实现设计,不修改生产代码。
1. 建模目标
根据已生效的卷包智能排产明细 t_schedule_plan_detail,计算各滤棒物料在不同日期的需求,并生成滤棒设备生产计划。
滤棒计划必须满足:
- 卷包开始生产前,所需滤棒已经生产完成。
- 滤棒生产完成后必须存放指定时长,达到可用状态后才能供应卷包。
- 满足滤棒设备能力、工厂日历、开台计划、物料适配及换牌时间约束。
- 首版不考虑现有库存,期初可用库存按 0 建模。
- 在满足卷包需求的前提下,尽量晚生产、减少库存等待和换牌损耗。
- 滤棒排产不能修改卷包计划,只能根据卷包计划生成上游供应计划。
2. 数据关系
2.1 卷包需求来源
从指定的卷包排产版本读取:
t_schedule_plan_version
│
└── t_schedule_plan_detail
├── mat_id
├── plan_qty
├── plan_date
└── plan_start_time一次滤棒排产只能关联一个确定的卷包排产版本,不能把不同版本的明细混合计算。
滤棒排产版本应保存:
source_pack_schedule_plan_version_id用于追踪滤棒计划依据的卷包版本。
2.2 卷烟与滤棒映射
通过 t_filter_cost 建立转换关系:
卷烟成品物料 mat_id
│
├── filter_mat_id 滤棒物料
├── unit_consume_qty 标准单耗
├── switch_consume 是否使用统计单耗
└── statistic_consume 统计单耗有效单耗定义为:
if switch_consume = 1 and statistic_consume > 0:
effective_consume = statistic_consume
else:
effective_consume = unit_consume_qty单耗缺失、非正或单位不一致时,应在进入求解器前终止,并返回配置错误。
2.3 滤棒存放时间
新增滤棒存放时间配置,至少包含:
model_site_id
work_shop_id
filter_mat_id
storage_hours
enable配置读取顺序:
- 滤棒物料级配置;
- 工厂或车间默认配置;
- 均未配置时返回错误,不允许默认按 0 小时处理。
3. 卷包需求转换
3.1 单条明细转换
当前卷包 CP-SAT 明细的 plan_qty 按“箱”处理。
对于卷包明细 :
- 卷包计划量:,单位为箱;
- 对应滤棒物料:;
- 单箱滤棒消耗:,单位为万支/箱。
滤棒需求为:
单位为万支。
这里不再执行 planQty / 5。如果后续需要兼容其他排产分支,应先在输入适配层统一转换成“箱”,不能把单位换算散落在求解代码中。
3.2 日需求聚合
同一天可能有多个卷烟牌号使用同一种滤棒。
对滤棒物料 和生产日期 :
需求截止时间取当天相关卷包明细最早的开台时间:
因此形成如下需求事件:
滤棒物料 | 需求日期 | 需求截止时间 | 需求量
F01 | 2026-09-10 | 2026-09-10 07:30 | 120万支
F01 | 2026-09-11 | 2026-09-11 07:30 | 100万支使用累计需求而不是逐条绑定,可以让前一天的剩余滤棒继续覆盖后续需求。
4. 时间模型
4.1 时间粒度
首版使用小时桶建模。
每个时间桶来自滤棒车间工厂日历:
bucket.start_time
bucket.end_time
bucket.machine_id
bucket.available_capacity非工作时间不生成生产变量。
如果换牌时间不是整小时,应按照实际分钟数扣减相邻时间桶的有效能力,不能直接忽略或简单四舍五入。
4.2 存放后的可用时间
滤棒物料 的存放时长为 。
时间桶 的产量统一视为在桶结束时完成,其可用时间为:
只有满足以下条件的产量才能供应截止时间 的卷包需求:
该处理相对保守,但可以避免把仍在生产或仍在存放的滤棒提前计入库存。
5. 决策变量
定义:
表示滤棒物料 是否在设备 的时间桶 上生产。
表示对应时间桶的滤棒产量。
为避免 CP-SAT 使用浮点数,所有产量应统一放大成整数。例如以 0.01 万支 为最小单位:
scaledQty = round(quantityWanZhi × 100)所有需求、产能和求解结果必须使用相同缩放比例。
6. 硬约束
6.1 设备物料适配
只有 t_filter_equ_capacity 存在有效能力配置时,设备才能生产该滤棒:
6.2 单机互斥
同一设备、同一时间桶最多生产一种滤棒:
6.3 设备能力
其中 Capacity 根据设备小时能力和时间桶有效工作时长计算。
6.4 工厂日历
生产变量只能建立在滤棒设备有效开台时间内。
休息日、停机班次和非工作时段的能力为 0。
6.5 换牌时间
设备从滤棒 切换到 时,需要满足:
换牌时间来自 t_filter_change_brand_time。
相同滤棒连续生产不产生换牌时间。
6.6 累计供应保障
定义截止时刻 前已经完成存放的累计产量:
定义截止时刻 前的累计需求:
首版期初库存为 0,因此必须满足:
该约束需要在每个需求截止时刻建立,而不是只在排产周期结束时检查。
6.7 总量约束
首版不考虑安全库存,也不允许无意义超产:
如果未来增加最小批量或整托盘约束,可以将等式改为允许少量尾差,并单独最小化超产量。
7. 自动向前扩展排产窗口
由于期初库存为 0,月初卷包需求通常需要在上月末提前生产。
例如:
卷包需求时间:09-01 07:30
滤棒存放时间:8小时则滤棒必须在以下时间前完成生产:
08-31 23:30排产起点不能固定为计划月份第一天。
窗口计算流程:
- 找到所有需求中最早的截止时间。
- 减去对应滤棒的存放时间。
- 按滤棒设备日历向前累计可用产能。
- 如果前置产能不足,继续向前加载工作日。
- 直到各滤棒理论产能和设备总产能能够覆盖前置需求。
- 若已经没有更早日历或设备始终无能力,返回无解诊断。
上月末生成的明细仍归属于本次滤棒排产版本,通过明细日期体现实际生产时间。
8. 优化目标
采用分层优化,避免不同目标的权重互相覆盖。
第一层:满足卷包生产
正式求解中累计供应保障为硬约束,不允许缺料。
第二层:尽量晚生产
在不缺料的前提下,最大化生产时间位置,使滤棒尽量靠近需求时间完成存放。
等价于最小化提前库存时间:
第三层:减少换牌
优先让同一种滤棒连续生产,减少换牌损耗。
第四层:设备优先级
根据 t_filter_equ_group_brand_priority,优先把滤棒安排到推荐设备。
第五层:设备负荷平衡
在不影响前四层目标的前提下,减少设备间负荷差异,避免部分设备长期满负荷而其他设备空闲。
9. 无解诊断模型
正式模型无解时,不保存排产结果。
诊断模型在累计保障约束中增加缺口变量:
其中:
诊断模型第一目标为:
为优先保障较早的卷包计划,应让越早的需求缺口惩罚越大。
诊断结果至少输出:
滤棒物料
需求日期
卷包开台时间
累计需求量
可用产量
缺口量
最晚应完成生产时间
主要原因主要原因包括:
- 卷烟物料未配置滤棒单耗;
- 滤棒未配置存放时间;
- 没有可生产该滤棒的设备;
- 工厂日历没有足够工作时间;
- 存放提前期不足;
- 设备总产能不足;
- 换牌时间导致可用产能不足。
10. 实现思路
10.1 输入装载层
建立独立的滤棒排产上下文装载器,负责:
- 加载指定卷包排产版本;
- 查询卷包日进度明细;
- 批量加载
t_filter_cost; - 转换并聚合滤棒日需求;
- 加载滤棒存放时间;
- 加载设备能力、机组优先级和换牌矩阵;
- 加载滤棒车间日历;
- 计算自动向前扩展后的排产窗口;
- 完成单位转换和输入校验。
所有数据库查询和业务单位转换应在该层完成,求解器只接收已经标准化的整数模型。
10.2 问题模型层
建立独立的 FilterScheduleProblem,包含:
sourcePackVersionId
scheduleStartTime
scheduleEndTime
filterMaterials
demandEvents
machines
timeBuckets
capacityMap
changeoverMap
storageHoursMap
machinePriorityMap不要让 CP-SAT 代码直接查询数据库。
10.3 求解层
滤棒 CP-SAT 可以沿用卷包求解器的组织方式:
ProblemBuilder
VariableBuilder
ConstraintBuilder
ObjectiveBuilder
SolutionMapper
FeasibilityAnalyzer可以复用卷包排产中的设计思想,但首版不应为了代码复用而重构现有卷包 CP-SAT。滤棒使用独立类和独立模型,稳定后再评估是否抽取公共时间桶、日历和换牌组件。
10.4 结果转换层
将相邻设备、相同滤棒的连续小时桶合并为一条滤棒排产明细:
manageAreaId
filterMatId
planQty
planDate
planStartTime
planEndTime
actualStartTime
actualEndTime
workHours同时保存对应需求身份或滤棒订单计划明细 ID,保证能够解释这批滤棒服务于哪些日期的卷包需求。
10.5 版本一致性
滤棒计划生成后,应记录源卷包版本。
如果源卷包版本被作废、重新发布或日进度发生变化,滤棒版本应标记为“需求已变化”,必须重新排产,不能继续作为有效供应计划。
11. 后续库存扩展
首版:
未来接入库存后,累计保障约束扩展为:
其中:
InitialUsableInventory:排产开始时已经完成存放的库存;FutureMaturedInventory(t):当前尚未完成存放、但会在时刻 前成熟的库存;A_f(t):本次滤棒排产产生的可用量。
因此首版模型不需要推翻,只需增加两类外部供应事件。
12. 验收场景
- 9 月 10 日卷包生产 100 箱,单耗 0.05 万支/箱,应生成 5 万支滤棒需求。
- 两个卷烟牌号映射到同一种滤棒时,应合并成一个累计需求。
- 存放时间为 8 小时,09-10 07:30 的需求只能由 09-09 23:30 前完成的产量覆盖。
- 09-09 提前生产的剩余量可以继续覆盖 09-10、09-11 的需求。
- 09-01 的需求可以自动在 08-31 或更早日期排产。
- 未完成存放的产量不能计入可用量。
- 缺少单耗、存放配置或设备能力时,不进入求解器。
- 正式模型无解时不保存结果,诊断模型能够给出具体物料、截止时间和缺口。
- 滤棒排产始终读取同一个明确的卷包版本。
- 首版所有需求均由本次排产生产,库存贡献固定为 0。

