貌似遺傳演算法看起來挺神秘的,但要真正初步的了解一下它的大概思想還是挺簡單的。我只想用最通俗的話和最簡單的程式設計來講講遺傳演算法。
先來求解乙個最簡單的問題,求解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 舉乙個例子,遺傳演算法和梯度下降 梯度下降和遺傳演算法都是優化演算法,而梯度下降只是其中最基礎的那乙個,它依靠梯度與方向導數的關係計算出最優值...