遺傳演算法初步探析

2021-06-05 14:02:40 字數 4195 閱讀 9136

貌似遺傳演算法看起來挺神秘的,但要真正初步的了解一下它的大概思想還是挺簡單的。我只想用最通俗的話和最簡單的程式設計來講講遺傳演算法。

先來求解乙個最簡單的問題,求解f(x)=x*2的最大值 , x屬於[0,31];即求解x的平方在[0,31]的最大值.現在我們用遺傳演算法來求解這個題目。

先解釋一下生物界的一些基礎知識:

1:染色體和基因,染色體可以理解為一段字串編碼,唯一的表示個體的特徵的,如1001,就表示乙個染色體,1,0,0,1這樣的就是基因

2:選擇,就是比較合適環境的個體生存下來,不合適環境的個體會被淘汰,

3:交叉,也就是繁殖,就是乙個個體遺傳父母的基因,有好基因,也有不好的基因,如下面

1001   1000  

他們兩個個體第4位交叉後變為下面的 

1000   1001

4:變異,也就是這個個體的基因會產生突變,如1001變為1000就是突變

現在我們可以做上面的題目了,我們要求[0,31]中x的平方最大值,按照遺傳演算法的邏輯,適者生存,即要讓計算機盡量選擇「適者」,排除「不適者」,在這個題目「適者」就是x的平方比較大的x值。當然首先要把x變成染色體,也就是編碼,編碼可以有很多種方式,最簡單的就是二進位制編碼。如31編碼為1111;

確定編碼規則後就可以按照下面的步驟來寫**了,總共有四步:

1:初始化

//遺傳演算法建構函式

public ga()

chromosome[i] = s;//這是初始化種群大小,即一開始有多少個體,我這裡選擇4個string array = new string[4];

} gcount = 0; //全域性變數,表示當前第幾代,先不用管

// print("初始化:");

}

初始化完了,我們有4個初始個體了,為了分析,假如我們隨機得到了下面四個染色體:

10010   11000   10101    00101

現在要根據這4個隨機的個體找到31這個最大的x值,便有了以下的三大步驟,即遺傳演算法的主要步驟:

2:選擇,從上面4個染色體中選擇

//選擇

void select()

} if(fitarray[max]>bestfit)

chromosome[min] = chromosome[max];

print("選擇後:");

}//求染色體x的適應度函式

double fit(string x)

我們根據染色體的適應度來選擇留下來的染色體,在我們上面的4個染色體中:

10010   11000   10101    00101

根據適應度函式x的平方,(11000)的平方最大,即適應度最大,(00101)的平方最小,即適應度最小,所以00101會淘汰,被替換成11000,因此,經過選擇步驟後,我們的染色體變成了

10010   11000   10101    11000

3:交叉

//交叉

void cross()

char cr = new char[4][5];

//隨機產生4個染色體中哪兩個需要交叉

int a = r.nextint(4);

int b = r.nextint(4);

for(int i=0;i<4;i++)

//隨機產生交叉的位置j和l,因為染色體為5位,所以值要小於5

int j = r.nextint(5);

int l = r.nextint(5);

if(l10010   11000   10101    11000

如果是第乙個和第三個染色體的第2位到第4位進行交叉,即上面**中(a=0,b=2,j=1,l=3),交叉後得到

10100   11000   10011    11000

這是我們經過交叉後得到的結果,當然交叉不是每一次迭代都需要,還需要一定的概率,後面會說到。

4:變異

//變異

void variation()else

chromosome[i] = new string(c);

print("變異後:");

}

以常識來講,變異的操作概率更低,但假如我們這次發生了變異,還是用上面的資料:

10100   11000   10011    11000

如果是第四個染色體的第三位發生了變異,即會變為:

10100   11000   10011    11100

以上是所以一次迭代的操作,即一次生物繁殖的過程,當然,我們會經過很多次的迭代來最終得到31(即11111)這個最大值,如下

