Given the following formula
with the table below encode the relationship of x_0
, x_1
and r
for Objective 2':
For objective 2, we can code it as following with Docplex, where we have either 0 or 1 for priority p
.
CPriorityInFreight = mdl.binary_var_matrix(catPriorities, freights, name='CPriorityInFreight')
FreightMixture = mdl.binary_var_dict(freights, name='FreightMixture')
for p in catPriorities:
for f in freights:
# CPriorityInFreight[c, f] = 1 <-> priority c is in freight f
CPriorityInFreight[p, f] = (
1 <= mdl.sum(Assignment[o, f] for o in orders if get_order(o).CategoryPriority == p))
for f in freights:
# sums == 2 <-> we have both cat 0 and cat 1
FreightMixture[f] = (2 == mdl.sum(CPriorityInFreight[c, f] for c in catPriorities))
o2 = mdl.sum(FreightMixture[f] for f in freights)
In Objective 2', we now have the following code for decision variable declaration (with FreightMixture
containing value 0,1,2
) and first formula
CPriorityInFreight = mdl.binary_var_matrix(catPriorities, freights, name='CPriorityInFreight')
FreightMixture = mdl.integer_var_dict(freights, name='FreightMixture')
for p in catPriorities:
for f in freights:
# CPriorityInFreight[c, f] = 1 <-> priority c is in freight f
CPriorityInFreight[p, f] = (
1 <= mdl.sum(Assignment[o, f] for o in orders if get_order(o).CategoryPriority == p))
But how do we translate these relationship on second formula of Objective 2' into Docplex? (I am ok with OPL as I can understand it too)
(Of course if there are simpler way to achieve semantically equivalent formulas with Objective 2', feel free to suggest)
Both in docplex and OPL you can use logical constraints.
In OPL for instance:
int R[0..1][0..1]=[[0,0],[2,1]];
dvar boolean x;
dvar boolean y;
dvar int obj;
maximize obj;
subject to
{
forall(i in 0..1,j in 0..1) (x==i) && (y==j) => (obj==R[i][j]);
}
that is generic to any R table and gives
obj = 2;
x = 1;
y = 0;
You can write less logical constraints if you adapt to the table. In your example
int R[0..1][0..1]=[[0,0],[2,1]];
dvar boolean x;
dvar boolean y;
dvar int obj;
maximize obj;
subject to
{
(x==0) => (obj==0);
(x==1) => (obj==2-y);
}
works fine
And the equivalent code in python docplex
from docplex.mp.model import Model
mdl = Model(name='logical')
x = mdl.binary_var(name='x')
y = mdl.binary_var(name='y')
obj= mdl.integer_var(name='obj')
R=[[0,0],[2,1]]
decisionVars=[x,y,obj]
for i in range(0,2):
for j in range(0,2):
mdl.add_constraint(mdl.if_then((x==i)+(y==j)==2,(obj==R[i][j])))
mdl.maximize(obj)
mdl.solve()
for v in decisionVars:
print(v.name," = ",int(v.solution_value))
that gives
x = 1
y = 0
obj = 2