对于我试图创建的遗传算法,我实现了一种变异机制,但它非常粗糙:
for (int j = 0; j < number_of_variables - 1; j++)
{
std::uniform_int_distribution<int> mutation(0, 20);
int mutation_outcome = mutation(rng);
if (mutation_outcome == 1)
{
new_individuals[k].chromosomes[0].at(j) = dist(rng);
}
}
它实际上做的是创造一个20%的机会来改变其中一个&#34;基因&#34;在我个体中,基因都是双倍的。
它的工作正常,但我真正想做的是能够改变底层的位。
例如,我有一个双值-6.57885
的基因,转换网站告诉我的是0000000011000000000110100101000010111110000011011110110100101000
位。
答案 0 :(得分:1)
要翻转一个随机位,从1开始,左移一个介于0和63之间的随机数,然后将其与双重异或:
编译的例子,根据马克B指出的那样调整你不能异或的事实:
#include <stdlib.h>
double mutate(double input)
{
long double_as_long = *(long*)&input;
int bit_index = rand() % 63; //you must call srand(seed) somewhere first
long mutator = 1 << bit_index;
long output = double_as_long ^ mutator;
return *(double*)&output;
}
根据所需的突变程度,你可以在一个循环中随机调用这个次数。
我希望这会有所帮助。
编辑:我以rand()
为例来获取位索引,但我强烈建议您使用更好的随机数生成器。
另一个编辑:
位操作员说明:
左移运算符(<<
)将数字中的所有位向左移动指定的次数:
1 << 3
0001 becomes 1000
XOR运算符,又称异或,(^
)“翻转”位,其中设置为1:
1001 ^ 0100 = 1101
0010 ^ 0011 = 0001