>我目前正在尝试使我的遗传算法"生成"或"进化"到给定的单词。问题是,它永远不会完全达到这个词,它停止在太高的适应度分数上,即使它应该继续变异。
下面是一个示例:
用户输入 ="HelloWorld">
500 代后 = "XelgoWorfd">
而且我不知道为什么它不会继续变异。通常,它应该通过随机更改字符串中的一些字符来恢复。
因此,我很高兴能得到一些帮助。
下面是一个基本的分步说明:
- 使用完全随机字符串创建 20 条染色体
- 计算与目标词相比的健身分数。 (计算ASCII差异)
- 以最高分配对两条染色体。 随机
- 改变一些染色体(更改随机字符串字符)
- 杀死90%的弱者,并用精英染色体(目前具有最佳适应度分数的染色体)代替它。
- 重复一切。
所以这是我的算法最重要的方法:
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;
}
你的时间步骤中有些东西完全不对劲:
- 使用完全随机的字符串创建 20 条染色体。似乎还可以。
- 计算与目标词相比的健身分数。(计算ASCII差异)。似乎还可以。
- 以最高分配对两条染色体。什么?你只繁殖两条最适者染色体来创造新的种群?这意味着您将拥有一个几乎完全相似的人口。按比例繁殖,因此所有基因组都有机会生育后代
随机- 改变一些染色体(更改随机字符串字符)
- 杀死90%的弱者,并用精英染色体(目前具有最佳适应度分数的染色体)代替它。你杀了90%?所以基本上,你每次迭代都保留 2 个最好的基因组,然后用步骤 1 替换其他 18 个?你想要的是在第 3 步保持 2 个最适者,并通过繁殖创造其他 18 个个体。
- 重复一切。
因此,请将步骤更改为:
初始化。初始化种群,创建 20 条随机染色体
- 计算每个染色体的分数
- 将两条最适者染色体保存到下一个种群(又名精英主义),通过按比例繁殖适应性来获得其他 18 个需要的个体
有- 一定几率突变染色体
- 重复
不要每轮都随机创建个人。这会将您的算法变成随机搜索。
你的变异和计算成本函数很奇怪。特别是,mutate() 看起来被困在局部最小值中。任何向上或向下的突变都会比精英更糟糕(它们可能是相同的,所以交叉不会改变任何东西)。使用不同的突变:选择一个随机索引并完全更改它。同时从 cost() 中删除 i*i。