问题描述
我对Cplex非常陌生。我有这两个约束(R是范围20内的一组数字):
model.add_constraints((model.sum(x[i,j] for j in R2 ) == 2 for i in R),"C1" )
model.add_constraints((x[i,n1-4] ==x[i,n1-2] for i in R ),"C2" )
我需要计算有多少 i 同时满足C1和C2,然后定义一个新的约束条件,说明“ i中至少有10个满足C1和C2的要求”
我该如何使用cplex?
解决方法
让我给你一个zoo example
中的例子Task.Factory.StartNew(() => { ... },TaskCreationOptions.LongRunning);
给出
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 "," 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," seats");
,
在Docplex中,每个线性约束都可以用作表达式,其作用类似于布尔变量,如果满足约束,则等于1;如果不满足,则等于0。
请注意,当添加到模型中(通过Mode.add,Model.add_constraint(s))时,约束将始终满足。 但是,您可以编写:
m.add( (x<=3) + (y>=5) >= 1)
这意味着满足约束(x = 5)中的至少一个(可能是两个)。
在您的情况下,假设N个约束cts [i]的数组为:
m.add( m.sum(cts) >= 10)
您也可以在目标中使用这样的表达式:
m.maximize(m.sum(cts))
将最大限度地满足约束条件
将确保至少满足其中10个
注意:为避免性能问题,请始终使用Model.sum
而不是Python sum
。
在下面的代码中,我创建了两个包含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()