Norman Schmitz
Norman Schmitz

Reputation: 13

CPLEX/OPL model - constraints with subset index

I am currently programming a CPLEX/OPL model using IBM ILOG CPLEX Optimization Studio. I have a problem with using sums or indexes which contain a subset and depend on another parameter/variable, e.g. check the following constraints: NB 2,3,4,8).

Can anyone help me with incorporating these constraints properly?

Please find the source code attached:

  //Parameter

int maxblock=...;                   //number of blocks (I)
int maxprodfam=...;             //number of product families (J)
int maxprod=...;                    //number of products (P)
int maxdemand=...;                  //number of demand elements (K)

range blocks=1..maxblock;
range prodfam=1..maxprodfam;
range products=1..maxprod;
range demandelements=1..maxdemand;

int startalpha[blocks]=...;     //earliest start time of block i
int endalpha[blocks]=...;       //latest completion time of block i
int prodtime[products]=...;     //unit production time for product p (a)
int minorsetup[products]=...;   //minor setup time per sub-lot of product p (s)
int majorsetup[prodfam]=...;        //major setup time for product family j (S)
int demand[products]=...;           //demand elements (d)

//Variablen

dvar int+ x[blocks][demandelements];    //quantity of demand element k satisfied from production in block i (x)
dvar boolean y[blocks][prodfam];        //product family assessment to blocks (y)
dvar boolean q[blocks][products];       //product assessment to blocks 
dvar boolean o[blocks];             //activation of blocks (e.g. if a prodfam is assignes to it)
dvar int+ alpha[blocks];                //start time block
dvar int+ duration[blocks];         //duration of block

 //Modell

minimize
alpha[maxblock]+duration[maxblock]; //objective function (minimize the makespan)

subject to {
 forall(i in blocks)
   NB1: //one product family assigned to each block
    sum(j in prodfam)
      y[i][j]==o[i];

 forall(i in blocks, j in prodfam)
   NB2: //production sub-lots
    sum(p in products(j))q[i][p]<=y[i][j]*abs(products(j));

 forall(i in blocks, k in demandelements(i))
   NB3: //product flow from block i into demand element k
    x[i][k]<=demand[k]*q[i][p(k)];

 forall(i in blocks)
   NB4: //block schedule
    duration[i]==sum(j in prodfam)majorsetup[j]*y[i][j]
    +sum(p in products)minorsetup[p]*q[i][p]
    +sum(k in demandelements(i))alpha[p(k)]*x[i][k];

 forall(i in 2..maxblock)
   NB5: //block starts when other block finished
    alpha[i]>=alpha[i-1]+duration[i-1];

 forall(i in blocks)
   NB6: //time window earliest start
    alpha[i]>=startalpha[i]*o[i];

 forall(i in blocks)
   NB7: //time window latest completion
    alpha[i]+duration[i]<=endalpha[i];

 forall(k in demandelements)
   NB8: //matching output and demand
    sum(i in blocks(k))x[i][k]==demand[k];
}

Upvotes: 0

Views: 3832

Answers (1)

TimChippingtonDerrick
TimChippingtonDerrick

Reputation: 2072

It is not clear what your problem is, but I am guessing your problem is to do with modelling things like products(j) in constraint 2. Try using sets for these - so create an array of sets of products in each product family. There are examples of this in the OPL examples provided as part of the install. For example, in the examples\opl\models\AssemblySequencing\Sequence model we have

{string} computer[AllComputers] = ...;

So you could do something similar as e.g.

{int} productsInFamily[prodfam] = ...;

EDIT: using the new structures... try something like:

 forall(i in blocks, j in prodfam)
   NB2: //production sub-lots
    sum(p in productsInFamily[j])q[i][p]<=y[i][j]*abs(products(j));

There are many other ways to do this sort of data structure, some may be more efficient, some may make more sense from the business perspective. I personally like working with sets of things, especially with sets of tuples. Get to know the data structure types and how to combine them in OPL, because having the right data structures always helps your modelling.

Upvotes: 0

Related Questions