You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CP-SAT创建布尔变量报错:判断教师授课次数是否为0的解决方法

问题解决方法

错误根源

你遇到的TypeError是因为OR-Tools CP-SAT不支持嵌套的等式表达式:teacher_works_n_times == 0会返回一个BoundedLinearExpression对象,无法直接与布尔变量进行相等比较。同时你定义teacher_works_n_times的方式也有误,不能用model.NewIntVar(...).Sum(...)的链式调用。

修正步骤

  1. 正确计算教师授课次数总和:直接对classes_by_teacher[t]中的变量求和,得到表示授课次数的线性表达式。
  2. 用双向约束关联布尔变量与数值条件:通过OnlyEnforceIf方法,分别定义当布尔变量为真时总和为0,以及布尔变量为假时总和大于0的约束,确保两者完全等价。

修改后的完整代码

classes_by_teacher = {}
for t in all_teachers:
    cur_classes = []
    for d in all_days:
        for p in all_day_parts:
            for g in all_groups:
                for s in all_subjects:
                    cur_classes.append(classes[(t, d, p, g, s)])
    classes_by_teacher[t] = cur_classes

teacher_i_doesnt_work = []

for t in all_teachers:
    # 直接计算授课次数总和,无需提前创建IntVar
    teacher_works_n_times = sum(classes_by_teacher[t])
    teacher_doesnt_work = model.NewBoolVar(f"teacher {t} does not work")
    
    # 双向约束:布尔变量为真时,授课次数必须为0
    model.Add(teacher_works_n_times == 0).OnlyEnforceIf(teacher_doesnt_work)
    # 反向约束:布尔变量为假时,授课次数必须大于0
    model.Add(teacher_works_n_times > 0).OnlyEnforceIf(teacher_doesnt_work.Not())
    
    teacher_i_doesnt_work.append(teacher_doesnt_work)

model.Maximize(sum(teacher_i_doesnt_work))

额外说明

如果需要将teacher_works_n_times显式定义为IntVar(比如需要单独跟踪这个变量),可以这样写:

teacher_works_n_times = model.NewIntVar(0, 10000, f"How many times does {t} work")
model.Add(teacher_works_n_times == sum(classes_by_teacher[t]))

之后再添加和布尔变量关联的双向约束即可。

内容的提问来源于stack exchange,提问作者mikecarti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:26:07