考虑一个涉及一组任务的优化问题,目标是找到这些任务的特定顺序。
我想用遗传算法解决这个问题,其中每个染色体对应这五个任务的特定顺序,所以每个基因在对应于一个任务.
所以,例如,和将是对应于两个不同任务顺序的两条染色体。
在这种情况下,我们如何设计变异和交叉操作,以便在进化过程中保持这些约束?
遗传算法应该产生三个最佳染色体或任务顺序。
考虑一个涉及一组任务的优化问题,目标是找到这些任务的特定顺序。
我想用遗传算法解决这个问题,其中每个染色体对应这五个任务的特定顺序,所以每个基因在对应于一个任务.
所以,例如,和将是对应于两个不同任务顺序的两条染色体。
在这种情况下,我们如何设计变异和交叉操作,以便在进化过程中保持这些约束?
遗传算法应该产生三个最佳染色体或任务顺序。
如果我理解正确,您的问题是关于使用遗传算法找到执行一系列任务以最大化结果的最佳方式。
简而言之,您正在尝试解决推销员问题。
如果我是正确的,您正在寻找允许您使用有序元素集的交叉和变异算法。对于这些场景,您通常会选择经典的 PMX(部分映射交叉)和交换突变。但是,还有很多其他的交叉算法可以使用 OX1、OX2(基于 Order Based Crossover 的两种变体)、Shuffle Crossover、Ring Crossover 等。让我们从变异开始,这样更容易。
为简单起见,我将有序基因组表示为整数数组:int[] genome = {1, 2, 3, 4, 5};
交换突变
这个概念非常基本:要突变一个有序的基因组,你只需交换两个元素。简单。
public int[] InterchangeMutation(int[] genome)
{
int i1 = random.Next(0, genome.Length);
int i2 = random.Next(0, genome.Length);
var copy = genome.ToArray(); //just making a copy here
copy[i1] = genome[i2];
copy[i2] = genome[i1];
return copy;
}
PMX 变体交叉
这有点复杂,因为我们必须考虑重复。根据经验,我喜欢使用部分映射分频器的这种变体。它比原来的更容易实现(你可以在网上找到论文),但它会花费更多的计算复杂性。基因组越长,您付出的代价就越高。
public int[] PMX2Crossover(int[] P1, int[] P2)
{
//Initializing child genome
int[] child = new int[P1.Length];
for (int i = 0; i < P2.Length; i++) child[i] = -1;
//Step1: getting random section to copy over
int i1 = random.Next(0, P1.Length);
int i2 = random.Next(0, P1.Length);
//Step 2: Copying over section from P1
for (int i = Math.Min(i1, i2); i < Math.Max(i1, i2); i++) child[i] = P1[i];
//Step 3A: Copying values from P2
for (int i = 0; i < P2.Length; i++) if (child[i] ==-1 && !child.Contains(P2[i])) child[i] = P2[i];
//Step 3B: Copying values from P1
for (int i = 0; i < P2.Length; i++) if (child[i] == -1 && !child.Contains(P1[i])) child[i] = P1[i];
//Step 3C: Copying remaining values from P1
int emptyGene = child.IndexOfFirst(-1);
while (emptyGene != -1)
{
child[emptyGene] = FirstMissingGene(P1, child);
emptyGene = child.IndexOfFirst(-1);
}
return child;
}
private int FirstMissingGene(int[] parent, int[] child)
{
foreach (var gene in parent) if (!child.Contains(gene)) return gene;
return -1; // should never get here
}
您可以简单地使用跟踪已添加到子项的基因的哈希图将交叉的复杂性降低到 O(n)(从 O(n*n))。
要获得第一个孩子的电话PMX2Crossover(P1, P2);,第二个只需交换父母PMX2Crossover(P2, P1);
希望这对您有所帮助。
资料来源:我做过一段时间的人工智能学士教授。
您可以使用np.random.choiceshuffle 数组。您可以使用距离度量来查找作为当前良好集合的突变体的新数组。