CPLE Как динамически задать массив переменных решения

Я хочу сформулировать задачу гибкого планирования работы цеха с MIP вместо CP.

Если есть массив с указанием количества операций каждого задания.

num_op = [3, 2, 5]

И Xijk - это переменная решения, указывающая, выполняется ли j-я операция задания i на машине k или нет.

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

Я написал это dvar boolean x[i in Jobs][j in][k in Machs]; и не знаю, как его завершить.

Помогите, пожалуйста. Спасибо!!


person Yuan    schedule 03.11.2019    source источник


Ответы (1)


Если я правильно понимаю ваш пример, то ваше определение num_op указывает на то, что у вас есть три разных задания, первое задание имеет 3 операции, второе - 2 и последнее задание - 5 операций. Это означало бы, что второе измерение Xijk должно измениться в зависимости от первого измерения. Такой гибкий размер массива невозможен с CPLEX.

Вот альтернатива:

  • Определите M как максимальное количество операций (в вашем случае 5).
  • Определить dvar boolean x[i in Jobs][j in 1..M][k in Machs];
  • Явно зафиксируйте все переменные на 0, которые соответствуют несуществующим операциям: forall (i in Jobs, j in 1..M, k in Machs) if (j > num_op[i]) X[i][j][k] == 0;

Последний шаг даже необязателен: вы можете определить переменные для несуществующих операций, но просто не использовать их где-либо в вашей модели (хотя это может дать предупреждение для неиспользуемых переменных).

Другой вариант - создать кортеж tuple { int i; int j; int k }, а затем создать набор кортежей, содержащий все допустимые комбинации i, j, k и индекса X для этого набора кортежей.

person Daniel Junglas    schedule 04.11.2019
comment
Могу я задать вам еще одну проблему? Поскольку мой M будет массивом, как реализовать его в dvar boolean x[i in Jobs][j in 1..M][k in Machs];? Другими словами, я хочу, чтобы он был зубчатым 3D-массивом. И, могу ли я использовать кортеж в качестве переменной решения? Большое спасибо за помощь мне. - person Yuan; 04.11.2019
comment
Я не совсем уверен, как M может быть массивом (это означает максимальное значение в num_op, поэтому это должно быть число). Но в любом случае, если M - массив, вы можете написать j in M вместо j in 1..M. Вы не можете использовать кортеж в качестве переменной решения, но можете использовать кортежи для индексации переменных решения. Это, наверное, то, что вы хотите здесь, - person Daniel Junglas; 04.11.2019
comment
Я написал это: int nbOps[1..3]=[3,2,5]; dvar boolean x[Jobs][j in nbOps][Mchs];Но ошибка говорит, что я не могу использовать int [range] с in. - person Yuan; 04.11.2019
comment
Потому что в моей задаче в каждом задании есть разное количество операций, и каждая операция может выбрать машину из своего набора машин-кандидатов. В результате мне нужна переменная Xijk, чтобы обозначить, выполняется ли j-я операция задания i на машине k или нет. В разных заданиях i разное количество операций. j зависит от работы i. Есть ли у меня какой-нибудь способ смоделировать этот Xijk? Большое спасибо. - person Yuan; 04.11.2019
comment
Почему вы хотите (или должны) моделировать это с помощью 3D-массива? Использование простого массива, индексированного набором кортежей, намного проще на практике и обычно значительно упрощает правильное написание ваших ограничений, а также упрощает интерпретацию результатов. Одно из самых больших препятствий для написания хороших (то есть правильных и читаемых) моделей - это застревание в мысленном ожидании и подходе к мышлению этих моделей в терминах 2D, 3D или более высоких массивов. - person TimChippingtonDerrick; 05.11.2019
comment
Вы можете сделать {int} nbOps = { 3, 2 ,5 }, чтобы оператор in заработал. - person Daniel Junglas; 05.11.2019