首页 文章

遗传算法停止变异

提问于
浏览
0

我目前正试图让我的遗传算法“生成”或“演化”到一个给定的单词 . 问题是,它永远不会完全达到这个词,它会停留在一个太高的 Health 分数,即使它应该继续变异 .

下面是一个例子:

用户输入=“HelloWorld”500代后=“XelgoWorfd”

我不知道为什么它不会继续变异 . 通常它应该随着字符串中的一些字符随机改变而恢复 .

所以我会很乐意提供一些帮助 .

这是一个基本的逐步说明:

  • 使用完全随机化的字符串创建20个染色体

  • 计算与目标词相比的 Health 分数 . (计算Ascii ID差异)

  • 将两个染色体配对得分最高 .

  • 随机改变一些染色体(改变随机字符串字符)

  • 杀死90%的弱人群并用精英染色体取代它(具有当前最佳 Health 评分的染色体) .

  • 重复一切 .

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

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;
}

2 回答

  • 1

    在你的时间步骤中完全没有东西:

    使用完全随机化的字符串创建20个染色体 . 好像没问题 . 计算与目标词相比的 Health 分数 . (计算Ascii id的差异) . 好像没问题 . 将两个染色体配对得分最高 . 什么?你唯一培育出两条最适合的染色体来创造新的种群?这意味着你的人口几乎完全相似 . 按比例增加适应性,因此所有基因组都有机会有一个后代随机突变一些染色体(改变随机字符串)杀死90%的弱群体并用优良染色体(具有当前最佳 Health 分数的染色体)取而代之 . 你杀了90%?所以基本上,你每次迭代都要保留2个最佳基因组,然后用步骤1替换其他18个基因组?你想要的是在步骤3保持2适合性,并通过育种创造其他18个个体 . 重复一切 .

    所以改变你的步骤:

    INIT . 初始化群体,创建20个随机染色体计算每个染色体的得分将两个最适合的染色体保存到下一个群体(又称精英主义),通过按比例繁殖健身获得其他18个需要的个体以一定的机会重复染色体重复

    不要每轮都创造随机个体 . 这会将您的算法转换为随机搜索 .

  • 1

    你的mutate和calculateCost函数很奇怪 . 特别是,mutate()看起来被设计为陷入局部最小值 . 任何突变上升或下降将比精英更糟糕(它们可能相同,因此交叉不会改变) . 使用不同的mutate:选择一个随机索引并完全更改它 . 同时从cost()中删除i * i .

相关问题