我试图在我的排列中解决遗传算法中的交叉问题。
假设我有两个20个整数的排列。我想交叉他们让两个孩子。父母内部有相同的整数,但顺序不同。
例:
Parent1:
5 12 60 50 42 21 530 999 112 234 15 152 601 750 442 221 30 969 113 134
Parent2:
12 750 42 113 530 112 5 23415 60 152 601 999 442 221 50 30 969 134 21
让它成为那样 - 我怎样才能让这两个孩子中的孩子?
你在寻找什么 有序交叉。对旅行商问题有一个解释 这里。
这是 一些Java代码 实现部分映射交叉(PMX)变体。
交叉的选择取决于整数的顺序或绝对位置对于适应性是否重要。在 HeuristicLab (C#)我们已经实现了文献中发现的几个流行的,包括:OrderCrossover(2个变种),OrderBasedCrossover,PartiallyMatchedCrossover,CyclicCrossover(2个变种),EdgeRecombinationCrossover(ERX),MaximalPreservativeCrossover,PositionBasedCrossover和UniformLikeCrossover。它们的实现可以与HeuristicLab.Encodings.PermutationEncoding插件中的科学源一起找到。 ERX仅对TSP或类似TSP的问题有意义。 CX是基于位置的,PMX部分位置部分基于订单,但更多的是位置。 OX完全基于订单。
请注意,我们的实现假设一个连续的编号排列,整数从0到N-1。您必须先将它们映射到此范围。
根据我对遗传算子的研究和实现。存在许多类型的交叉算子用于顺序编码(即不允许重复基因,如同 TSP)。总的来说,我认为有两个主要的家庭:
ERX家族
邻居列表用于存储父母双方中每个节点的邻居。然后,仅使用列表生成子项。众所周知,ERX更多 尊重和等位基因的传播,这基本上意味着基因之间的联系不太可能被打破。
类似ERX的运营商的例子包括: 边缘重组(ERX),Edge-2,Edge-3,Edge-4和Generalized Partition Crossover(GPX)。
类似OX的分频器
选择两个交叉点。然后,点之间的基因在两个父母之间交换。由于不允许重复,每个交叉提出了避免/消除重复的技术。这些交叉运算符比ERX更具破坏性。
类似OX的交叉示例: 订单交叉(OX),最大防腐交叉(MPX)和部分映射交叉(PMX)。
第一个家族(ERX)在普通遗传算法中表现更好。而第二族更适合于混合遗传算法或模因算法(使用局部搜索)。 这张纸 详细解释。
在旅行销售问题(TSP)中,您希望订单访问城市列表,并且您希望仅访问每个城市一次。如果您直接在基因组中编码城市,那么天真的交叉或突变通常会产生无效的行程。
我曾经提出过一种解决这个问题的新方法:我不是直接在基因组中编码解决方案,而是编码一个转换,重新排序一个规范的值列表。
鉴于基因组[1,2,4,3,2,4,1,3],你可以从任意顺序的城市列表开始,按字母顺序排列:
- 亚特兰大
- 波士顿
- 芝加哥
- 丹佛
然后,您将从基因组中获取每对值,并在这些位置交换城市。因此,对于上面的基因组,你将交换1和2中的那些,然后是4和3中的那些,然后是2和4中的那些,最后是1和3中的那些。你最终得到:
- 丹佛
- 芝加哥
- 波士顿
- 亚特兰大
使用此技术,您可以使用任何类型的交叉或变异操作,并始终获得有效的巡视。如果基因组足够长,则可以探索整个解空间。
我已经将它用于TSP和其他优化问题并取得了很大的成功。