2012-07-29 57 views
7

我正在嘗試實現一個非常簡單的遺傳算法示例。按位交叉兩個整數

有一次,你必須做一個「交叉」(生物學)與兩個數字(父母)才能得到一個「孩子」。

你可以找到交叉在這裏的解釋:(第二個圖中,更容易「一點」跨接一個我正在試圖做的)

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

染色體(父母和孩子)是數字,但「交叉」將有點操作。

我發現對於「染色體」中的一個的解決方案,這是這樣的:

  • 移動的位X量向右(>>>操作者)
  • 然後再次移動至位X位置但是這次是在左側(<<運營商)

所以這將保持其中一條染色體的末端,並以0開頭。

但我真的不知道如何解決其他染色體的問題,然後也做交叉。

(可能是XOR一次我保持染色體的開始/結束,並用0填充其餘部分。)

或者我應該甚至從另一個角度來處理這個問題呢?

+0

你總是知道你的兩個輸入有多大的數字(例如,16位整數) ? – David 2012-07-29 01:01:11

+0

是的,它們總是16位整數。可以修改的一件事是交叉百分比。例如,75%將保留父A的前4位(25%),然後從父B的12位(75%)位跟隨這4位。 – 2012-07-29 01:05:42

回答

4

如果跨接的部分爲p(例如,p = 0.25),那麼這應該工作:

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

有兩點要注意:

  • 這僅僅是僞代碼。你可能需要一些演員在那裏。
  • 這對待p不同於你在上面的評論中對待它。 (只是1-P代替p來得到你的P的定義。)
+0

哇,mind = blown!我需要一些時間來理解這段代碼。 ^^感謝您的快速回答! – 2012-07-29 01:15:54

+0

好吧,將0xffff模式向右移動然後向左移動的操作與您在描述中所做的操作相同,因此如果您的p = .5,則mask1將在右移之後變爲0xff,然後在左移之後變爲0xff00背部。將它與0xffff進行異或運算可以獲得掩碼2中未打開的所有位。 – David 2012-07-29 01:18:53

+0

謝謝你的解釋! – 2012-07-29 01:26:02

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;