Запуск решения несколько раз - PullRequest
0 голосов
/ 05 мая 2020

Мне нужно выполнить сборку три раза. Каждый раз решение должно иметь разные входные данные из разных столбцов кортежа. Вот почему мне нужно получить доступ к переменной l oop в OPL в качестве параметра, и мне нужно изменять этот параметр с каждым l oop. Подскажите, пожалуйста, как это сделать в ODM OPL. (Я могу сделать это при запуске автономной модели с физическим файлом .dat, введя int в файл dat и изменив его значения с каждым l oop, но это невозможно при работе через приложение ODM).

Ответы [ 2 ]

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

То, что написал Даниэль, прекрасно работает. Если вы не хотите иметь ненужный файл .dat, вы можете написать

sub.mod

tuple T {
  int round1;
  int round2;
}
T t = <1, 2>;

int param = ...;

dvar float x;

minimize x;
subject to { x >= param; }

, а затем в другой модели, которая будет основной:

tuple T {
  int round1;
  int round2;
}
T t = <1, 2>;

main {
  thisOplModel.generate();
  var src = new IloOplModelSource("sub.mod");
  var def=new IloOplModelDefinition(src);
  var data = new IloOplDataElements();;
  for (var i = 0; i < 2; ++i) {
    if (i == 0)
       data.param = thisOplModel.t.round1;
    else
       data.param = thisOplModel.t.round2;
    var opl = new IloOplModel(def, cplex);
    opl.addDataSource(data);
    opl.generate();
    cplex.solve();
    writeln("Round " + i + ": " + cplex.getObjValue() + ", " + data.param);
    opl.end();
  }
}

, что даст

Round 0: 1, 1
Round 1: 2, 2

и

tuple T {
  int round1;
  int round2;
}
T t = <1, 2>;

int solutions[0..1];

main {
  thisOplModel.generate();
  var src = new IloOplModelSource("sub.mod");
  var def=new IloOplModelDefinition(src);
  var data = new IloOplDataElements();;
  for (var i = 0; i < 2; ++i) {
    if (i == 0)
       data.param = thisOplModel.t.round1;
    else
       data.param = thisOplModel.t.round2;
    var opl = new IloOplModel(def, cplex);
    opl.addDataSource(data);
    opl.generate();
    cplex.solve();
    writeln("Round " + i + ": " + cplex.getObjValue() + ", " + data.param);
    thisOplModel.solutions[i]=opl.x.solutionValue;
    opl.end();
  }

  writeln(thisOplModel.solutions);
}

, чтобы ответить на ваш следующий вопрос о заполнении таблиц

, что дает

Round 0: 1, 1
Round 1: 2, 2
 [1 2]
1 голос
/ 06 мая 2020

Вы можете сделать это с помощью скриптовой функции main():

.dat файл:

param = 0; // This value is actually never used

.mod файл:

tuple T {
  int round1;
  int round2;
}
T t = <1, 2>;

int param = ...;

dvar float x;

minimize x;
subject to { x >= param; }

main {
  thisOplModel.generate();
  var def = thisOplModel.modelDefinition;
  var data = thisOplModel.dataElements;
  for (var i = 0; i < 2; ++i) {
    if (i == 0)
       data.param = thisOplModel.t.round1;
    else
       data.param = thisOplModel.t.round2;
    var opl = new IloOplModel(def, cplex);
    opl.addDataSource(data);
    opl.generate();
    cplex.solve();
    writeln("Round " + i + ": " + cplex.getObjValue() + ", " + data.param);
    opl.end();
  }
}

код сценария изменяет данные перед созданием новой модели на каждой итерации. У вас есть более сложная версия кода, подобная этой в примере cutstock_main.mod, который поставляется с CPLEX.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...