逐渐增加突变的概率

时间:2013-11-19 15:36:52

标签: java genetic-algorithm probability-theory mutation

我正在实现与遗传算法非常相似的东西。因此,您经历了多代人口 - 在一代人的最后,您可以通过三种不同的方式“随机”,“突变”和“交叉”创建新的群体。

目前概率是静态的,但我需要做到这一点,以便突变的概率逐渐增加。我很欣赏任何方向,因为我有点卡住..

这就是我所拥有的:

int random = generator.nextInt(10);
if (random < 1)  
    randomlyCreate() 
else if (random > 1 && random < 9 )
    crossover(); 
else  
    mutate();

谢谢。

3 个答案:

答案 0 :(得分:1)

在if语句中,用变量替换硬编码数字,并在每一代开始时更新它们。

你的if语句有效地将0到10的区间分成三个区间。调用mutate() vs crossover() vs randomlyCreate()的概率取决于每个bin的大小。您可以通过逐渐移动垃圾箱的边界来调整突变率。

在您的代码中,mutate()被称为20%的时间,(当random = 9或1时),randomlyCreate()被称为10%的时间(当random = 0时)和{{ 1}}被称为另外70%的时间。

以下代码在第0代开始时使用相同的比率,但每代的突变率增加1%。因此对于第1代,突变率为21%,对于第2代,突变率为22%,依此类推。无论突变率如何,crossover()的频率都是randomlyCreate()的1/7。

您可以通过更改crossover()来提高变异率的二次,指数或任何形式。

我在下面的代码中使用了浮点数。双打也会起作用。

如果突变率是你最感兴趣的,那么移动突变箱可能会更直观,因为它最初位于[0,2],然后从那里增加其上限(2.1,2.2,等等)。然后你可以很容易地读出变异率(21%,22%等)。

getMutationBoundary()

答案 1 :(得分:0)

使用您当前使用9的变量,并且(例如)每次尝试乘以0.9,除非mutate()发生,在这种情况下,您将其乘以{ {1}}例如。这样,突变的机会缓慢但呈指数增长(是的,这是可能的),直到它们实际发生变异,此时另一个突变的机会像砖块一样下降并且过程重新开始。

这些值是完全随机的,不是基于任何有关变异的知识,但我只是向您展示如何操纵它以便每次都有变量值。另外:如果您使用我刚才使用的内容,请确保变量的值设置为10(如果超过10)。

答案 2 :(得分:0)

对操作符的任何遗传概率选择都是任意的(如果使用某些函数来增加或减少概率,也是有效的)。更好地编码染色体内的操作员。例如,您可以添加一些位来编码您使用的所有运算符。生成子项时,您可以查看这些位中所有元素的位数,并将运算符的概率设置为等于全局中运算符的当前情况。

例如:

void adaptive_probabilities(GA *ga, long chromosome_length) {
    register int i, mut = 1, xover = 1, uxover = 1, ixover = 1, pop;
    char bit1, bit2;

    for (i = 0; i < ga->npop; i++) {
        bit1 = ga->pop[i]->chromosome[chromosome_length - 2];
        bit2 = ga->pop[i]->chromosome[chromosome_length - 1];

        if (bit1 == '0' && bit2 == '0') {
            mut++;
        } else if (bit1 == '0' && bit2 == '1') {
            xover++;
        } else if (bit1 == '1' && bit2 == '0') {
            uxover++;
        } else if (bit1 == '1' && bit2 == '1') {
            ixover++;
        }
    }

    pop = ga->npop + 4;

    ga->prob[0] = mut / (float)pop;
    ga->prob[1] = xover / (float)pop;
    ga->prob[2] = uxover / (float)pop;
    ga->prob[3] = ixover / (float)pop;
}

在我的情况下,我使用两位,因为我的染色体编码四个操作符(三种类型的交叉+突变)。操作符的位位于染色体末端。所有概率都是> 0(运算符的计数器从1开始)然后我必须用

正确地标准化所有概率
pop = ga->npop + 4;

然后,我生成一个随机数,用于根据计算出的数据ga-&gt; prob中保存的概率选择运算符。更改新子节点的最后位以反映使用的运算符。

这种机制确保了GA的双重搜索:在错误空间(像往常一样)和运算符空间中。概率自动更改并进行优化,因为在计算的任何时刻使用最佳运算符生成子项的概率更高。