Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

possible to index a set by a variable?

I am trying to do something that logically should be possible to do. However, I am not sure how to do this within the realm of linear programming. I am using ZMPL/SCIP, but this should be readable to most.

set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;

var a;
var b;

subto bval:
  b == 2;

subto works:
  a == u[2];

#subto does_not_work:
#  a == u[b];

I am trying to make sure that the variable a is equal to the value at the index b in u. So for example, I ensure that b == 2 and then I try to set the constraint that a == u[b], but that does not work. It complains that I am trying to index with a variable. I am able to just do a == u[2] however, which makes a equal to 20.

Is there a way to easily access u at an index specified by a variable? Thanks for any help/guidance.


EDIT: I think the consensus is that this is not possible because it no longer becomes an LP. In that case, can anyone think of another way to write this so that, depending on the value of b, I can get an associated value from the set u? This would have to avoid directly indexing it.


SOLUTION: Based on the response from Ram, I was able to try it out and found that it was definitely a viable and linear solution. Thanks, Ram! Here is sample solution code in ZMPL:

set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;

var a;
var b;
var y[I] binary;

subto bval:
  b == 4;

subto only_one:
  sum <i> in I : y[i] == 1;

subto trick:
  b == (sum <i> in I : y[i] * i);

subto aval:
  (sum <i> in I : u[i]*y[i]) == a;
like image 498
gnychis Avatar asked Oct 04 '22 11:10

gnychis


1 Answers

Yes, you can rewrite and linearize your constraints, by introducing a few extra 0/1 variables (indicator variables). These kinds of tricks are not uncommon in Integer Programming.

Constraints In English

b can take on values from 1 through 5. b = {1..5}

and depending on b's value, the variable a should become u[b]

Indicator Variables

Let's introduce 5 Y variables - Y1..Y5 (one for each possible value of b)

Only one of them can be true at any given time.

 Y1 + Y2 + Y3 + Y4 + Y5 = 1
 All Y's are binary {0,1}

Here's the trick. We introduce one linear constraint to ensure that the corresponding Y variable will take on value 1, only when b is that value.

b - 1xY1 - 2xY2 - 3xY3 - 4xY4 - 5xY5 = 0

(For example, if b is 3, the constraint above will force Y3 to be 1.)

Now, we want a to take on the value u[b].

 a = u[1]xY1 + u[2]xY2 + u[3]xY3 + u[4]xY4 + u[5]xY5 

Since u[ 1] ...u[5] are constants known beforehand, the constraint above is also linear.

Here is one reference on these kinds of IF-THEN conditions in Integer Programming. Many of these tricks involve the Big-M, though we didn't need it in this case.

Hope that helps you move forward.

like image 85
Ram Narasimhan Avatar answered Oct 07 '22 18:10

Ram Narasimhan