美文网首页
创建种群的代码3--繁殖

创建种群的代码3--繁殖

作者: 大龙10 | 来源:发表于2022-08-14 00:04 被阅读0次

    书名:代码本色:用编程模拟自然系统
    作者:Daniel Shiffman
    译者:周晗彬
    ISBN:978-7-115-36947-5
    第9章目录

    9.7 创建种群的代码3

    第3步:繁殖

    • 交配池已经准备好了,下面我们要开始新个体的繁殖。
      首先要选择双亲,我们可以用随机的方式选择它们,这符合生物繁殖的特征,传统GA也是采用这种方式。
      但对我们而言,选择父本并没有任何限制:可以用“无性”繁殖的方式实现,也可以选择3个或4个父本合成子代DNA。
      在代码演示中,我想用两个父本,并分别称为parentA和parentB。

    • 首先,我们要生成两个随机数作为交配池的下标,这是一个介于0至ArrayList长度之间的随机数。

    int a = int(random(matingPool.size()));
    int b = int(random(matingPool.size()));
    
    • 接下来,我们从交配池中取出这两个下标对应的DNA对象。
    DNA parentA = matingPool.get(a);
    DNA parentB = matingPool.get(b);
    
    • 交配池中的同一个对象可能会有多个实例(我们也肯重复选中某个随机数),因此parentA和parentB可能是同一个DNA对象。如果要严谨地对待这个问题,我们可以加入一些检查代码,确保不选中同一个对象;但是这么做并不会带来很大的效益
    • 得到双亲后,下面我们就开始执行交叉和突变过程。
    DNA child = parentA.crossover(parentB); 交叉函数 A
    child.mutate(); 突变函数
    
    • 当然,crossover()函数和mutate()函数需要我们自己来实现。从上面的调用方式可以看出,crossover()函数的参数是DNA对象,它的返回值是一个新的DNA对象,也就是子代个体。
    DNA crossover(DNA partner) { 函数的参数是DNA对象,返回值也是DNA对象
    DNA child = new DNA(); 子代是新的DNA对象,DNA在构造函数中是用随机方式初始化的,但我们会
    int midpoint = int(random(genes.length)); 在基因数组中选择随机的“中间点
    for(int i = 0; i < genes.length; i++) {
        if (i > midpoint) child.genes[i] = genes[i]; 中间点之前和之后的基因来自不同的父
            else child.genes[i] = partner.genes[i];
        }
        return child; 返回子代DNA
    }
    
    • 上述crossover()函数的实现使用了“随机中间点”方法,子代基因的第一部分取自parentA,第二部分取自parentB。
    • mutate()函数比crossover()函数更容易实现。我们只需要遍历基因数组,根据突变率为每个字符随机选择一个新字符。举个例子,如果突变率为1%,我们将有1%的概率选择一个新字符。
    float mutationRate = 0.01;
    void mutate() {
        for (int i = 0; i < genes.length; i++) { 遍历数组中的每个基因
        if(random(1) < mutationRate) {这里的代码有1%的机会执行
            genes[i] = (char) random(32,128); 突变,产生随机字符
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:创建种群的代码3--繁殖

          本文链接:https://www.haomeiwen.com/subject/hpvzwrtx.html