Оптимизация в AMPL возвращает неправильный результат

Я новичок в AMPL «Математический язык программирования». Я пытаюсь решить некоторые уравнения, но обнаружил, что ответ логически неверен (или, насколько я понимаю!). Итак, мой код выглядит следующим образом (после того, как я обнаружил проблему, мне пришлось упростить его, чтобы понять):

option solver minos;
var x;
var y;
var z;
maximize output: x+y+z;
subject to x_lim: 0<=x<=1;
subject to y_lim: 0<=y<=1;
subject to z_lim: 0<=z<=1;
subject to disable: if x = 1 then (y+z) = 0;
solve;
display output,x,y,z;

Вывод следующий:

output = 1
x = 1
y = 0
z = 0

но если я прав, максимальный вывод должен быть 2 (когда x = 0, y = 1, z = 1).

Теперь, если я изменю порядок объявления переменных:

var y;
var x;
var z;
maximize output: x+y+z;
subject to x_lim: 0<=x<=1;
subject to y_lim: 0<=y<=1;
subject to z_lim: 0<=z<=1;
subject to disable: if x = 1 then (y+ z) = 0;
solve;
display output,x,y,z;

тогда выход становится равным 3 (x=y=z=1) и ограничение (если x = 1, то (y+z) = 0) не выполняется!

Проблема как-то проста. Я пытаюсь сгруппировать как можно больше переменных, чтобы максимизировать результат и удовлетворить все ограничения.

Не могли бы вы помочь мне понять это?


person user3787524    schedule 29.06.2014    source источник


Ответы (1)


Вот очищенная версия вашей модели:

var x binary;
var y >= 0, <= 1;
var z >= 0, <= 1;
maximize output: x + y + z;
disable: y + z <= 2*(1-x);
solve;
display output, x, y, z;

Это печатает:

output = 2
x = 0
y = 1
z = 1

Я предположил, что по крайней мере x является двоичной переменной, иначе ваша модель не имеет для меня особого смысла. Также обратите внимание, как я выразил границы переменных прямо в объявлении, а не как отдельные ограничения.

Проблема с вашей исходной моделью заключается в том, что AMPL — это язык моделирования, а не язык программирования: вы должны выражать if - then иначе, чем в языках программирования. См. Приемы целочисленного программирования в разделе 7.3 Ограничения "или-или"< /эм>. Я знаю, что это нелогично и болезненно. if - then, на которые вы наткнулись, служат другой цели и не предназначены для использования с переменными.

Если вы используете CPLEX, вы можете интуитивно выразить ограничения if-then:

disable: x = 1  ==>  y + z = 0;

Он должен работать; к сожалению, у меня не установлен CPLEX, поэтому я не могу его протестировать.

person Ali    schedule 29.06.2014
comment
Спасибо чувак. Это было отличное объяснение. У меня есть cplex, и я попробовал .. Это сработало: D - person user3787524; 29.06.2014
comment
Отлично, я рад, что это помогло! Если это решило вашу проблему, рассмотрите возможность принятия моего ответа. Принятие ответов: как это работает? - person Ali; 29.06.2014
comment
@ user3787524 Да? Каким будет ваш вопрос? - person Ali; 29.06.2014
comment
если я хочу минимизировать количество групп... каким будет код? в предыдущем примере я хочу, чтобы результат был 2 (это означает 2 группы, первая содержит x, а вторая содержит y и z) - person user3787524; 29.06.2014
comment
@user3787524 user3787524 К сожалению, я не понимаю, но, похоже, это другой вопрос. Пожалуйста, напишите свой вопрос с кодом и объяснением и опубликуйте его как новый вопрос. Не волнуйся, я увижу это. - person Ali; 29.06.2014
comment
Спасибо!! Я буду следовать некоторым методам раскраски графов. Я думаю, это может решить проблему. - person user3787524; 29.06.2014