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

如何在Python OR-Tools中实现x3∈{1,4}的变量取值约束?

解决OrTools SAT约束:让变量仅取特定值

你的代码问题出在两个核心点:

  • 没必要引入布尔变量数组b和AddExactlyOne(b)约束,这完全是多余的,反而打乱了约束逻辑。
  • 对x3的约束逻辑完全错误:你用同一个布尔变量b[3]同时绑定了x[3]==1和x[3]==4的约束,这意味着当b[3]为真时,x3必须同时等于1和4(不可能实现);当b[3]为假时,x3必须既不等于1也不等于4,正好和你的需求相反。

要实现x[3] ∈ {1,4}的约束,OrTools有更直接的方式,不需要复杂的布尔变量嵌套:

方法一:用AddAllowedAssignments(最直观)

这个API专门用来约束变量只能取指定集合内的值,代码极简:

from ortools.sat.python import cp_model

model = cp_model.CpModel()
# 定义4个变量,范围0-10
x = [model.NewIntVar(0, 10, f'val_{i}') for i in range(4)]
# 直接约束x[3]只能取1或4
model.AddAllowedAssignments([x[3]], [[1], [4]])

solver = cp_model.CpSolver()
status = solver.Solve(model)

if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
    for n, dval in enumerate(x):
        print(f'int: {n}: sol: {solver.Value(dval)}')
else:
    print('unsat')

方法二:用逻辑或约束

如果想手动构建逻辑约束,可以用AddBoolOr实现x[3]==1 || x[3]==4的逻辑:

from ortools.sat.python import cp_model

model = cp_model.CpModel()
x = [model.NewIntVar(0, 10, f'val_{i}') for i in range(4)]

# 创建两个布尔变量分别表示x3等于1和等于4的情况
b1 = model.NewBoolVar('x3_eq_1')
b4 = model.NewBoolVar('x3_eq_4')

# 绑定布尔变量与数值约束
model.Add(x[3] == 1).OnlyEnforceIf(b1)
model.Add(x[3] != 1).OnlyEnforceIf(b1.Not())
model.Add(x[3] == 4).OnlyEnforceIf(b4)
model.Add(x[3] != 4).OnlyEnforceIf(b4.Not())

# 要求至少一个布尔变量为真(即x3是1或4)
model.AddBoolOr([b1, b4])

solver = cp_model.CpSolver()
status = solver.Solve(model)

if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
    for n, dval in enumerate(x):
        print(f'int: {n}: sol: {solver.Value(dval)}')
else:
    print('unsat')

运行以上任意一种代码,都会得到符合预期的输出:x3只会是1或4,其他变量在0-10范围内任意取值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:25:22