Reputation: 11
I am very new to Cplex. I have these two constraints (R is the set of numbers in range 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 need to count how many i are fulfilling both C1 and C2 and then define a new constraint that says "at least 10 of i fulfill both C1 as C2".
How can I do that with cplex?
Upvotes: 0
Views: 974
Reputation: 846
In the following code, I create two lists of 100 integer variables, xi and xj.
I then define a list of logical and constraints ctands
,
true when xi[k]>=3 and yi[k]>=5.
I then post that the sum of these logical constraints is exactly equal to 10, which means exactly 10 of them must be satisfied, as any constraint can be used as a binary variable, equal to 1 when satisfied.
The objective is to minimize the sum of xi and xj, so the result is, as expected 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()
Upvotes: 0
Reputation: 10077
let me give you an example out of the zoo example
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");
which gives
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
Upvotes: 0
Reputation: 846
In Docplex, each linear constraint can be used as an expression, that acts like a boolean variable, equal to 1 if the constraint is satisfied, to 0 if not satisfied.
Note that when added to the model (via Mode.add, Model.add_constraint(s)), a constraint will always be satisfied. However, you can write:
m.add( (x<=3) + (y>=5) >= 1)
which means that at least one (possibly two) of the constraints (x<=3) and (y>=5) is satisfied.
In your case, , assuming an array of N constraints cts[i], writing:
m.add( m.sum(cts) >= 10)
You can also use such an expression in the objective:
m.maximize(m.sum(cts))
will maximize the number of satisfied constraints
will ensure at least 10 of them are satisfied
Note: always use Model.sum
, not Python sum
to avoid performance issues.
Upvotes: 1