Cplex OPL:eliminate some dvar in preprocessing

145 views Asked by At

I have a question regarding eliminating some invalid decision variable commbinations in the preprocessing. I have a 2-dimensional decision variable X indexed with [commodities][arcs].Please see the code below.The index "commodities" is based on the tuple "Data".The index "arcs" is based on the tuple "Arc".Both tuples "Data" and "Arc" are based on a tuple "TimeNode". I dont'want the program iterate all X combinations. I want to remove some of the decision variables in the preprocessing, by considering a condition where I compare Origin time in the Data tuple and FromNode time in the Arc tuple and if "Origin.time>FromNode.time", X equals 0,thus eliminated from iteration and not regarded. Thus, the size of the problem will be reduced and some memory saved. I made some examplary code below, with execute. If i have, for example, {Data} commodities= {<1 <1 3><2 8>>...}, 1 is an id, <1 3> - Origin with 1 as a starting node and 3 is a start time. I do not need the problem to regard all Xs earlier than start time 3.
However, the execute does not work as X is a decision variable. What could I possibly do? Formulate the condition as a constraint? Thank you. I would appriciate any advice.

  tuple TimeNode { 
  int node;
  int time;}
  {TimeNode} tnodes = { <n,t> | n in Nodes, t in Time };

  tuple Data{            
  int id;
  TimeNode Origin;           
  TimeNode Destination; }
  {Data} commodities= {<1 <1 3><2 8>>, <2 <2 5><3 10>>};

  tuple Arc {  
  TimeNode FromNode      
  TimeNode ToNode; }
  {Arc} arcs={<<i,s>,<j,e>> | <i,j> in st_arcs, s in Time , e in Time };

  dvar float+ x[commodities][arcs];

  execute {
       for(var c in commodities){
         for(var a in arcs){
           if(c.Origin.time>a.FromNode.time)
            x[c][a]=0;
         }
       }
  }

"ERROR:Assignment to decision variable in "x # 0 # 0" not possible."

1

There are 1 answers

2
Alex Fleischer On

you could write that in the subject to block:

subject to
  {
    forall( c in commodities, a in arcs:c.Origin.time>a.FromNode.time) x[c][a]==0;
  }

For instance

{int} s={1,2};

dvar int x[s] in 0..10;

maximize sum(i in s) x[i];
subject to
{
  forall(i in s:i<=1) x[i]==0;
}

works fine

and is better than

{int} s={1,2};

dvar int x[s] in 0..10;

execute
{
  for(var i in s) if (i<=1) x[i].UB=0;
}

maximize sum(i in s) x[i];
subject to
{
  //forall(i in s:i<=1) x[i]==0;
}

that looks like what you tried to write

But what is the best is often to build a new set and then to have decision variables for the meaningful subset:

{int} s={1,2};
{int} s2={i | i in s :i>1};

dvar int x[s2] in 0..10;



maximize sum(i in s2) x[i];
subject to
{
  
}