2

我正在从事一项小型学术任务,以使用遗传算法 (GA) 解决旅行商问题 (TSP)。我正在遵循一个非常简单的经典表示,将城市和旅游存储在数组中,例如,10 个城市的旅游可以表示为 9-1-0-4-3-8-6-5-2-7 等等。对 GA 有相当基本的了解,我对您将遵循哪种方法将不同类型的突变应用于 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>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 的突变切割,然后反转那个子路径 ==> 1-2-6-5- 4-3-7-8-9。

但是你如何应用这个?你是不是循环遍历路线,然后根据突变率选择一个城市,然后直接选择另一个指标来确定子路线的长度?突变一次并退出?在这种实现中,如果我们的突变切割最终是 0-9 或 0-(length-1) ,整个染色体或路线是否可以突变以反转整个事物?在这种情况下,突变率的真正价值是什么?我有点迷失在这里...

我提前道歉,因为它太长了。但我会很感激任何关于这些问题的评论,或者如果有人可以指导我到任何详细讨论这些事情的资源。我看过很多研究论文,但没有多少人接触过这种细节和细节。

谢谢你。

4

3 回答 3

1

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

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

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

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

第二种选择通常会更快地收敛,但可能更难避免影响结果的变异函数中的细微偏差。

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

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

于 2012-09-13T19:45:04.960 回答
1

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

于 2012-09-26T05:18:22.957 回答
0

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

于 2012-09-13T22:46:42.863 回答