5:迭代求最終結果

public static void main(string args) 

system.out.println("最好的適應度:"+bestfit+" 最好的值;"+bestchromosome);

}

以下給出迭代開始和迭代結束的一些結果,僅供參考:

初始化:

01100

11000

01010

00110

選擇後:

01100

11000

01010

11000

交叉後:

01100

11000

01010

11000

第幾代..1

選擇後:

01100

11000

11000

11000

交叉後:

01000

11000

11000

11100

第幾代..2

選擇後:

11100

11000

11000

11100

交叉後:

11000

11000

11100

11100

變異後:

11000

11000

10100

11100

................................

選擇後:

11111

11111

11111

11111

交叉後:

11111

11111

11111

11111

第幾代..998

選擇後:

11111

11111

11111

11111

第幾代..999

選擇後:

11111

11111

11111

11111

交叉後:

11111

11111

11111

11111

第幾代..1000

最好的適應度:961.0 最好的值;11111

這樣我們就得到我們想要的值11111(即31)

有些人可能會疑惑,經過這些操作,為什麼能夠得到這個31最大值呢?理一下思路,一開始,計算機是隨機得到4個[0,31]的值,然後選擇操作會把x的值越來越推進最優解,但是這個是臨時的最優解,重新選擇四個個體:

10010   11000   10001    01001

這裡的最優解是11000,想象一下,如果一直只進行選擇操作,而不進行交叉和變異操作,最後的結果會是:

11000    11000    11000    11000  

因為111000是這裡的最優,最後所有的不合適的解都會被11000給替換。交叉又起了什麼作用呢?假如在上面的四個個體中在進行選擇的同時也進行交叉操作,最後的結果會是:

11011   11011   11011   11011

還是得不到我們想要的值11111,為什麼會這樣呢?大家可以想象一下,因為在我們的染色體中,第三位都是0,第三位無論怎麼進行選擇和交叉操作,都不會變,這樣我們還是得不到我們想要的值,接下來是變異發揮作用的時候。相信大家都已經很明白了,因為變異也是隨機的,只要變異的次數夠多,總會把其中乙個染色體的第三位變成1,這樣再進行選擇,交叉操作的時候就能夠得到11111了。至於最後有關選擇,交叉,變異的範圍以及它怎麼影響到最後的結果我會在「

模式和遺傳演算法的搜尋機制」中講到,其中牽涉到模式和遺傳演算法的搜尋域問題。

遺傳演算法(1) 初步認識

最近學習了遺傳演算法,嘗試著把它按照理解寫下來。對於遺傳演算法從名字上就可以看出來是和生物有關的東西,可以認為是和生物進化有關係,在生物進化裡面又有一句話叫 物競天擇,適者生存。也就是說受環境的影響,最終會留下那些能適應環境的生物。如果從生物學裡面進行考慮可能會涉及到 一堆的概念名詞,如 染色體,個...

python遺傳演算法 Python 遺傳演算法實現

關於遺傳演算法 遺傳演算法是仿照自然界中生物進化而產生的一類優化演算法。個人感覺遺傳演算法簡單粗暴,適應性廣。關於遺傳演算法的介紹網上有很多了,這裡按照我自己的理解簡單概括一下。編碼解碼,將待優化的引數編碼為dna序列,最簡單直接的為二進位制編碼 即有兩種鹼基的dna鏈 生成隨機初代 選擇,適應度 ...

遺傳演算法 python 簡書 遺傳演算法

優化的演算法有很多種,從最基本的梯度下降法到現在的一些啟發式演算法,如遺傳演算法 ga 差分演化演算法 de 粒子群演算法 pso 和人工蜂群演算法 abc 舉乙個例子,遺傳演算法和梯度下降 梯度下降和遺傳演算法都是優化演算法,而梯度下降只是其中最基礎的那乙個,它依靠梯度與方向導數的關係計算出最優值...