按位交叉两个整数

时间:2012-07-29 00:56:44

标签: javascript bit-manipulation genetic-algorithm

我目前正在尝试实现一个非常简单的遗传算法示例。

有一次,你必须用两个数字(父母)做一个“交叉”(生物学)才能得到一个“孩子”。

您可以在此处找到交叉的解释:

How to "crossover" two strings (1234 & abcd -> 12cd & ab34)

(第二个例子,更容易的“一点”交叉是我正在尝试做的。)

染色体(父母和孩子)是数字,但“交叉”将有点操作。

我找到了一条“染色体”的解决方案,其中包括:

  • 将位X移动到右侧(>>>运算符)
  • 然后再次移动位X位,但这次是向左移动(<<运算符)

因此,这将保留其中一条染色体的末端并以0开头填充。

但我真的不知道如何解决另一条染色体的问题,然后也做了交叉。

(一旦我保留染色体的开始/结束并用0填充其余部分,可能是异或。)

或者我是否应该从另一个角度处理这个问题?

2 个答案:

答案 0 :(得分:4)

如果交叉的分数是p(例如,p = .25),那么这应该有效:

mask1 = ((0xffff >> 16*p) << 16*p)
mask2 = 0xffff ^ mask1
output1 = (input1 & mask1) ^ (input2 & mask2)
output2 = (input1 & mask2) ^ (input2 & mask1)

几点说明:

  • 这只是伪代码。你可能想要一些演员阵容。
  • 这种处理方式与您在上述评论中对待的方式不同。 (只需用1-p替换p即​​可得到p的定义。)

答案 1 :(得分:1)

一种天真的方法是使用4个局部变量:

int chromatid1Start;
int chromatid1End;
int chromatid2Start;
int chromatid2End;

然后,将传入的chromatid1分配给前两个变量,将chromatid2分配给最后两个变量。

chromatid1Start = chromatid1;
chromatid1End = chromatid1;
chromatid2Start = chromatid2;
chromatid2End = chromatid2;

Start染色单体变量执行右移直到交叉点,然后左移相同的量。在End染色单体变量上,向左移动到交叉点,然后右移相同的数量。

chromatid1Start = (chromatid1Start >> 16 * crossoverPercent) << 16 * crossoverPercent;
chromatid1End = (chromatid1End << 16 * (1 - crossoverPercent)) >> 16 * (1 - crossoverPercent);
chromatid2Start = (chromatid2Start >> 16 * crossoverPercent) << 16 * crossoverPercent;
chromatid2End = (chromatid2End << 16 * (1 - crossoverPercent)) >> 16 * (1 - crossoverPercent);

通过这种方式,你可以跨越另一个的结尾:

int daughterChromatid1 = chromatid1Start + chromatid2End;
int daughterChromatid2 = chromatid2Start + chromatid1End;