遗传算法停止变异

时间:2017-05-11 20:02:48

标签: c# algorithm genetic-algorithm

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

以下是一个例子:

  

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

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

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

这是一个基本的逐步解释:

  1. 使用完全随机化的字符串创建20个染色体
  2. 计算与目标词相比的适合度分数。 (计算Ascii id差异)
  3. 将两个染色体配对得分最高。
  4. 随机改变一些染色体(改变随机字符串字符)
  5. 杀死90%的弱势群体并用精英染色体替换它(具有当前最佳健康评分的染色体)。
  6. 重复一切。
  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 个答案:

答案 0 :(得分:1)

在你的时间步骤中,某些事情完全消失了:

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

因此,请将步骤更改为:

  

INIT。初始化群体,创建20个随机染色体

     
      
  1. 计算每个chromsome的得分
  2.   
  3. 将两个最适合的染色体保存到下一个群体(又称精英主义),通过按比例繁殖健身获得其他18个需要的个体
  4.   
  5. 以一定的机会突变chromsomes
  6.   
  7. 重复
  8.   

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