Как записать последовательность по ограничениям последовательности для планирования - PullRequest
0 голосов
/ 23 января 2020

Теперь я попытался добавить EQ7: новое ограничение, которое отличает каждый start_pour[k][j] от других start_pour[k][j], равных site_process_time[c], для работающей модели. Он показал расслабленное решение, которое = неосуществимое решение. Как мне написать это ограничение? Спасибо.

 EQ7 :
 forall(c in customer)
   sum(k in truck, j in job)
      (start_pour[k][j] + site_process_time[c] + (M*(1-x[c][k][j]))) <= 
   sum(k in truck, j in job)
      (start_pour[k][j] + (M*(1-x[c][k][j])));

.MOD

 int c =...;
 int k =...;
 int j =...;

 range customer     =   1..c;
 range truck        =   1..k;
 range job          =   1..j;


 float demand[customer]=...;
 float travel[customer]=...;
 float plant_process_time[customer]=...; 
 float site_process_time[customer]=...; 

 float capacity[truck]=...;

 int M=...;


 dvar int+ start_load[truck][job];
 dvar int+ start_pour[truck][job];

 dvar boolean x[customer][truck][job];
 dvar boolean y[customer];

 /***************************************/

 dexpr float Travel_Cost =  sum(c in customer, k in truck, j in job)
                              x[c][k][j];

 dexpr float Penalty_Cost = sum(c in customer)
                              M*y[c];

 minimize   Travel_Cost  + Penalty_Cost;

 /***************************************/

 subject to { 

 EQ2 : //Assignment
 forall(k in truck, j in job)
   sum(c in customer)
     x[c][k][j] <= 1 ;


 EQ3 : //Precedence
 forall(k in truck, j in job : j > 1)
   sum(c in customer)
     x[c][k][j] <=
   sum(c in customer)
     x[c][k][j-1];

 EQ4 : //Demand <= Supply
 forall(c in customer)
   sum(k in truck, j in job)
     x[c][k][j] * capacity[k] >= demand[c] * (1-y[c]);


 EQ5 : //Job-Time Sequencing;
 forall(c in customer, k in truck, j in job)
   start_load[k][j] + plant_process_time[c] + travel[c] <= start_pour[k][j] + (M*(1-x[c][k][j-1]));


 EQ6 : //Job-Time Sequencing;
 forall(c in customer, k in truck, j in job: (j-1) in job)
   start_pour[k][j-1] + site_process_time[c] + travel[c] <= start_load[k][j]+ (M*(1-x[c][k][j-1]));

 }

.DAT

 c = 2;
 k = 2;
 j = 5;

 demand = [10 30];
 travel = [5 10];
 plant_process_time = [1 1];
 site_process_time = [2 2];

 capacity = [4 5];

 M= 100000;

1 Ответ

1 голос
/ 23 января 2020

Чтобы заставить работать модель, вам нужно как минимум изменить

EQ5 : //Job-Time Sequencing;
 forall(c in customer, k in truck, j in job)
   start_load[k][j] + plant_process_time[c] + travel[c] <= start_pour[k][j] + (M*(1-x[c][k][j-1]));

на

EQ5 : //Job-Time Sequencing;
 forall(c in customer, k in truck, j in job:(j-1) in job)
   start_load[k][j] + plant_process_time[c] + travel[c] <= start_pour[k][j] + (M*(1-x[c][k][j-1]));

Тогда вы можете использовать логические ограничения вместо больших M

EQ5 : //Job-Time Sequencing;
 forall(c in customer, k in truck, j in job:(j-1) in job)
(1==x[c][k][j-1] ) => (start_load[k][j] + plant_process_time[c] + travel[c] <= start_pour[k][j]);

Для EQ7 вы можете начать с

EQ7 :
 forall(c in customer)
   forall(ordered k,k2 in truck, ordered  j,j2 in job)

      start_pour[k][j] != start_pour[k2][j2];

или даже

    EQ7 :
 forall(c in customer)
   forall(ordered k,k2 in truck, ordered  j,j2 in job)

     ((1==x[c][k][j] ) && (1==x[c][k2][j2]))=> (abs(start_pour[k][j] -start_pour[k2][j2]) >=plant_process_time[c]);

, если хотите учесть время процесса

И я бы предложил вам иметь взгляните на CPOptimizer в CPLEX, поскольку это очень хорошо для планирования.

...