Google OR-Tools调度设置正迟滞惩罚时出现BoundedLinearExpr评估错误
OR-Tools CP-SAT 仅统计超期迟滞惩罚的实现方法
你遇到的报错是因为OR-Tools CP-SAT求解器的变量(IntVar)和线性表达式属于求解器内部封装类型,无法直接使用Python原生的max()函数或者if条件判断进行求值,必须使用求解器提供的约束接口实现逻辑。
解决方案
两种实现方式均可达到仅对超期作业计算迟滞惩罚的效果,替换你原有迟滞变量定义的代码即可:
方案1:使用AddMaxEquality接口(官方推荐)
直接调用CP-SAT内置的最大值约束实现逻辑:
due_date = job[0][0][4] # 原始迟滞:作业结束时间减截止时间,可正可负 lateness_raw = l_end - due_date # 定义正迟滞变量:仅统计超期部分,取值下界为0 tardiness = model.NewIntVar(0, horizon_due_date, f'tardiness_job_{job_id}') # 约束正迟滞等于 0 和 原始迟滞 的最大值 model.AddMaxEquality(tardiness, [0, lateness_raw]) # 加入惩罚项列表 termin.append(tardiness)
方案2:双约束实现(兼容性更强)
如果遇到版本适配问题,也可以通过两条简单约束实现同等效果。因为你的目标函数是最小化总迟滞,求解器会自动将tardiness取到满足约束的最小值,刚好等于max(0, lateness_raw):
due_date = job[0][0][4] lateness_raw = l_end - due_date tardiness = model.NewIntVar(0, horizon_due_date, f'tardiness_job_{job_id}') # 两条约束替代max逻辑 model.Add(tardiness >= 0) model.Add(tardiness >= lateness_raw) termin.append(tardiness)
后续不需要修改任何其他逻辑,你原有的目标函数代码可以直接复用。现在termin列表中存储的就是每个作业仅超期部分的惩罚值,提前完工的作业迟滞惩罚为0,完全符合需求。
内容的提问来源于stack exchange,提问作者Svenja K
相关产品推荐
相关产品推荐

