按位遍历两个整数

Cross-over two integers bitwise

本文关键字:两个 整数 遍历      更新时间:2024-04-02

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

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

你可以在这里找到Cross-Over的解释:

如何";"交叉";两个字符串(1234&abcd->12cd&ab34)

(第二幅插图,我正试图做的是更容易的"一点"交叉。)

染色体(父母和孩子)是数字,但"交叉"将是一个小运算。

我为其中一条"染色体"找到了解决方案,如下所示:

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

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

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

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

还是我应该从另一个角度来看待这个问题?

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

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

注意事项:

  • 这只是伪代码。你可能想要一些石膏
  • 这与你在上面的评论中对待p的方式不同。(只需将p替换为1-p,就可以得到你对p的定义。)

一个简单的方法是使用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;