无法推断出AMPL的上限

时间:2014-09-24 13:58:42

标签: optimization mathematical-optimization ampl

我打算进行优化,我希望在受到一些时间限制的系统中最大化流量,并且一些“必须满足这些路线”的限制。第一次约束规定每辆车不得超过24小时的工作量(以分钟表示)。第二次约束是一个小区消除约束,它还说明在“车辆”有时间行驶之前,“访问”节点的启动时间不能被激活等.Constraint3描述了K1和N1之间的道路必须使用不超过9时间,使用任何车辆k。最后一个约束表明来自特定节点的所有车辆必须在一天结束时返回。

 maximize maxamount: sum{i in V, j in V, k in K} x[i,j,k];

 subject to TimeConstraint {k in K}: 
     sum{i in V, j in V} traveltime[i,j]*x[i,j,k] <= 1440; 

 subject to StartTime{i in V,j in V, k in K}:
     starttime[i] + servicetime[i] +traveltime[i,j] - 1300 * (1 - x[i,j,k]) <= starttime[j];

 subject to Constraint3:
     sum{k in K} x["K1","N1",k] <= 9;

 subject to EndNode{k in K}: 
     sum{i in V}x[i,"K1",k] - sum{j in V} x["K1",j,k]= 0;

Constraint3和EndNode还有几个相同类型的约束(仅与其他“预定义位置”有关,例如K1和N2之间的道路不能超过4次访问等等)。

我的问题是我得到了错误Impossible推导的边界x [K1,K1,1]有下限= 0和上限= -76我已经理解这源于冲突的约束。不过我的问题是:怎么样?几乎只使用二进制变量,我不明白为什么上面的代码不起作用。我误解了我在模特中实际做了些什么吗?

我注意到编译器只在i = j时抱怨,所以我检查了我的.dat文件并注意到i和j之间的旅行时间,当i = j时非常大(因此程序不会选择那些路径) )。但是,将.dat文件编辑为不再自动超出TimeConstraints限制仍会给出相同的错误(尽管较小,现在上限为-1而不是-76)。

我希望有人可以对此进行阐述。

提前致谢 Cenderze

1 个答案:

答案 0 :(得分:2)

  

i和j之间的旅行时间,当i = j非常大时(因此程序不会选择那些路线)

如果traveltime[i,j] = M(非常大),StartTime的{​​{1}}读取

i=j

因此,每当servicetime[i] + M - 1300 * (1 - x[i,j,k]) <= 0 <=> 1300 * x[i,j,k] <= 1300 - servicetime[i] - M 时,问题都是不可行的。

我建议使用M > 1300 - servicetime[i]为所有对X定义(i,j)变量,或者i<>j定义(如果问题是对称的)。

跟进评论

以下代码段在插入AMPL Online Editor

时效果很好
i < j

输出:

param n := 10;
set N:= 1..n;
set V := {i in N, j in N: i <> j};
display V;

将您的代码段更改为

set V :=
(1,2)    (2,3)    (3,4)    (4,5)    (5,6)    (6,7)    (7,8)    (8,9)    (9,10)
(1,3)    (2,4)    (3,5)    (4,6)    (5,7)    (6,8)    (7,9)    (8,10)   (10,1)
(1,4)    (2,5)    (3,6)    (4,7)    (5,8)    (6,9)    (7,10)   (9,1)    (10,2)
(1,5)    (2,6)    (3,7)    (4,8)    (5,9)    (6,10)   (8,1)    (9,2)    (10,3)
(1,6)    (2,7)    (3,8)    (4,9)    (5,10)   (7,1)    (8,2)    (9,3)    (10,4)
(1,7)    (2,8)    (3,9)    (4,10)   (6,1)    (7,2)    (8,3)    (9,4)    (10,5)
(1,8)    (2,9)    (3,10)   (5,1)    (6,2)    (7,3)    (8,4)    (9,5)    (10,6)
(1,9)    (2,10)   (4,1)    (5,2)    (6,3)    (7,4)    (8,5)    (9,6)    (10,7)
(1,10)   (3,1)    (4,2)    (5,3)    (6,4)    (7,5)    (8,6)    (9,7)    (10,8)
(2,1)    (3,2)    (4,3)    (5,4)    (6,5)    (7,6)    (8,7)    (9,8)    (10,9);
== 1 ==========================

然后试一试。我明白了:

set N = {'K1', 'K2','K3','K4'};
set V := {i in N, j in N: i != j};
display V

我希望这有帮助!