OR-Tools 作业车间调度进阶:长任务跨班次连续加工的建模与实现

落静酱_6706

落静酱_6706

2026-06-04

448人浏览

原创

OR-Tools 作业车间调度进阶:长任务跨班次连续加工的建模与实现

本文详解如何在 OR-Tools CP-SAT 求解器中,对需跨多个班次(如早/中/夜班)或周末停机时段的长工件工序,实现不可分割、严格连续的排程——避免被其他任务插入中断,并兼顾日历约束(如班次间隙、周末停工)。

本文详解如何在 or-tools cp-sat 求解器中,对需跨多个班次(如早/中/夜班)或周末停机时段的长工件工序,实现**不可分割、严格连续**的排程——避免被其他任务插入中断,并兼顾日历约束(如班次间隙、周末停工)。

在实际制造调度中,一个典型挑战是:某道关键工序(如大型铸件热处理、精密真空镀膜)耗时长达16小时以上,必须连续运行,不能因班次交接(如22:00–06:00夜班结束)或周末停机而中断。若简单将其拆分为多个短任务并用 OnlyEnforceIf 强制首尾衔接,如提问者所遇,求解器仍可能在逻辑间隙中插入其他作业——因为 OnlyEnforceIf 是条件约束(soft),而非硬性拓扑强制;且多段拆分后,各子任务间缺乏“原子性”语义,易受日历空档干扰。

✅ 正确解法:使用 IntervalVar 的动态长度 + 日历感知建模

Google OR-Tools 官方文档明确推荐:不主动拆分长任务,而是定义一个能“跨越日历断点”的单区间变量(IntervalVar),其长度自动适配实际可用工作时间。核心在于利用 model.NewOptionalIntervalVar() 配合 model.AddNoOverlap() 和日历约束,让求解器自主计算该任务在非工作时段(如周末、班次间隔)的“自然暂停”,但逻辑上保持连续——即:任务开始后,仅在机器可用时段推进,总加工时长不变,且中途绝不允许其他任务抢占同一机器。

CAPTURELAB
CAPTURELAB

一款面向游戏玩家的AI游戏视频工具,可以自动识别和整理游戏精彩片段,帮助玩家更快制作游戏集锦视频。

下载

▶ 关键代码实现(CP-SAT Python)

from ortools.sat.python import cp_model

model = cp_model.CpModel()

# 假设:machine_id = 0 的机床采用两班制(22:00–06:00 + 周末停工)
# 定义其工作日历:以分钟为单位,例如 [ (0, 1440), (1560, 2880) ] 表示周一00:00–24:00中仅13:00–24:00可用(示例)
work_intervals = [
    (0, 1440),    # 周一 00:00–24:00 全天(可选)
    (1560, 2880), # 周一 13:00–24:00(夜班时段)
    # ... 更多班次与日期区间
]

# 创建「日历感知」的区间变量:start, end, size 均为变量,size = 总加工时长(固定)
task_duration = 960  # 16小时 = 960分钟(不可拆分的物理约束)
start_var = model.NewIntVar(0, horizon, 'task_start')
end_var = model.NewIntVar(0, horizon, 'task_end')
interval = model.NewIntervalVar(start_var, task_duration, end_var, 'long_task_0')

# 【核心】添加日历约束:任务只能在 work_intervals 内执行
# 方法:为每个不可用时段 [unavail_start, unavail_end],添加“任务不得完全落入其中”的约束
for unavail_start, unavail_end in get_unavailable_intervals(work_intervals, horizon):
    # 任务要么在不可用时段前结束,要么在其后开始
    model.Add(end_var = unavail_end).OnlyEnforceIf(
        model.NewBoolVar(f'after_{unavail_end}').Not()
    )
    # 或更简洁地:使用 AddNoOverlap + 辅助不可用区间(推荐)
    # model.AddNoOverlap([interval, model.NewIntervalVar(unavail_start, unavail_end - unavail_start, unavail_end, f'gap_{unavail_start}')])

# 强制该任务在 machine_id=0 上执行(绑定资源)
machine_intervals = machine_to_intervals[0]
model.AddNoOverlap(machine_intervals + [interval])  # 将长任务加入该机所有任务区间集合

# 目标:最小化最大完工时间(makespan)
model.Minimize(end_var)

? 为什么优于拆分+OnlyEnforceIf?

  • ✅ 语义正确:单个 IntervalVar 天然表达“一个不可中断的物理过程”,求解器理解其原子性;
  • ✅ 日历自适应:无需手动枚举所有班次间隙,通过区间约束自动规避非工作时段;
  • ✅ 求解鲁棒:避免因布尔变量爆炸导致 OnlyEnforceIf 约束松弛失效;
  • ✅ 目标清晰:直接优化 end_var,而非间接最小化首尾距离 spltMin。

⚠️ 注意事项与最佳实践

  • 时间粒度统一:全程使用分钟(或秒) 作为基础单位,避免浮点误差与整数截断;
  • 日历预处理:将班次表(如 [22:00, 06:00])和节假日转换为绝对时间戳区间(如 1672531200 → 1672552800),再生成 unavailable_intervals;
  • 避免 AddCircuit 误用:AddCircuit 适用于路径规划(如TSP),不适用于单机任务序列约束;此处应坚持 AddNoOverlap + 区间建模;
  • 性能调优:对超长任务(>48h),可设置 model.Add(end_var - start_var == task_duration) 替代 NewIntervalVar(..., size, ...),提升数值稳定性;
  • 验证连续性:求解后检查 solution.value(end_var) - solution.value(start_var) 是否恒等于 task_duration —— 若成立,则证明无隐式中断。

通过这一建模范式,您不再需要“把大象塞进冰箱分三步”,而是直接为大象定制一间带休息室的专属房间:它何时进门、何时出门,由调度逻辑决定;但只要进门,就必须待满16小时,期间任何人不得打扰——这正是智能制造中高价值工序调度的工程本质。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1771

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4584

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

27057

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3267

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3287

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1203

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2543

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.8万人学习