Как заставить последующую переменную иметь одинаковое значение? - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть двоичная переменная y[k][t], где k = 1..3 (машины) и t = 1..10 (время).Переменная Y равна 1, если машина активна, и 0 в противном случае.

При оптимизации, если машина 1 активна в течение периода 1, например, Y[1][1] = 1, я хочу, чтобы машина продолжала работать в течение как минимум 3 периодов времени.то есть Y[1][1] = Y[1][2] = Y[1][3] = Y[1][4] = 1.

Я хочу, чтобы последовательные переменные для t + 1, t + 2, t + 3 были такими же, как t, если она активна.

как я могу это сделать в cplex studio?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2019

то, что Эрвин написал о минимальной длине пробега, прекрасно.Если вы полагаетесь на логические ограничения, доступные в CPLEX, то модель будет немного проще:

range K=1..3;
range T=1..10;

dvar boolean Y[K][T];
dvar boolean start[K][T];


subject to
{
forall(k in K) start[k][1]==Y[k][1];
forall(k in K,t in T:t!=1) start[k][t] ==  ((Y[k][t]==1) && (Y[k][t-1]==0));

forall(k in K) forall(l in 1..3) 
  forall(t in T:(t+l) in T) (start[k][t]==1) => (Y[k][t+l]==1);


}

Но что может привести к длительному времени решения, если вы увеличиваете временной горизонт, так как мы перечисляем время.В CPLEX и OPL вы также можете использовать CPOptimizer и его специальные концепции планирования: интервалы.

Тогда вы напишите

using CP;

range K=1..3;
range T=1..10;

int nbMaxIntervals=4;

dvar interval itvs[K][1..nbMaxIntervals] optional in T size 3..10;

subject to
{
forall(k in K) forall(i in 1..nbMaxIntervals-1) 
     endBeforeStart(itvs[k][i],itvs[k][i+1]);


}

. То, что вы работаете не менее 3-х периодов времени,

size 3..10;

Примечание: Подробнее о CPOptimizer

0 голосов
/ 25 сентября 2019

Это иногда называют минимальной длиной пробега.Есть разные подходы, чтобы справиться с этим.Скажем, у нас есть x(t) в качестве наших двоичных переменных, указывающих, работает ли машина в момент времени t.Первым делом необходимо ввести двоичную переменную start(t), которая указывает, когда начинается запуск.Вот что я имею в виду:

  t      1 2 3 4 5 6 7 8
  x      0 1 1 1 0 1 1 0
  start  0 1 0 0 0 1 0 0

Запуск начинается, когда x(t-1)=0 and x(t)=1 или, более формально:

start(t) = x(t)*(1-x(t-1)) 

Это нелинейно.Мы можем линеаризовать это, используя:

start(t) <= x(t)
start(t) <= 1-x(t-1)
start(t) >= x(t)-x(t-1)

Часто мы просто используем границу:

start(t) >= x(t)-x(t-1)

Далее нам нужно:

start(t) = 1 ==> x(t)...x(t+K-1) = 1

где K - минимальный пробегдлина.

Это может быть смоделировано как:

x(t+1) >= start(t)
...
x(t+K-1) >= start(t)

(мы уже знаем, что x(t)=1 if start(t)=1).

...