Cplex Refiner: Как добавить существующие ограничения только для левой или правой руки? - PullRequest
0 голосов
/ 30 января 2019

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

Поэтому я бы хотел разделить каждое ограничение матрицы на отдельные ограничения.левша и правша.Пример:

10 <= x1 <= 40

должно превратиться в

10 <= x1 <= infinity
-infinity <= x1 <= 40

, что математически равно.

В примере IBM об уточнении cplex (http://www -01.ibm.com / support / docview.wss? Uid = swg21429472 ) этот фрагмент кода используется для учета ограничений:

for (int c1 = 0; c1 < rng.Length; c1++)
{
    constraints[c1] = rng[c1];
}

Я немного обновил его, чтобы разделить ограничения (обратите внимание: пример IBM интенсивно использует индекс массива ограничений. Также необходимо обновить все эти locs)

for (int c1 = 0; c1 < rng.Length; c1++)
{
    constraints[c1] = cplex.Ge(rng[c1].Expr, rng[c1].LB);
}
for (int c1 = 0; c1 < rng.Length; c1++)
{
    constraints[rng.Length + c1] = cplex.Le(rng[c1].Expr, rng[c1].UB);
}

Это файл модели, который я использовал.(Границы x1 находятся в конфликте с c3 и c4, очевидно).

 Maximize
      obj: x1 + 2 x2 + 3 x3
 Subject To
      c1:  x2 + x3 <= 20
      c2: x1 - 3 x2 + x3 <= 30
      c3: x1 <= 40
      c4: x1 >= 40
 Bounds
      10 <= x1 <= 10    
 Generals
      x1 x2 x3
 End

Обновленная версия кода с разделенными ограничениями выводит неверные результаты (сначала левые, затем правые).он только показывает, что x1 является частью конфликта (ты не можешь быть конфликтом сам по себе. ему нужен приятель!)

Solution status = Infeasible
Model Infeasible, Calling CONFLICT REFINER
Number of SOSs=0
IloRange  : -infinity <= (1*x2 + 1*x3) <= infinity
IloRange  : -infinity <= (1*x1 - 3*x2 + 1*x3) <= infinity
IloRange  : -infinity <= (1*x1) <= infinity
IloRange  : 40 <= (1*x1) <= infinity
IloRange  : -infinity <= (1*x2 + 1*x3) <= 20
IloRange  : -infinity <= (1*x1 - 3*x2 + 1*x3) <= 30
IloRange  : -infinity <= (1*x1) <= 40
IloRange  : -infinity <= (1*x1) <= infinity
Lower bound of x1
Upper bound of x1
Lower bound of x2
Upper bound of x2
Lower bound of x3
Upper bound of x3
Conflict Refinement process finished: Printing Conflicts
 Proved : Upper bound of x1
Conflict Summary:
 Constraint conflicts = 0
 Variable Bound conflicts = 1
 SOS conflicts = 0
Calling FEASOPT

Исходная версия с ограничениями для обеих рук печатает ожидаемыйрезультаты (c4 и x1 являются частью конфликта)

Solution status = Infeasible
Model Infeasible, Calling CONFLICT REFINER
Number of SOSs=0
IloRange c1 : -infinity <= (1*x2 + 1*x3) <= 20
IloRange c2 : -infinity <= (1*x1 - 3*x2 + 1*x3) <= 30
IloRange c3 : -infinity <= (1*x1) <= 40
IloRange c4 : 40 <= (1*x1) <= infinity
Lower bound of x1
Upper bound of x1
Lower bound of x2
Upper bound of x2
Lower bound of x3
Upper bound of x3
Conflict Refinement process finished: Printing Conflicts
 Proved : IloRange c4 : 40 <= (1*x1) <= infinity
 Proved : Upper bound of x1
Conflict Summary:
 Constraint conflicts = 1
 Variable Bound conflicts = 1
 SOS conflicts = 0
Calling FEASOPT

1 Ответ

0 голосов
/ 31 января 2019

В документации для RefineConflict указано следующее для параметра cons:

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

В вашем измененном фрагменте вы добавляете новые ограничения в массив constraints, для которых не добавлено в модель (Например, вы используете метод Ge, а не AddGe).

Я думаю, вы могли бы сделать что-то вроде следующего:

cplex.Remove(rng); // First remove the original constraints
for (int c1 = 0; c1 < rng.Length; c1++)
{
    IRange tmp = rng[c1];
    // Now, add new constraints to the model and save them in the constraints array.
    constraints[c1] = cplex.AddGe(tmp.Expr, tmp.LB);
    constraints[rng.Length + c1] = cplex.AddLe(tmp.Expr, tmp.UB);
}

Вы должны добавить следующую строку простоперед вызовом RefineConflict, чтобы убедиться, что измененная модель выглядит так, как вы ожидаете:

cplex.ExportModel("modified.lp");
...