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 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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?
Not sure what you mean by 'calling' constraints. In my example, cts is a Python list with constraint objects.
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

1 Comment

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.
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()

10 Comments

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.
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.
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.
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
I strongly suggest you use Model.logical_and to clarify your logical constraints.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.