Solved

Writing a constraint

  • 27 December 2020
  • 5 replies
  • 158 views

Userlevel 1
Badge +3

Dear staff,

I would like to receive some help writing the following constraint for a mathematical model.

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:

p(i) binary variable

p(j) binary variable

a(i,j) continuous variable

C(i,j) parameter

H(i) parameter

H(j) parameter

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

if p(i) = 1 and p(j) = 0, then a(i,j) <= C(i,j)*H(j)

if p(i) = 0 and p(j) = 1, then a(i,j) <= C(i,j)*H(i)

if p(i) = 0 and p(j) = 0, then  a(i,j) <= C(i,j) * (H(i) + H(j))/2

if p(i) = 1 and p(j) = 1, then a(i,j) <= C(i,j)

If you have any suggestions on how to write the above conditions within a constraint, I will be glad.

Thank you,

icon

Best answer by Marcel Hunting 28 December 2020, 17:59

View original

5 replies

Userlevel 1
Badge +3

Thank you very much for your precious inputs.

I will try to implement them

Userlevel 4
Badge +4

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.

Userlevel 1
Badge +3

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!

Userlevel 1
Badge +3

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,

 

 

Userlevel 5
Badge +2

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

sum[y1|(ord(y1)<= ord(y)), p(i, y1)] = varSum(i, y)

sum[y1|(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. 

 

Reply


Didn't find what you were looking for? Try searching on our documentation pages:

AIMMS Developer & PRO | AIMMS How-To | AIMMS SC Navigator