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



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

user1765444的回答很有意义…我刚刚读了sashkello的建议(使用偏移二进制可以消除GA内部的有符号整数)。这样做交叉和变异等将很容易-使用shashkello和user1765444的答案的组合。问题是,如果数据类型的宽度大于范围,那么交叉可能会产生无效的子类型。

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

然后假设你有两个父母int32 parent1[n]和int32 parent2[n]。类似下面的伪代码?在这个交叉中,字符串只是一个二进制字符串,因为交叉(即符号位被视为另一个位)…

免责声明:对不起,下面的代码是粗糙的,未编译的,所以可能包含错误…只是一个想法!

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

那么你可能需要检测超出范围的子节点,或者让超出范围的子节点在下一轮得分为0。也许你可以用一些智能来增强交叉,比如将无效值限定为最接近的有效值等?

希望有帮助?

此外,我发现"如何解决它:Z. Michalewicz和D . Fogel的现代启发式"在试图理解问题编码等方面非常有用

最新更新