3 回答
TA贡献1921条经验 获得超9个赞
在 Docplex 中,每个线性约束都可以用作一个表达式,其作用类似于布尔变量,如果满足约束则等于 1,如果不满足则等于 0。
请注意,当添加到模型时(通过 Mode.add、Model.add_constraint(s)),约束将始终得到满足。但是,您可以写:
m.add( (x<=3) + (y>=5) >= 1)
这意味着至少满足一个(可能是两个)约束 (x<=3) 和 (y>=5)。
在您的情况下,假设有一个包含 N 个约束 cts[i] 的数组,则编写:
m.add( m.sum(cts) >= 10)
您还可以在目标中使用这样的表达式:
m.maximize(m.sum(cts))
将最大化满足约束的数量
将确保其中至少 10 人满意
注意:始终使用Model.sum
,而不是 Pythonsum
以避免性能问题。
TA贡献1797条经验 获得超6个赞
让我举一个动物园里的例子
from docplex.mp.model import Model
# Data
Buses=[
(40,500),
(30,400),
(35,450),
(20,300)
]
nbKids=300
# Indexes
busSize=0;
busCost=1;
for b in Buses:
print("buses with ",b[busSize]," seats cost ",b[busCost])
mdl = Model(name='buses')
#decision variables
mdl.nbBus=mdl.integer_var_dict(Buses,name="nbBus")
# Constraint
mdl.add_constraint(sum(mdl.nbBus[b]*b[busSize] for b in Buses) >= nbKids, 'kids')
# Objective
mdl.minimize(sum(mdl.nbBus[b]*b[busCost] for b in Buses))
mdl.solve()
# Display solution
for b in Buses:
print(mdl.nbBus[b].solution_value," buses with ",b[busSize]," seats");
#Add a constraint
# Number of sizes where we have 1 or 2 buses should be at least 3
mdl.add(mdl.sum(mdl.logical_and(1<=mdl.nbBus[b],mdl.nbBus[b]<=2) for b in Buses) >=3)
mdl.solve()
# Display solution
for b in Buses:
print(mdl.nbBus[b].solution_value," buses with ",b[busSize]," seats");
这使
buses with 40 seats cost 500
buses with 30 seats cost 400
buses with 35 seats cost 450
buses with 20 seats cost 300
5.0 buses with 40 seats
1.0 buses with 30 seats
2.0 buses with 35 seats
0 buses with 20 seats
4.0 buses with 40 seats
1.0 buses with 30 seats
2.0 buses with 35 seats
2.0 buses with 20 seats
TA贡献1802条经验 获得超4个赞
在以下代码中,我创建了两个包含 100 个整数变量的列表 xi 和 xj。
然后,我定义一个逻辑和约束列表ctands,当 xi[k]>=3 且 yi[k]>=5 时为 true。
然后我发布这些逻辑约束的总和恰好等于 10,这意味着必须满足其中的 10 个,因为任何约束都可以用作二进制变量,满足时等于 1。
目标是最小化 xi 和 xj 的总和,因此结果如预期为 10 * 3 + 10*5 = 80
m = Model()
xi = m.integer_var_list(100, ub=10, name='xi')
xj = m.integer_var_list(100, ub=11, name='xj')
ctands = [((xi[k]>=3) + (xj[k]>=5)==2) for k in range(100)]
# version with logical_and
# ctands = [mdl.logical_and((xi[k]>=3), (xj[k]>=5)==2)) for k in range(100)]
#state that exactly 10 ands are true: the value of an and is 1 when true, 0 when false
m.add(m.sum(ctands) == 10)
# this minimize pulls xs and ys variables to 0
m.minimize(m.sum(xi) + m.sum(xj))
m.solve()
m.print_solution()
添加回答
举报