如何基于CPLEX上的其他两个约束来实施新约束?

问题描述

我对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()