0

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?

3 Answers3

1

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.

Philippe Couronne
  • 826
  • 1
  • 5
  • 6
  • You mentioned that in your approach " at least one (possibly two) of the constraints (x<=3) and (y>=5) is satisfied." But I need exactly both of them to be satisfied for at least 10 of i. Also, how can I call my constraint with cts? – Ashkan Rezaee Sep 10 '20 at 13:01
  • Not sure what you mean by 'calling' constraints. In my example, `cts` is a Python list with constraint objects. – Philippe Couronne Sep 10 '20 at 16:04
0

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
Alex Fleischer
  • 9,276
  • 2
  • 12
  • 15
  • s there a way that I could avoid the logical_and command? I am using cplex for solving my solution pool so some of my docplex constraints (including logical_and) are being ignored during the population. – Ashkan Rezaee Sep 10 '20 at 15:53
0

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()
Philippe Couronne
  • 826
  • 1
  • 5
  • 6
  • Is there a way that I could avoid the logical_and command? I am using cplex for solving my solution pool so some of my docplex constraints (including logical_and) are being ignored during the population. – Ashkan Rezaee Sep 10 '20 at 15:51
  • I dont quite get why the logical ands are ignored, but you could alternatively use m.add((xi[k]==3) + (xj[k]==5) == 2) to implement the and. sum equals 2 means both constraints are satisfied. – Philippe Couronne Sep 10 '20 at 16:00
  • I put ctands = [((model.sum(x[i, j] for j in R2 ) == 2) + (x[i, n1-4] ==x[i, n1-2])==2) for i in R] model.add(model.sum(ctands) == 10) My first two constraints get satisfied but the last constraint (sum==10) does not get satisfied. I have sum=4 in soutions. – Ashkan Rezaee Sep 22 '20 at 09:08
  • This doesnt look like and and to me. The constraint (x[i, n1-4] ==x[i, n1-2]) , used as an expression, can be equal to 0 or 1, never to 2, so (x[i, n1-4] ==x[i, n1-2])==2) is always false, hence equal to 0 – Philippe Couronne Sep 22 '20 at 10:13
  • I strongly suggest you use `Model.logical_and` to clarify your logical constraints. – Philippe Couronne Sep 22 '20 at 10:13
  • There was a mistake in my previous constraint. The correct one is : ctands = [((x[i, n1-4] ==x[i, n1-2])+ (x[i, n1-3] ==x[i, n1-1])==2) for i in R] model.add(model.sum(ctands) >=10 But with this constriant I don't get right solutions (less than 10 fulfill the rule) – Ashkan Rezaee Sep 22 '20 at 16:04
  • When I use the logical_and I don't get a good result. It's like the constraint is being ignored – Ashkan Rezaee Sep 22 '20 at 16:15
  • At this point, we'd need a (small) code sample to investigate these problems. – Philippe Couronne Sep 23 '20 at 07:22
  • My model is so big It is not possible to post it here. Can I send it to you by email? – Ashkan Rezaee Sep 25 '20 at 13:00
  • If you noticed an issue with `Model.logical_and` we'd need a small sample code to reproduce. With an academic license, support is limited to modeling advice and investigation of potential bugs. – Philippe Couronne Sep 28 '20 at 09:21