【发布时间】:2015-09-05 17:29:02
【问题描述】:
假设我想最小化一系列城市之间的旅行距离:
开始游览:S-1-2-3-4-5-E
最佳游览:S-5-1-2-3-4-E
行程必须以S 开始,必须以E 结束,但可以按任意顺序游览其间的城市。在我的用例中,S 和 E 之间的城市数量将在 1 到 35 之间。
我目前使用的启发式是重复的两次选择(以伪javascript显示):
minStopSequence = ['S', 1, 2, 3, 4, 5, 'E'];
changed = true;
while (changed === true) {
changed = false;
for (i = 1; i < minStopSequence.length - 2; i++) {
for (j = i + 1; j < minStopSequence.length - 1; j++) {
newStopSequence = reverseTheMiddleSection(minStopSequence, i, j);
newSegmentDur = getDuration(newStopSequence);
if (newSegmentDur < minSegmentDur) {
minSegmentDur = newSegmentDur;
minStopSequence = newStopSequence;
changed = true;
}
}
}
}
这通常无法找到最佳解决方案(例如,它不会在上面的示例中找到最佳游览)。我尝试通过移位来增加它(对于每个索引,对于每个长度,将该段移动到末尾),但是这样做会导致两个问题:
- 我重复一些旅行的可能性(效率低下)
- 我仍然没有达到最佳状态,即使在 5 个城市的小型旅行中也是如此
我已经看到 lin-kernighan-helsgaun 算法在尺寸 http://www.researchgate.net/profile/Daniel_Karapetyan/publication/227414913_Lin-Kernighan_heuristic_adaptations_for_the_generalized_traveling_salesman_problem/links/02e7e527676733456d000000.pdf p.11),但我不确定如何使其适应我的使用案子。
如果可以使用这种启发式方法,您能帮我弄清楚如何实现它吗?如果不是,那么对于最小问题(例如 n
【问题讨论】:
-
看起来(在我第一次通读时)像这样正在做一个简单的爬山(或在这种情况下下降)启发式。这很容易陷入局部最小值而不是找到全局最小值。您可能需要一些其他操作员,即使这样,您也可能需要允许一些非改进的解决方案被接受,以使您摆脱本地最小值。但是你需要更多的基础设施来实现这些,最终得到像禁忌或模拟退火这样的东西。
-
是有道理的,至少直觉上我一直认为必须有一个更简单的解决方案,因为问题的规模很小。也许不是:-/
-
这就是这类问题的原因之一。它们看起来很简单,但实际上它们可能非常困难。在您的 subtour 上添加更复杂的运算符可能会有所帮助,但随后很难在它们之间进行选择(因为您的 subtour 中有更多可能的更改要尝试 - 首先改进更改,在 N 次尝试或所有可能的尝试中找到的最佳更改,等等)并记录您使用过或未使用过的那些,以避免骑自行车。在这里有很多乐趣,还有很大的发挥空间。
标签: javascript algorithm optimization mathematical-optimization traveling-salesman