我是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)!
问题在某种程度上很简单。我试图尽可能多地对变量进行分组,以最大化输出并满足所有约束条件。
你能帮我理解一下吗?
答案 0 :(得分:3)
以下是模型的清理版本:
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 Either-或constraints 下的Integer Programming Tricks。我知道这是违反直觉和痛苦的。您偶然发现if
- then
用于不同目的,并不意味着与变量一起使用。
如果您使用的是CPLEX,则可以非常直观地表达if
- then
限制:
disable: x = 1 ==> y + z = 0;
它应该工作;不幸的是,我没有安装CPLEX,所以我无法测试它。