OR-tools CP-SAT中presence_literal与时长乘积和约束实现问题
OR-Tools SAT调度中添加存在性与任务时长乘积和约束的错误解决
问题背景
尝试基于OR-Tools的带切换时间调度示例代码,添加约束:所有被选中任务(presence_literal为真)的时长之和不超过makespan(horizon),但直接使用intervals[i]参与运算时触发错误:
arg = cmh.assert_is_a_number(arg) TypeError: Not a number: interval_j5_t11_a0
错误原因
intervals[i]是IntervalVar对象,代表一个包含start、end、duration属性的时间区间,并非数值类型,不能直接参与乘法和求和运算。必须提取区间的时长部分(固定值或IntVar变量)来构建约束。
正确实现方式
情况1:任务时长为固定值
如果示例中任务的时长是预先定义的固定值(比如存在durations_per_machines[machine_id][i]数组存储每个任务的时长),直接使用固定时长构建约束:
# 在每个machine_id的循环内添加 model.Add(sum(machine_presences[i] * durations_per_machines[machine_id][i] for i in all_machine_tasks) <= horizon)
情况2:任务时长为变量(IntervalVar的duration属性)
如果任务时长是动态变量(存储在IntervalVar的duration中),通过intervals[i].Duration()提取对应的IntVar进行运算:
# 在每个machine_id的循环内添加 model.Add(sum(machine_presences[i] * intervals[i].Duration() for i in all_machine_tasks) <= horizon)
嵌入示例代码的位置
将约束添加到机器循环内、circuit约束构建完成之前:
for machine_id in all_machines: # ... 原有的机器相关逻辑代码 ... # 添加存在性与时长乘积和约束 model.Add(sum(machine_presences[i] * intervals[i].Duration() for i in all_machine_tasks) <= horizon) # 构建circuit约束(原示例代码中的model.AddCircuit(arcs)) model.AddCircuit(arcs)
内容的提问来源于stack exchange,提问作者Gerard L
相关产品推荐
相关产品推荐

