【问题标题】:Traveling salesman ampl旅行推销员放大器
【发布时间】:2018-10-03 20:25:23
【问题描述】:

我正在处理一个旅行推销员问题,但不知道如何解决它。问题包含十个工人,十个应该开车去的工作场所和一辆接一辆的汽车。每公里收费1.5美元。此外,所有节点(包括工人和工作场所)都位于 10*10 矩阵中,矩阵中每个块之间的距离为 1 公里。
该问题应使用 AMPL 解决。

我已经在 excel 中计算了每个坐标之间的距离,并将矩阵复制粘贴到 AMPL 中的 dat.file 中。

 This is my mod.file so far (without the constrains): 

    param D > 0;
    param D > 0;
    set A = 1..W cross 1..D; 

    var x{A};   # 1 if the route goes from person p to work d, 
               # 0 otherwise

    param cost;
    param distance;

    minimize Total_Cost:
        sum {(w,d) in A} cost * x[w,d]; 

【问题讨论】:

  • x如何指定路由?它标识了哪些人去哪个工作场所,但不是按照什么顺序。您可能想要寻找更符合您要查找的内容的表示。
  • 好点,我也忘了写 x 应该是二进制的,这是因为汽车不应该在同一条路线上行驶两次。问题还在于指定了所有路由,但没有指定它们之间的路由,所以我不知道我应该如何在 AMPL 中编写它。另外我知道解决方案只能在 AMPL 中解决,并且不需要计算与 excel 的距离,但我认为这可能更容易。需要很多帮助...
  • 我不太清楚这里的问题。每个工人是否已经被分配到特定的工作,或者该分配是否是问题的一部分?汽车可以同时搭载多名工人,还是需要先将每个工人停在他们的工作场所,然后再接下一个?
  • 每个工人都被分配到一个特定的工作,是的。有一辆汽车接走一名工人,然后将他送到他的工作场所,然后再接下一辆。我们现在已经设法找到了一条路线,但不知道如何消除 subtours。感谢您的回复!

标签: ampl


【解决方案1】:

好的,所以您的路线如下所示: start-worker 1-job 1-worker 2-job 2-worker 3-job-3-...-job 10-end(给予或获取起点和终点,具体取决于关于你如何制定问题。

在这种情况下,您的路线的“worker n-job n”部分是预先确定的。您不需要在路线优化中包含“worker n-job n”成本,因为对于路线的这些部分没有选择(当然,您需要记住它们以计算总成本)。

所以你在这里实际上是一个基本的 TSP,它有 10 个“目的地”(每个目的地代表一个工人及其分配的工作),但成本矩阵不对称(因为从工作 i 到工人 j 的旅行成本不是与从工作 j 到工人 i 的旅行成本相同)。

如果您已经有基本 TSP 的实现,那么它应该很容易适应。如果没有,那么您需要编写一个并为不对称成本矩阵进行微小的更改。我在 AMPL 中看到了两种不同的方法。

具有子路径消除的二维决策矩阵

决策变量 x{1..10,1..10} 定义为:如果路线从作业 i 到作业 j,则 x[i,j] = 1,否则为 0。约束要求此矩阵的每一行和每一列都只有一个 1。

这种方法具有挑战性的部分是防止 subtours(即产生的“路线”实际上是两个或多个单独的循环而不是一个大循环)。听起来你目前的尝试是在这个阶段。

subtours 问题的一种解决方案是迭代方法:

  1. 编写一个包含所有要求的实现,除了 subtour 预防。
  2. 用这个实现解决。
  3. 检查生成的解决方案是否有子游览。
  4. 如果没有找到子路线,则返回解决方案并结束。
  5. 如果您确实找到了子游览,请添加一个约束以阻止该特定子游览。 (确定子游览中涉及的弧,并设置一个约束,暗示它们不能全部被选中。)然后转到#2。

对于一个小练习,您也许可以手动进行 subtour 消除。对于更大的练习,或者如果您的讲师不喜欢这种方法,您可以创建一个 .run 使其自动化。有关实施示例,请参阅 Bob Fourer 于 2013 年 7 月 31 日在this thread 中的帖子。

具有时间维度的 3-D 决策矩阵

在这种方法下,您设置一个决策变量 x{1..10,1..10,1..10},其中 x[i,j,t] = 1 如果路线从作业 i 到工人j 在时间 t,否则为 0。然后,您的约束要求该路线往返每个工作/工人组合恰好一次,如果它在时间 t 去工人 i,那么它必须去 工作 i在时间 t+1(第一个/最后一个问题除外),它在时间 t 只做一件事,并且时间 10 的端点与时间 1 的起点匹配(假设您想要一个电路)。

这可以防止子旅游,因为它强制一条路线从时间 1 的某个点开始,在时间 10 返回到该点,并且不会多次访问任何其他点 - 这意味着它必须经过所有它们恰好一次。

【讨论】:

  • 谢谢,这非常有帮助!
猜你喜欢
  • 1970-01-01
  • 2011-09-08
  • 2015-04-28
  • 2017-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
相关资源
最近更新 更多