在Ruby中解决旅行商问题(50+个地点)

8
我在一家送货公司工作。我们目前通过“手动”方式解决50多个位置的路线问题。
我一直在考虑使用Google Maps API来解决这个问题,但我已经了解到有24个点的限制。
目前我们在服务器上使用Rails,所以我考虑使用一个Ruby脚本来获取50多个位置的坐标并输出一个合理的解决方案。
你会用什么算法来解决这个问题?
Ruby是解决这种类型问题的好编程语言吗?
你知道任何现有的Ruby脚本吗?

1
你当然意识到这是最难的问题之一了,对吧?没有真正伟大的答案?仍然有合理的解决方案,但只是确保你知道它们真的不会是伟大的 - Matchu
1
我已经添加了标签“旅行推销员”。你尝试过查看该标签下的其他问题吗? - Andrew Grimm
感谢您添加标签...我在stackoverflow上搜索了“旅行推销员”,但没有找到什么有用的信息...我正在寻找一种实际可行的解决方案,用于在单个服务器上执行50多个位置(使用Ruby)...另外,旅行的拼写是双L:traveLLing。 - jfanals
2
请澄清:50个位置是为多少用户/司机/销售人员?它需要实时运行,还是可以安排在晚上运行 - 以便在早上有解决方案? - 公平地说 - 我只是从服务器负载的角度提出这个问题。 - konung
3
这是关于旅行推销员和农夫的50个女儿的老故事吗? - the Tin Man
显示剩余4条评论
6个回答

6

这可能是您正在寻找的内容:

警告:

这个网站被Firefox标记为攻击网站 - 但它并不像是。事实上,我之前使用过没有问题。

[查看URL的修订历史记录]

rubyquiz似乎已经关闭了(已经关闭了一段时间),但是您仍然可以查看WayBack机器和archive.org来查看该页面: http://web.archive.org/web/20100105132957/http://rubyquiz.com/quiz142.html


你建议的URL指向可以下载的多个解决方案...我能够调整Joseph Seaton的一个解决方案的代码以适应我的需求。再次感谢您指出那个网站 :) 我在不到10秒钟的时间内成功得到了一个合理的解决方案... - jfanals
非常欢迎你。顺便说一句,我强烈建议你去探索并尝试解决那里的一些问题 - 这将帮助你成为更好的 Ruby 程序员。当我有时间时,我会每周尝试解决一个问题。 - konung

4

+1!特别是要查看从欧几里得TSP子部分链接的PTAS,或者在http://www.cs.princeton.edu/~arora/pubs/tsp.ps中描述的PTAS(更易于遵循的说明可在http://corelab.ntua.gr/courses/approx-alg/material/Euclidean%20TSP.pdf中获得)。它为您提供了一个多项式时间O(1+1/epsilon)近似算法,适用于任何您喜欢的epsilon(当然,请注意指数随1/epsilon增长)! - Yonatan N

2
以下是几个技巧:
1:将相对接近的位置合并成一个图形,并将这些位置转换为主图中的单个节点。这可以让你贪心而不需要太多工作。
2:使用近似算法。
2a:我最喜欢的是比托尼克旅行。它们很容易破解。
见更新

这里有一个带有比托尼克旅行的py lib另一个
让我去找一个 ruby 的库吧。我发现除了 RGL以外,很难找到更多的库,因为它的效率存在问题....

更新
在您的情况下,最小生成树攻击应该是有效的。我想不出任何情况,使得你的城市不符合三角不等式。这意味着应该有一个相对较快而不错的近似值。特别是如果距离是欧几里得距离,我认为,再一次,它必须是。


1

其中一种优化方案是使用动态规划,但时间复杂度仍然很高 O(2**n),这不太可行,除非你使用一些聚类和分布式计算,否则 Ruby 或单个服务器对你来说并不是很有用。

我建议您采用贪心策略而不是使用 DP 或暴力搜索,这样更容易实现。

一旦程序结束,您可以进行一些记忆化,并将结果存储在某个地方以供以后查找,这也可以节省一些周期。

在代码方面,您需要实现具有权重的顶点、边。

例如:具有带权重的边的顶点类,递归。然后是一个图形类,它将填充数据。


1
暴力破解方法被认为对于超过20个点是不切实际的。对于50个点,他将不得不尝试阶乘(50!)排列 - 每个销售员大约需要尝试30414093201713378043612608166064768844377641568960512000000000000次。 - konung

1
我使用元启发式算法,如蚁群优化来解决Bays29(29城市)问题的TSP问题,它在很短的时间内给出了接近最优解。您可以潜在地使用相同的方法。
尽管我是用Java编写的,但我仍将在此处提供链接,因为我正在努力将其移植到Ruby: Java: https://github.com/mohammedri/ant_colony_java_TSP Ruby: https://github.com/mohammedri/aco-ruby(不完整) 这是它解决的数据集:https://github.com/jorik041/osmsharp/blob/master/Core/OsmSharp.Tools/Benchmark/TSPLIB/Problems/TSP/bays29.tsp

请注意,我使用的是各个城市之间的欧几里得距离,即直线距离。在现实生活中,考虑到道路和城市地图等因素,我认为这并不理想,但它可能是一个很好的起点 :)


0

如果您希望算法生成的解决方案成本在最优解的3/2以内,那么您需要使用Christofides算法。ACO和GA没有保证的成本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接