在GA中应用变异来解决旅行商问题

时间:2012-09-13 18:54:23

标签: implementation genetic-algorithm traveling-salesman mutation

我正在开展一项小型学术任务,使用遗传算法(GA)解决旅行商问题(TSP)。我正在按照一个非常简单的经典表示来存储城市和阵列中的游览,例如10个城市游览可以表示为9-1-0-4-3-8-6-5-2-7等等。 对GAs有一个相当基础的知识,我对于将不同类型的突变应用于TSP会采用何种方法感到困惑。假设我们的路线表示为路线,变异率用变量m_rate表示。

[1]简单插入突变

说我们有:1-2-3-4-5-6-7-8-9。然后我们选择一个随机城市,比如索引5,然后选择一个像2这样的随机插入索引,然后突变的染色体是:1-2-6-3-4-5-7-8-9。

现在我正在做的是应用变异:

for (int i=0; i<route.length; i++) {
 if (m_rate<Math.random()) {
 // Pick a random city
 int randomCity =  0 + (int)(Math.random() * ( ((route.length-1) - 0) + 1));
 // Do the insertion and shift the array where appropriate
 }
}

换句话说,我循环遍历路线中的每个城市并查看变异条件是否成立(m_rate&gt; Math.random()),如果确实如此,那么我停在那个索引然后随机选择一个插入点使用变异概率变量。 只要未遇到数组的结尾,我就会继续将相同的内容应用于其他所有剩余的城市或索引。 这是正确的方法吗?应用第一次突变后,我应该停止还是突然离开?是否应该以某种方式在选择插入点时涉及变异概率?虽然这对我来说似乎没有多大意义。 如果有可能在染色体或途径中有多个城市发生突变,那么染色体是否有可能被重新植入?换句话说,如果我最终做了第二次或第三次突变,将染色体反转到其初始形态(在变异之前)会发生什么?

[2]互惠交换突变。

在染色体中选择一个随机城市,然后选择第二个随机城市并交换这两个城市。例如,在路线1-5-2-8-0-9-3-7-4-6。如果我们最终选择索引2和索引7,那么突变的染色体是:1-5-7-8-0-9-3-2-4-6。

我通过遍历路线中的每个城市并检查概率条件,然后直接选择随机城市进行交换,而不应用任何类型的突变率,遵循上述插入突变的类似方法。上述同样的问题在这里适用..

[3]倒置突变。

这是最棘手的一个。给定如1-2-3-4-5-6-7-8-9的染色体,我们选择像索引2到索引5的突变切割,然后将该子路径反转==&gt; 1-2-6-5-4-3-7-8-9。

但是你如何申请呢?您是否循环路线然后根据突变率选择一个城市,然后直接选择另一个索引来确定子路由的长度?变异一次并退出?在这种实现中,如果突变切割结束为0-9或0-(长度-1),整个染色体或途径是否可以突变反转整个事物?在这种情况下,突变率的真正价值是什么?我有点迷失在这里......

我提前为此做了太长时间道歉..但我会感谢对这些问题的任何评论,或者如果有人可以指导我进行详细讨论这些事情的任何资源。我看了很多研究论文,但没有多少人研究过这类细节和细节。

谢谢。

3 个答案:

答案 0 :(得分:1)

当您选择突变时,您有几个选择:

  • 您可以允许突变产生无效/非法染色体并对其进行评分。这意味着GA将搜索正确性(清除非法结果)和最佳结果。
  • 您可以编写一个只生成有效/合法输出的变异函数。

第一个选项可以让你写一个更简单,更自然的染色体突变。但是,您可能需要扩展表示(例如,允许您的10个城市游览的12或15个插槽),算法将需要更长时间才能收敛。如果必须评估正确性,您的分数功能可能会更昂贵。您可以灵活地解释染色体的解释方式(例如,忽略第二次出现的目的地)。

第一个选项也可能出于同样的原因简化交叉的实现。

第二个选项通常会更快地收敛,但是可能更难以避免影响结果的突变函数中的微妙偏差。

您建议的表示和突变类似于TSP的非GA近似值,它依赖于交换,然后进行改进测试。模拟退火是决定接受哪种转座的一种方法。

GA实现可能需要完全不同的染色体才能使交叉和突变自然。

答案 1 :(得分:1)

我认为最好的选择是使用转换进行突变和交叉使用OX(有序)。我写了一个用于解决TSP的GA,它的工作非常好。在我的情况下,当应用反演时,我选择两个随机点(它可能是整个字符串)但不是相同的点。最好的结果,其中突变率为0.2 / 0.3,交叉率为0.8但这取决于您的选择机制

答案 2 :(得分:0)

反演通常是解决TSP的最佳工作变异算子。您可以下载并试验HeuristicLab,其中包括更多此类变异运算符和交叉。它允许您定义实验,您可以与每个操作员一起运行GA几次,看看哪种方法效果最好。有一些视频教程可以帮助您入门。它是开源的,因此您也可以查看实现。