mathematical-optimizationcplexopl

Implementing the RCPSP with OPL using CPLEX adding multiple predecessors for a task


After receiving help numerous times with this issue here, I'm on my way from one step to finishing my model. I've created this one, and it's functioning well with a single predecessor task. However, I'm now aiming to adapt this model to handle multiple predecessor tasks. :

// Example data
range J = 1..4;
range R = 1..1;
range T = 0..9;
int P[J] = [0,1,2,3]; 
int d[J] = [2, 3, 1, 4];
int EF[J] = [0, 2, 5, 6];
int LF[J] = [0, 2, 5, 6];
int Tbar = sum(j in J) d[j];

// Resource usage matrix
int u[J][R] = [[2],[5],[5],[5]]; 

// Resource availability
int a[R]= [10];

// Decision Variables
dvar boolean x[J][T];

dexpr int CT = sum(j in J, t in EF[j]..LF[j])t*x[j][t];
minimize CT;

subject to {
  forall(j in J)
    ct1:sum (t in EF[j]..LF[j]) x[j][t] == 1;
  forall(j in J: P[j] != 0) // assuming 0 indicates no predecessor
    ct2:sum (t in EF[j]..LF[j]) x[j][t] * t >=
        sum (t in EF[P[j]]..LF[P[j]]) x[P[j]][t] * (t + d[P[j]]);
  forall(r in R, t in 1..Tbar) {
    ct3:sum(j in J) u[j][r] * sum(q in maxl(t, EF[j])..minl(t + d[j] - 1, LF[j])) x[j][q] <= a[r];
  }
}

For this one, I'm attempting to modify it to handle multiple predecessor tasks and encountering some issues with it :

// Example data
range J = 1..10;
range R = 1..2;
range T = 1..10;
{int} Tasks =asSet(1..10);
setof(int) P[Tasks] = [{0}, {1}, {2}, {1}, {4,3}, {4,3}, {4,3}, {6}, {8}, {5,7,9}];

int d[J] = [7, 3, 1, 8, 2, 1, 1, 2, 2, 1];
int EF[J] = [0, 7, 10, 7, 15, 15, 15, 16, 18, 20];
int LF[J] = [0, 11, 14, 7, 18, 15, 19, 16, 18, 20];
int Tbar = sum(j in J) d[j];

// Resource usage matrix
int u[J][R] = [[2,1], [2,2], [2,2], [1,1], [2,1], [2,1], [1,0], [2,1], [2,2], [3,0]];

// Resource availability
int a[R] = [4, 2];

// Decision Variables
dvar boolean x[J][T];

dexpr int CT = sum(j in J, t in EF[j]..LF[j]:t in T) t * x[j][t];
minimize CT;

subject to {
  forall(j in J)
    ct1:sum (t in EF[j]..LF[j]) x[j][t] == 1;
  forall(j in J: P[Tasks]!= 0) // assuming 0 indicates no predecessor
        ct2:sum (t in EF[j]..LF[j]) x[j][t] * t >=
             sum (t in EF[P[Tasks]]..LF[P[Tasks]]) x[P[Tasks]][t] * (t + d[P[Tasks]]); 
  forall(r in R, t in 1..Tbar) {
    ct3:sum(j in J) u[j][r] * sum(q in maxl(t, EF[j])..minl(t + d[j] - 1, LF[j])) x[j][q] <= a[r];
  }
}

I'm aiming to adapt the RCPSP model to handle multiple predecessor tasks.


Solution

  • The following model works fine

    // Example data
    range J = 1..4;
    range R = 1..1;
    range T = 0..9;
    //int P[J] = [0,1,2,3]; 
    int d[J] = [2, 3, 1, 4];
    int EF[J] = [0, 2, 5, 6];
    int LF[J] = [0, 2, 5, 6];
    int Tbar = sum(j in J) d[j];
    
    {int} Tasks =asSet(1..10);
    setof(int) P[Tasks] = [{}, {1}, {2}, {1}, {4,3}, {4,3}, {4,3}, {6}, {8}, {5,7,9}];
    // {} means no predecessor
    
    
    // Resource usage matrix
    int u[J][R] = [[2],[5],[5],[5]]; 
    
    // Resource availability
    int a[R]= [10];
    
    // Decision Variables
    dvar boolean x[J][T];
    
    dexpr int CT = sum(j in J, t in EF[j]..LF[j])t*x[j][t];
    minimize CT;
    
    subject to {
      forall(j in J)
        ct1:sum (t in EF[j]..LF[j]) x[j][t] == 1;
      forall(j in J) forall(predj in P[j]) // assuming 0 indicates no predecessor
        sum (t in EF[j]..LF[j]) x[j][t] * t >=
            sum (t in EF[predj]..LF[predj]) x[predj][t] * (t + d[predj]);
      forall(r in R, t in 1..Tbar) {
        ct3:sum(j in J) u[j][r] * sum(q in maxl(t, EF[j])..minl(t + d[j] - 1, LF[j])) x[j][q] <= a[r];
      }
    }