This is getting somewhat ugly. I would use indicator constraints; see section 14.2.4 in the Language Reference for more information.

p(i) = 1 → a(i,j) <= C(i,j)*H(j)*(1-p(j)) + C(i,j)*p(j)

p(j) = 1 → a(i,j) <= C(i,j)*H(i)*(1-p(i)) + C(i,j)*p(i)

p(i) = 0 → a(i,j) <= C(i,j) * (H(i) + H(j))/2 * (1-p(j)) + M*p(j)

Here M is a big number (“big M”). The left part of each of these three constraints represents the *activating condition*.

Please note that indicator constraints are only supported by CPLEX and Gurobi.

Thanks very much!

That’s indeed a good idea to try with indicator constraints. I haven’t thought about it. I will give it a try!

Dear staff,

I would like to ask you further help for a potential extension of the constraint mentioned in the previous messages. (I don’t know if I should open a separate discussion for this, but I try to continue here for now).

Within a graph, I define arcs (i-j) where “i” and “j” are nodes. For each arc and node, I also have the following variables and parameters (basically, there is a new index “y” compared to the previous case):

p(i,y) binary variable

p(j,y) binary variable

a(i,j,y) continuous variable

C(i,j) parameter

H(i,y) parameter

H(j,y) parameter

I would like to write a constraint expressing the following conditions:

For all y,

if sum(y1|((ord(y1)<=ord(y)), p(i,y1)) = 1 and sum(y1|((ord(y1)<=ord(y)), p(j,y1)) = 0, then a(i,j,y) <= C(i,j)*H(j,y)

if sum(y1|((ord(y1)<=ord(y)), p(i,y1)) = 0 and sum(y1|((ord(y1)<=ord(y)), p(j,y1)) = 1, then a(i,j,y) <= C(i,j)*H(i,y)

if sum(y1|((ord(y1)<=ord(y)), p(i,y1)) = 0 and sum(y1|((ord(y1)<=ord(y)), p(j,y1)) = 0, then a(i,j,y) <= C(i,j) * (H(i,y) + H(j,y))/2

if sum(y1|((ord(y1)<=ord(y)), p(i,y1)) = 1 and sum(y1|((ord(y1)<=ord(y)), p(j,y1)) = 1, then a(i,j,y) <= C(i,j)

If you have any suggestions on how to write the above extended conditions within a set of constraint, I will be glad. I am not sure about the possibility of including the summation together with the indicator constraints.

Thank you,

Hi @Chibo, i and j are indices of same set. So, create a new variable varSum(i, y) like below

`sumsy1|(ord(y1)<= ord(y)), p(i, y1)] = varSum(i, y)`

sumsy1|(ord(y1)<= ord(y)), p(j, y1)] = varSum(j, y)

varSum can be binary as your post suggests that the above sums are either 0 or 1.

Create another auxillary binary variable auxVar(y) with below constraints. forall (i, y)

`auxVar(y) >= varSum(i, y)`

auxVar(y) >= varSum(j, y)

auxVar(y) <= varSum(i, y) + varSum(j, y)

Now, for the constraint you would like to write - forall (i, j, y)

`a(i, j, y) <= C(i, j) * )H(i, y)/2 + H(j, y)/2 `

`- varSum(i)*H(i, y)/2 - varSum(j)*H(j, y)/2 `

+ varSum(i, y) + varSum(j, y) - auxVar(y)]

As H and C are parameters, there is no multiplication of variables here. the 4 cases in your constraint will evaluate as

`1. varSum(i, y) = 1, varSum(j, y) = 0 -> auxVar(y) = 1 & a(i, j, y) <= C(i, j) * H(j,y)/2`

2. varSum(i, y) = 0, varSum(j, y) = 1 -> auxVar(y) = 1 & a(i, j, y) <= C(i, j) * H(i,y)/2

3. varSum(i, y) = 0, varSum(j, y) = 0 -> auxVar(y) = 0 & a(i, j, y) <= C(i, j) * (H(i,y)/2 + H(j, y)/2)

4. varSum(i, y) = 1, varSum(j, y) = 1 -> auxVar(y) = 1 & a(i, j, y) <= C(i, j) * 1

It might have gotten some of the indices wrong but this should work for your case. Using varSum is not necessary, you can directly type in the sum ..] expression but you will need the additional auxVar constraint.

Thank you very much for your precious inputs.

I will try to implement them