遗传算法停止突变



>我目前正在尝试使我的遗传算法"生成"或"进化"到给定的单词。问题是,它永远不会完全达到这个词,它停止在太高的适应度分数上,即使它应该继续变异。

下面是一个示例:

用户输入 ="HelloWorld">
500 代后 = "XelgoWorfd">

而且我不知道为什么它不会继续变异。通常,它应该通过随机更改字符串中的一些字符来恢复。

因此,我很高兴能得到一些帮助。

下面是一个基本的分步说明:

  1. 使用完全随机字符串创建 20 条染色体
  2. 计算与目标词相比的健身分数。 (计算ASCII差异)
  3. 以最高分配对两条染色体。
  4. 随机
  5. 改变一些染色体(更改随机字符串字符)
  6. 杀死90%的弱者,并用精英染色体(目前具有最佳适应度分数的染色体)代替它。
  7. 重复一切。

所以这是我的算法最重要的方法:

public Chromoson[] mate(string gene) {
Console.WriteLine("[MATING] In Progress : "+gens+" "+gene);
int pivot = (int)Math.Round((double)gens.Length / 2) - 1;
string child1 = this.gens.Substring(0, pivot) + gene.Substring(pivot);
string child2 = gene.Substring(0, pivot) + this.gens.Substring(pivot);
Chromoson[] list = new Chromoson[2];
list[0] = new Chromoson(child1);
list[1] = new Chromoson(child2);
Console.WriteLine("[MATING] Pivot : "+pivot);
Console.WriteLine("[MATING] Children : "+child1+" "+child2);
return list;
}
public void mutate(float chance, int possiblyChanges) {
if (random.Next(0,101) <= chance) return;
int changes = random.Next(0, possiblyChanges + 1);
//int index = (int) Math.Floor((double)random.Next() * this.gens.Length);
for (int i = 0; i < changes; i++) {
int index = random.Next(0, 13);
StringBuilder builder = new StringBuilder(gens);
int upOrDown = random.Next(0, 101);
if (upOrDown <= 50 && (int)builder[index] > 0 && chars.Contains(Convert.ToChar(builder[index] - 1)))
builder[index] = Convert.ToChar(builder[index] - 1);
else if (upOrDown >= 50 && (int)builder[index] < 127 && chars.Contains(Convert.ToChar(builder[index] + 1)))
builder[index] = Convert.ToChar(builder[index] + 1);
else
mutate(chance, possiblyChanges);
gens = builder.ToString();
}
Console.WriteLine("[MUTATING] In Progress");
}
public void calculateCost(string otherGens)
{
int total = 0;
for (int i = 0; i < gens.Length; i++)
{
total += (((int)gens[i] - (int)otherGens[i]) * ((int)gens[i] - (int)otherGens[i])) * (i*i);
}
Console.WriteLine("[CALCULATING] Costs : " + total);
this.cost = total;
}

你的时间步骤中有些东西完全不对劲:

  1. 使用完全随机的字符串创建 20 条染色体。似乎还可以。
  2. 计算与目标词相比的健身分数。(计算ASCII差异)。似乎还可以。
  3. 以最高分配对两条染色体。什么?你只繁殖两条最适者染色体来创造新的种群?这意味着您将拥有一个几乎完全相似的人口。按比例繁殖,因此所有基因组都有机会生育后代
  4. 随机
  5. 改变一些染色体(更改随机字符串字符)
  6. 杀死90%的弱者,并用精英染色体(目前具有最佳适应度分数的染色体)代替它。你杀了90%?所以基本上,你每次迭代都保留 2 个最好的基因组,然后用步骤 1 替换其他 18 个?你想要的是在第 3 步保持 2 个最适者,并通过繁殖创造其他 18 个个体。
  7. 重复一切。

因此,请将步骤更改为:

初始化。初始化种群,创建 20 条随机染色体

  1. 计算每个染色体的分数
  2. 将两条最适者染色体保存到下一个种群(又名精英主义),通过按比例繁殖适应性来获得其他 18 个需要的个体
  3. 一定几率突变染色体
  4. 重复

不要每轮都随机创建个人。这会将您的算法变成随机搜索。

你的变异和计算成本函数很奇怪。特别是,mutate() 看起来被困在局部最小值中。任何向上或向下的突变都会比精英更糟糕(它们可能是相同的,所以交叉不会改变任何东西)。使用不同的突变:选择一个随机索引并完全更改它。同时从 cost() 中删除 i*i。

最新更新