Как добавить ограничения PuLP во временных диапазонах, которые не моделируются как переменные

В настоящее время я работаю над сложной задачей планирования, включающей большое количество параметров и переменных решения. Короче говоря, я пытаюсь распределить ресурсы по задачам на основе емкости, сложности, доступного времени и потенциального времени выполнения.

У меня есть матрица Av,j,t, которая определяет, сколько ресурсов назначено работе j в проекте v во время t, а также переменные Sv,j и Ev,j, которые определяют время начала и окончания каждой работы по проекту. . Математически все ограничения имеют смысл, но у меня большие проблемы с моделированием некоторых из них.

Чтобы гарантировать, что распределение заданий происходит только между начальным и конечным периодами задания, я применил ограничения:

pulp.lpSum([A[t][v][j] for t in [t0 for t0 in T if t0 >= S[v][j]]]) == P[v][j]
pulp.lpSum([A[t][v][j] for t in [t0 for t0 in T if t0 <= S[v][j] - 1]]) == 0
pulp.lpSum([A[t][v][j] for t in [t0 for t0 in T if t0 >= E[v][j] + 1]]) == 0

где Pv,j — общее время выполнения задачи с одним ресурсом. Моя основная проблема с ограничениями такого рода заключается в том, что время начала и окончания являются переменными модели, а T (набор времен) — нет. Попытка применить это ограничение в модели оказывается проблематичной, потому что Sv,j на самом деле не инициализируется во время установки ограничений, поэтому это ограничение на самом деле ничего не делает, поскольку набор

[t0 for t0 in T if t0 >= S[v][j]]

не меняется вместе с моделью. У меня также установлен индикатор для отслеживания завершения задания, Xv,j,t, который равен 1 для t > Ev,j и 0 в противном случае. Я пытался реализовать это несколькими способами, но все они основаны на суммах множеств t в T, которые не корректируются при корректировке модели.

Есть ли у кого-нибудь идеи о том, как я могу заставить эти наборы приспосабливаться к самой модели?


person or-math    schedule 20.08.2020    source источник


Ответы (1)


Все ограничения должны быть линейными. То, что вы пытаетесь указать, является нелинейным, поэтому не допускается.

Вместо этого вам нужно смоделировать что-то вроде:

                       t   1 2 3 4 5 6 7 8 9 10 11
   job is executing  x(t)  0 0 0 0 1 1 1 1 0 0 0 
   job is starting   s(t)  0 0 0 0 1 0 0 0 0 0 0 
    

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

   s(t) >= x(t)-x(t-1)
   sum(t, s(t)) <= 1      (one start allowed)
   sum(t, x(t)) = joblen

Чтобы получить время начала и окончания:

   S = sum(t, t*s(t));
   E = S + joblen - 1

Это достаточно стандартный подход. Это может быть упомянуто в вашем учебнике.

person Erwin Kalvelagen    schedule 20.08.2020
comment
Большое спасибо, очень ценю понимание - настолько застрял в математике модели, что пропустил необходимое условие линейности для ограничений :) - person or-math; 21.08.2020