遗传算法二进制编码负整数

时间:2013-04-22 22:44:18

标签: c genetic-algorithm

我正在尝试实现遗传算法,以最大化n个整数变量x1..xn的函数,其中每个变量属于[-n,n]范围。我正在考虑使用二进制编码来表示染色体,但我不确定如何编码负整数。我已经搜索了很长一段时间,但我没有遇到二进制编码的常见公式。 在遗传算法的[-n,n]范围内编码整数的最常用方法是什么? 我希望交叉和变异具有更少的复杂性(更少的条件检查)。如果对于初始填充,而不是在-n和n之间生成数字,我会生成从0到2n的数字并以二进制编码它们然后在解码时,我每次都减去n(对于每个后续生成)吗? / p>

1 个答案:

答案 0 :(得分:2)

user1765444的答案很有道理......我只是阅读了sashkello的建议(使用偏移二进制文件可以消除不得不在GA内部使用签名的内容)。使用shashkello和user1765444的答案组合进行交叉和变异等很容易。问题是如果您的数据类型的宽度大于您的范围,那么交叉可能会产生无效的子级。

假设int32具有您需要的宽度。然后是int32数组[n]。你知道有32n位,所以你可以随机取m的交叉点,其中m> = 0且m <1。 32N。您知道位m出现在数组[m / n]中,位位置m%n从msb开始(想象数组只是一个长二进制字符串)。

然后说你有2个父亲int32 parent1 [n]和int32 parent2 [n]。像下面的伪ish代码?在这个交叉中,为了交叉,字符串只是一个二进制字符串(即符号位被视为另一个位)......

免责声明:很抱歉,以下代码粗略准备,未编译,因此可能包含错误......只是想一想!

int child1[n];
uint32 m = rand_like_func(); // random cross over point, a bit position
                             // in the binary string of length n*32;
uint32 arraySlotForCrossOvr = (uint32)(m / n);
uint32 bitInSlotForCrossOvr = 31 - m % n;
uint32 maskForCrossOvrP2 = (1 << bitInSlotForCrossOvr) - 1;
uint32 maskForCrossOvrP1 = ~maskForCrossOvrP2;

// crossover to create child 1
memcpy(child1, parent1, arraySlotForCrossOvr);
child1[arraySlotForCrossOvr] = 
    (int32)( ((uint32)parent1[arraySlotForCrossOvr] & maskForCrossOverP1) |
             ((uint32)parent2[arraySlotForCrossOvr] & maskForCrossOvrP2) )
memcpy(
    child1, 
    parent2 + arraySlotForCrossOvr + 1, 
    total_num_slots - arraySlotForCrossOvr);

然后你可能必须检测超出范围的孩子,或者让超出范围的孩子在下一轮中得分为零。也许你可以用一些智能来增加交叉,比如将无效值限制到最接近的有效值等?

希望有帮助吗?

此外,我发现“如何解决它:Z. Michalewicz和D Fogel的现代启发式”在尝试理解问题的编码时非常有用:)