AMPL关于TSPTW的逻辑代码

时间:2018-01-15 11:40:01

标签: ampl

我正在研究这个AMPL代码(TSPTW:https://github.com/inter0509/TSPTW)。 这是用时间窗解析TSP的代码(我希望......)

  • rank:binary-matrix(2x2) - >如果rank [i,j] == 1,则将该弧从“node-i”变为“node-j”
  • constrain11:节点中只有一个弧
  • 约束12只有一个来自节点的弧
  • constrain13:必须选择arc到node-0到node-0
  • constrain21:为什么会有那段代码(“+ sum {i in V,j in V:i!= j}}(c [i,j])* y [i,k-1,j,k ];?“)
  • constrain31 / 32/33:我不知道..
  • constrain4:你必须在总和{j in V}之后到达(r [j] * rank [j,k]);
  • constarin5:你没有在sum {j in V}之前离开节点(d [j] * rank [j,k]);

  • “r”:抵达时的小时

  • “d”:离开节点时的小时
  • “p”:您必须在节点中停留数小时。

这是对的吗?我想不...

1 个答案:

答案 0 :(得分:0)

尝试使用无信息的变量名解释未注释的代码有点痛苦,但我想我已经弄明白了。

在先前在相同位置呈现的tsp.mod中,存在二元决策变量x {V,V},当且仅当路径从节点i到节点j时,其具有x [i,j] = 1。

在tsptw.mod中有一个二元决策变量等级{V,V},所以我们可能期望它在前一个模型中的工作方式与x {V,V}相同,但事实并非如此。

相反,当且仅当节点j是推销员巡回中要访问的第k个城市时,等级[j,k] = 1。例如,如果等级[8,3] =等级[5,4] =等级[12,5] = 1,那么游览中的第三个城市是城市#8,第四个城市是#5,第五个城市是城市#12,依此类推。

城市从0到n编号,因此这个问题实际上有n + 1个城市。

决策变量start [j]表示“游览顺序中第j个城市的开始时间”:例如如果rank [8,3] = 1,则start [3]给出我们在城市#8开始的时间。 (开始城市的计数从0开始。)

r和d代表每个城市允许的最早开始时间和最晚结束时间(以城市的数字ID为索引,而不是在旅行中的订单)。 p代表留在每个城市所需的时间,再次以城市的数字ID为索引。

c [j,k]是从城市j到城市k的时间。

如果旅行中的第k-1个城市是城市i,并且第k个城市是j,则

y [i,k-1,j,k]等于1。 (由约束31-33强制执行。)

打破目标函数:

minimize total_time : start[n]+sum{j in V:j!=0}(c[j,0]*rank[j,n])
+sum{j in V:j!=0} (p[j]*rank[j,n]);
  • start [n]:这只是游览中第n个(最后)城市的开始时间。
  • sum {j in V:j!= 0}(c [j,0] * rank [j,n]):rank [j,n] = 1当且仅当ID为#j的城市为n时游览中的城市,否则为0。 c [j,0]是从该城市到城市#0(开始)的时间。因此,这给出了从第n个(最后一个)城市返回我们开始的地方的旅行时间。
  • sum {j in V:j!= 0}(p [j] * rank [j,n]):这是花在第n个城市所需的时间。

完成约束:

subject to constrain11 {j in V}: sum{k in V} rank[j,k]=1;
subject to constrain12 {k in V}: sum{j in V} rank[j,k]=1;

每个城市必须有一个且只有一个等级(游览中的位置)。对于每个等级,必须只有一个城市被分配到该等级。 (这两个实际上是多余的,但这无关紧要。)

 subject to constrain13: rank[0,0] = 1;

我们从0号城市开始。

subject to constrain21 {k in V2}: start[k] >= 
start[k-1] + sum{i in V}(p[i]*rank[i,k-1])
+sum{i in V,j in V:i!=j}(c[i,j])*y[i,k-1,j,k];

我们在路线上的第k个城市开始的时间必须不小于上一个城市的开始时间,加上我们需要花费在上一个城市的时间,加上之间的旅行费用。第k-1和第k个城市。

subject to constrain22: start[0] = 0; 

在零时开始旅行。

subject to constrain31 {i in V,j in V,k in V2}: y[i,k-1,j,k]<=rank[i,k-1];
subject to constrain32 {i in V,j in V,k in V2}: y[i,k-1,j,k]<=rank[j,k];
subject to constrain33 {i in V,j in V,k in V2}: y[i,k-1,j,k]>=rank[i,k-1]+rank[j,k]-1;

总的来说,如果第k-1个城市访问的是i,那么这些确保y [i,k-1,j,k]为1,并且访问的第k个城市是j,否则它是零。

注意:虽然y在{V,V,V,V2}上编入索引,但大多数索引实际上是不相关的;只有第二个索引小于第四个索引的索引才对问题有任何意义。

subject to constrain4 {k in V2}: start[k] >= sum{j in V}(r[j]*rank[j,k]);

我们开始第k个城市之旅的时间必须大于或等于最早的开始时间(r),无论第k个城市实际是什么(j使得等级[j,k] = 1)。

subject to constarin5 {k in V2}: start[k]+sum{j in V}(p[j]*rank[j,k]) 
<= sum{j in V}(d[j]*rank[j,k]);

我们开始第k个城市的时间加上该城市所需的时间(p),不得超过该城市的最后完成时间(d)。

我没有去寻找错误,所以我不会保证其正确性,但我认为一般方法在这种解释下是有道理的。

如果您发现此答案有帮助,请通过承诺始终评论您的代码并使用信息性变量名称来支付它; - )