Проблема с ограничениями переменных двоичного решения в VRP - PullRequest
0 голосов
/ 08 мая 2020

Я хотел бы создать нелинейные издержки нарушения в моем VRP. Я уже создал весь свой VRP со временем windows, в котором у меня есть следующие переменные решения:

dvar float+ w[N][D]; // violation time for late arrivals for every node and every day

Эти двары работают, но теперь я хочу установить связь с переменными решения о стоимости нарушения, которые :

dvar boolean a1[N][D];// no violation 
dvar boolean a2[N][D];// soft violation of 0-5 minutes
dvar boolean a3[N][D];// soft violation of 6-10 minutes
dvar boolean a4[N][D];// soft violation of 11 -15 minutes 
dvar boolean a5[N][D];// soft violation of 15+ minutes

Я хочу принудительно:

a1[N][D] to be 1, when w[N][D] <=0, 0 otherwise
a2[N][D] to be 1, when w[N][D] >0 & <=5, 0 otherwise
a3[N][D] to be 1, when w[N][D] >5 & <=10, 0 otherwise
a4[N][D] to be 1, when w[N][D] >10 & <=15, 0 otherwise
a5[N][D] to be 1, when w[N][D] >=16, 0 otherwise

Тогда у меня есть:

  forall(i in N, d in D)
  (a1[i][d] + a2[i][d] + a3[i][d] + a4[i][d] + a5[i][d]) == 1;

Однако с этими ограничениями все еще что-то не так.

forall(i in N, d in D)
  (a1[i][d] + a2[i][d] + a3[i][d] + a4[i][d] + a5[i][d]) == 1; //sum of all a's = 1

forall(i in N, d in D)
  w[n][d]<= (5*a2[i][d]) + 1000*(1-a2[i][d]); // a2 == 1 when w[n][d]>0 & <=5

forall(i in N, d in D)
  (6*a3[i][d] - 1000*(a3[i][d]-1))<= w[i][d]; // a3

forall(i in N, d in D)
   w[i][d] <= (10*a3[i][d]) + 1000*(1-a3[i][d]); // a3

forall(i in N, d in D)
  (11*a4[i][d] - 1000*(a4[i][d]-1))<= w[i][d]; //a4

forall(i in N, d in D)
   w[i][d] <= (15*a4[i][d]) + 1000*(1-a4[i][d]); // a4

forall(i in N, d in D)
  (16*a5[i][d] - 1000*(a5[i][d]-1))<= w[i][d]; //a5

он устанавливает a5 == 1 для всех ограничений.

Кроме того, w используется в модели как:

forall (i in N, d in D:q[i][d]>=1)
y[i][d] - w[i][d] <= sl[i][d]; // late arrival time soft

где y [i] [d] - переменная времени прибытия

1 Ответ

1 голос
/ 09 мая 2020

если вы хотите, чтобы w было отрицательным, иногда вы должны иметь

dvar int w[N][D]; 

вместо

dvar int+ w[N][D];

Плюс вы можете использовать логические ограничения вместо большого M с жестко запрограммированным 1000

range N=1..2;
range D=1..3;

dvar boolean a1[N][D];
dvar int w[N][D] in -10..10;

subject to
{
// a1[N][D] to be 1, when w[N][D] <=0, 0 otherwise
forall(n in N,d in D) a1[n][d]==(w[n][n] <=0);
}
...