Нелинейная оптимизация Minizinc и Cplex

У меня есть простой нелинейный код, встроенный в minizinc, как показано ниже.

array[1..3] of var 1..10:x;
array[1..3] of var 10.0..20.0:y;
var float:z;
constraint sum(i in 1..3)(x[i]*y[i])=z;
solve minimize z;

Если я использую решатель Cplex в фоновом режиме minizinc, у меня появляется ошибка Float_times.

unable to create linear formulation for the `float_times` constraint. This model instance cannot be solved using a linear solver.

Если я конвертирую тот же код в OPL и использую их в IDE IBM ILOG Cplex, он предоставит ответ. Пример кода выглядит следующим образом.

dvar int x[ 1..3]  in 1..10;
dvar float y[ 1..3]  in 10.0..20.0;
dvar float z;
minimize z;
subject to {
cons1:
sum(i in 1..3)x[i]*y[i]==z;
}

Не могли бы вы объяснить, почему это происходит, хотя я использовал один и тот же решатель в обоих бэкэндах.


person suresh_chinthy    schedule 12.06.2020    source источник
comment
Каков лучший решатель, с которым я могу справиться, приведенный выше код minizinc из minizinc IDE.   -  person suresh_chinthy    schedule 12.06.2020
comment
Вы можете попробовать использовать решатели CP, которые поддерживают float_times, например Gecode, JaCoP или OptiMathSAT. Я не уверен, какие MIP-решатели поддерживают float_times. Судя по всему, CPLEX этого не делает. Может, Гуроби?   -  person hakank    schedule 12.06.2020


Ответы (1)


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

execute
{
  cplex.preind=0;
  cplex.optimalitytarget=3;
}

dvar int x[ 1..3]  in 1..10;
dvar float y[ 1..3]  in 10.0..20.0;
dvar float z;
minimize z;
subject to {
cons1:
sum(i in 1..3)x[i]*y[i]==z;
}

работает отлично

Таким образом, вы можете установить эту настройку «цель оптимальности» через minizinc.

Или полагайтесь на логические ограничения / индикаторы

execute
{
  cplex.preind=0;
  //cplex.optimalitytarget=3;
}

dvar int x[ 1..3]  in 1..10;
dvar float y[ 1..3]  in 10.0..20.0;
dvar float z;
dvar float xy[1..3];
minimize z;
subject to {
cons1:
sum(i in 1..3)xy[i]==z;

forall(i in 1..3) forall(j in 1..10) (x[i]==j) => xy[i]==y[i]*j;
}

тоже отлично работает

person Alex Fleischer    schedule 12.06.2020