網絡資料!算法
三:遺傳算法網絡
照例先給出科學定義:函數
遺傳算法(Genetic Algorithm, GA)起源於對生物系統所進行的計算機模擬研究。它是模仿天然界生物進化機制發展起來的隨機全局搜索和優化方法,借鑑了達爾文的進化論和孟德爾的遺傳學說。其本質是一種高效、並行、全局搜索的方法,能在搜索過程當中自動獲取和積累有關搜索空間的知識,並自適應地控制搜索過程以求得最佳解。優化
再給出相關術語:(各位看看就好,後面都會涉及到,再細說)編碼
基因型(genotype):性狀染色體的內部表現;翻譯
表現型(phenotype):染色體決定的性狀的外部表現,或者說,根據基因型造成的個體的外部表現;設計
進化(evolution):種羣逐漸適應生存環境,品質不斷獲得改良。生物的進化是以種羣的形式進行的。指針
適應度(fitness):度量某個物種對於生存環境的適應程度。blog
選擇(selection):以必定的機率從種羣中選擇若干個個體。通常,選擇過程是一種基於適應度的優勝劣汰的過程。繼承
複製(reproduction):細胞分裂時,遺傳物質DNA經過複製而轉移到新產生的細胞中,新細胞就繼承了舊細胞的基因。
交叉(crossover):兩個染色體的某一相同位置處DNA被切斷,先後兩串分別交叉組合造成兩個新的染色體。也稱基因重組或雜交;
變異(mutation):複製時可能(很小的機率)產生某些複製差錯,變異產生新的染色體,表現出新的性狀。
編碼(coding):DNA中遺傳信息在一個長鏈上按必定的模式排列。遺傳編碼可看做從表現型到基因型的映射。
解碼(decoding):基因型到表現型的映射。
個體(individual):指染色體帶有特徵的實體;
種羣(population):個體的集合,該集合內個體數稱爲種羣
的大小。
遺傳算法的有趣應用不少,諸如尋路問題,8數碼問題,囚犯困境,動做控制,找圓心問題(在一個不規則的多邊形中,尋找一個包含在該多邊形內的最大圓圈的圓心),TSP問題,生產調度問題,人工生命模擬等。下面我以袋鼠爲例子講講遺傳算法。(由於袋鼠會跳)
遺傳算法中每一條染色體,對應着遺傳算法的一個解決方案,通常咱們用適應性函數(fitness function)來衡量這個解決方案的優劣。因此從一個基因組到其解的適應度造成一個映射。能夠把遺傳算法的過程看做是一個在多元函數裏面求最優解的過程。能夠這樣想象,這個多維曲面裏面有數不清的「山峯」,而這些山峯所對應的就是局部最優解。而其中也會有一個「山峯」的海拔最高的,那麼這個就是全局最優解。而遺傳算法的任務就是儘可能爬到最高峯,而不是陷落在一些小山峯。(另外,值得注意的是遺傳算法不必定要找「最高的山峯」,若是問題的適應度評價越小越好的話,那麼全局最優解就是函數的最小值,對應的,遺傳算法所要找的就是「最深的谷底」)
問題的提出與解決方案:
讓咱們先來考慮考慮下面這個問題的解決辦法。
已知一元函數:
如今要求在既定的區間內找出函數的最大值
「袋鼠跳」問題
既然咱們把函數曲線理解成一個一個山峯和山谷組成的山脈。那麼咱們能夠設想所獲得的每個解就是一隻袋鼠,咱們但願它們不斷的向着更高處跳去,直到跳到最高的山峯(儘管袋鼠自己不見得願意那麼作)。因此求最大值的過程就轉化成一個「袋鼠跳」的過程。
做爲對比下面簡單介紹「袋鼠跳」的幾種方式。
1. 登山法(最速上升登山法):
從搜索空間中隨機產生鄰近的點,從中選擇對應解最優的個體,替換原來的個體,不斷重複上述過程。由於登山法只對「鄰近」的點做比較,因此目光比較「短淺」,經常只能收斂到離開初始位置比較近的局部最優解上面。對於存在不少局部最優勢的問題,經過一個簡單的迭代找出全局最優解的機會很是渺茫。(在登山法中,袋鼠最有但願到達最靠近它出發點的山頂,但不能保證該山頂是珠穆朗瑪峯,或者是一個很是高的山峯。由於一路上它只顧上坡,沒有下坡。)
2. 模擬退火:
這個方法來自金屬熱加工過程的啓發。在金屬熱加工過程當中,當金屬的溫度超過它的熔點(Melting Point)時,原子就會激烈地隨機運動。與全部的其它的物理系統相相似,原子的這種運動趨向於尋找其能量的極小狀態。在這個能量的變遷過程當中,開始時,溫度很是高, 使得原子具備很高的能量。隨着溫度不斷下降,金屬逐漸冷卻,金屬中的原子的能量就愈來愈小,最後達到全部可能的最低點。利用模擬退火的時候,讓算法從較大的跳躍開始,使到它有足夠的「能量」逃離可能「路過」的局部最優解而不至於限制在其中,當它停在全局最優解附近的時候,逐漸的減少跳躍量,以便使其「落腳 」到全局最優解上。(在模擬退火中,袋鼠喝醉了,並且隨機地大跳躍了很長時間。運氣好的話,它從一個山峯跳過山谷,到了另一個更高的山峯上。但最後,它漸漸清醒了並朝着它所在的峯頂跳去。)
3. 遺傳算法:
模擬物競天擇的生物進化過程,經過維護一個潛在解的羣體執行了多方向的搜索,並支持這些方向上的信息構成和交換。是以面爲單位的搜索,比以點爲單位的搜索,更能發現全局最優解。(在遺傳算法中,有不少袋鼠,它們降落到喜瑪拉雅山脈的任意地方。這些袋鼠並不知道它們的任務是尋找珠穆朗瑪峯。但每過幾年,就在一些海拔高度較低的地方射殺一些袋鼠,並但願存活下來的袋鼠是多產的,在它們所處的地方生兒育女。)(或者換個說法。從前,有一大羣袋鼠,它們被莫名其妙的零散地遺棄於喜馬拉雅山脈。因而只好在那裏艱苦的生活。海拔低的地方瀰漫着一種無色無味的毒氣,海拔越高毒氣越稀薄。但是可憐的袋鼠們對此全然不覺,仍是習慣於活蹦亂跳。因而,不斷有袋鼠死於海拔較低的地方,而越是在海拔高的袋鼠越是能活得更久,也越有機會生兒育女。就這樣通過許多年,這些袋鼠們居然都不自覺地聚攏到了一個個的山峯上,但是在全部的袋鼠中,只有聚攏到珠穆朗瑪峯的袋鼠被帶回了美麗的澳洲。)
遺傳算法的實現過程
遺傳算法的實現過程實際上就像天然界的進化過程那樣。首先尋找一種對問題潛在解進行「數字化」編碼的方案。(創建表現型和基因型的映射關係)而後用隨機數初始化一個種羣(那麼第一批袋鼠就被隨意地分散在山脈上),種羣裏面的個體就是這些數字化的編碼。接下來,經過適當的解碼過程以後(獲得袋鼠的位置座標),用適應性函數對每個基因個體做一次適應度評估(袋鼠爬得越高,越是受咱們的喜好,因此適應度相應越高)。用選擇函數按照某種規定擇優選擇(咱們要每隔一段時間,在山上射殺一些所在海拔較低的袋鼠,以保證袋鼠整體數目持平。)。讓個體基因變異(讓袋鼠隨機地跳一跳)。而後產生子代(但願存活下來的袋鼠是多產的,並在那裏生兒育女)。遺傳算法並不保證你能得到問題的最優解,可是使用遺傳算法的最大優勢在於你沒必要去了解和操心如何去「找」最優解。(你沒必要去指導袋鼠向那邊跳,跳多遠。)而只要簡單的「否認」一些表現很差的個體就好了。(把那些老是愛走下坡路的袋鼠射殺,這就是遺傳算法的精粹!)
因此咱們總結出遺傳算法的通常步驟:
開始循環直至找到滿意的解。
1.評估每條染色體所對應個體的適應度。
2.遵守適應度越高,選擇機率越大的原則,從種羣中選擇兩個個體做爲父方和母方。
3.抽取父母雙方的染色體,進行交叉,產生子代。
4.對子代的染色體進行變異。
5.重複2,3,4步驟,直到新種羣的產生。
結束循環。
接下來,咱們將詳細地剖析遺傳算法過程的每個細節。
編制袋鼠的染色體----基因的編碼方式
受到人類染色體結構的啓發,咱們能夠設想一下,假設目前只有「0」,「1」兩種鹼基,咱們也用一條鏈條把他們有序的串連在一塊兒,由於每個單位都能表現出 1 bit的信息量,因此一條足夠長的染色體就能爲咱們勾勒出一個個體的全部特徵。這就是二進制編碼法,染色體大體以下:
010010011011011110111110
上面的編碼方式雖然簡單直觀,但明顯地,當個體特徵比較複雜的時候,須要大量的編碼才能精確地描述,相應的解碼過程(相似於生物學中的DNA翻譯過程,就是把基因型映射到表現型的過程。)將過度繁複,爲改善遺傳算法的計算複雜性、提升運算效率,提出了浮點數編碼。染色體大體以下:
1.2 –3.3 – 2.0 –5.4 – 2.7 – 4.3
(注:還有一種編碼方式叫符號編碼)
那麼咱們如何利用這兩種編碼方式來爲袋鼠的染色體編碼呢?由於編碼的目的是創建表現型到基因型的映射關係,而表現型通常就被理解爲個體的特徵。好比人的基因型是46條染色體所描述的卻能解碼成一個眼,耳,口,鼻等特徵各不相同的活生生的人。因此咱們要想爲「袋鼠」的染色體編碼,咱們必須先來考慮「袋鼠」的「個體特徵」是什麼。也許有的人會說,袋鼠的特徵不少,好比性別,身長,體重,也許它喜歡吃什麼也能算做其中一個特徵。但具體在解決這個問題的狀況下,咱們應該進一步思考:不管這隻袋鼠是長短,肥瘦,黑白只要它在低海拔就會被射殺,同時也沒有規定身長的袋鼠能跳得遠一些,身短的袋鼠跳得近一些。固然它愛吃什麼就更不相關了。咱們由始至終都只關心一件事情:袋鼠在哪裏。由於只要咱們知道袋鼠在那裏,咱們就能作兩件必須去作的事情:
(1)經過查閱喜瑪拉雅山脈的地圖來得知袋鼠所在的海拔高度(經過自變量求適應函數的值。)以判斷咱們有不必把它射殺。
(2)知道袋鼠跳一跳(交叉和變異)後去到哪一個新位置。
若是咱們一時沒法準確的判斷哪些「個體特徵」是必要的,哪些是非必要的,咱們經常能夠用到這樣一種思惟方式:好比你認爲袋鼠的愛吃什麼東西很是必要,那麼你就想想,有兩隻袋鼠,它們其它的個體特徵徹底同等的狀況下,一隻長得黑,另一隻長得不是那麼黑。你會立刻發現,這不會對它們的命運有絲毫的影響,它們應該有同等的機率被射殺!只因它們處於同一個地方。(值得一提的是,若是你的基因編碼設計中包含了袋鼠黑不黑的信息,這其實不會影響到袋鼠的進化的過程,而那隻攀到珠穆朗瑪峯的袋鼠黑與白什麼的也徹底是隨機的,可是它所在的位置倒是很是肯定的。)
以上是對遺傳算法編碼過程當中常常經歷的思惟過程,必須把具體問題抽象成數學模型,突出主要矛盾,捨棄次要矛盾。只有這樣才能簡潔而有效的解決問題。
既然肯定了袋鼠的位置做爲個體特徵,具體來講位置就是橫座標。那麼接下來,咱們就要創建表現型到基因型的映射關係。就是說如何用編碼來表現出袋鼠所在的橫座標。因爲橫座標是一個實數,因此說透了咱們就是要對這個實數編碼。回顧咱們上面所介紹的兩種編碼方式,最早想到的應該就是,對於二進制編碼方式來講,編碼會比較複雜,而對於浮點數編碼方式來講,則會比較簡潔。恩,正如你所想的,用浮點數編碼,僅僅須要一個浮點數而已。而下面則介紹如何創建二進制編碼到一個實數的映射。
明顯地,必定長度的二進制編碼序列,只能表示必定精度的浮點數。譬如咱們要求解精確到六位小數,因爲區間長度爲2 – (-1) = 3 ,爲了保證精度要求,至少把區間[-1,2]分爲3 × 106等份。又由於
因此編碼的二進制串至少須要22位。
把一個二進制串(b0,b1,....bn)轉化位區間裏面對應的實數值經過下面兩個步驟。
(1)將一個二進制串表明的二進制數轉化爲10進制數:
(2)對應區間內的實數:
(像極了模數轉換)
例如一個二進制串<1000101110110101000111>表示實數值0.637197。
(糾正一個錯誤,這裏是-1)
二進制串<0000000000000000000000>和<1111111111111111111111>則分別表示區間的兩個端點值-1和2。
好了,目前爲止咱們把袋鼠的染色體給研究透了,讓咱們繼續跟進袋鼠的進化旅程
物競天擇--適應性評分與及選擇函數。
1.物競――適應度函數(fitness function)
天然界生物競爭過程每每包含兩個方面:生物相互間的搏鬥與及生物與客觀環境的搏鬥過程。但在咱們這個實例裏面,你能夠想象到,袋鼠相互之間是很是友好的,它們並不須要互相搏鬥以爭取生存的權利。它們的生死存亡更可能是取決於你的判斷。由於你要衡量哪隻袋鼠該殺,哪隻袋鼠不應殺,因此你必須制定一個衡量的標準。而對於這個問題,這個衡量的標準比較容易制定:袋鼠所在的海拔高度。(由於你單純地但願袋鼠爬得越高越好。)因此咱們直接用袋鼠的海拔高度做爲它們的適應性評分。即適應度函數直接返回函數值就好了。
2.天擇――選擇函數(selection)
天然界中,越適應的個體就越有可能繁殖後代。可是也不能說適應度越高的就確定後代越多,只能是從機率上來講更多。(畢竟有些所處海拔高度較低的袋鼠很幸運,逃過了你的眼睛。)那麼咱們怎麼來創建這種機率關係呢?下面咱們介紹一種經常使用的選擇方法――輪盤賭(Roulette Wheel Selection)選擇法。
好比咱們有5條染色體,他們所對應的適應度評分分別爲:5,7,10,13,15。
因此累計總適應度爲:
因此各個個體被選中的機率分別爲:
你能夠想象一下,咱們轉動輪盤,輪盤停下來的時候,指針會隨機地指向某一個個體所表明的區域,那麼很是幸運地,這個個體被選中了。(很明顯,適應度評分越高的個體被選中的機率越大。)
注:還有精英選擇機制
遺傳變異――基因重組(交叉)與基因突變。
應該說這兩個步驟就是使得子代不一樣於父代的根本緣由(注意,我沒有說是子代優於父代,只有通過天然的選擇後,纔會出現子代優於父代的傾向。)。對於這兩種遺傳操做,二進制編碼和浮點型編碼在處理上有很大的差別,其中二進制編碼的遺傳操做過程,比較相似於天然界裏面的過程,下面將分開講述。
1.基因重組/交叉(recombination/crossover)
(1)二進制編碼
二進制編碼的基因交換過程很是相似高中生物中所講的同源染色體的聯會過程――隨機把其中幾個位於同一位置的編碼進行交換,產生新的個體。
(2)浮點數編碼
若是一條基因中含有多個浮點數編碼,那麼也能夠用跟上面相似的方法進行基因交叉,不一樣的是進行交叉的基本單位不是二進制碼,而是浮點數。而若是對於單個浮點數的基因交叉,就有其它不一樣的重組方式了,好比中間重組:隨機產生就能獲得介於父代基因編碼值和母代基因編碼值之間的值做爲子代基因編碼的值。好比5.5和6交叉,產生5.7,5.6。
考慮到「袋鼠跳」問題的具體狀況――袋鼠的個體特徵僅僅表現爲它所處的位置。能夠想象,同一個位置的袋鼠的基因是徹底相同的,而兩條相同的基因進行交叉後,至關於什麼都沒有作,因此咱們不打算在這個例子裏面使用交叉這一個遺傳操做步驟。(固然硬要這個操做步驟也不是不行的,你能夠把兩隻異地的袋鼠捉到一塊兒,讓它們交配,而後產生子代,再把它們送到它們應該到的地方。)
2.基因突變(Mutation)
(1)二進制編碼
基因突變過程:基因突變是染色體的某一個位點上基因的改變。基因突變使一個基因變成它的等位基因,而且一般會引發必定的表現型變化。正如上面所說,二進制編碼的遺傳操做過程和生物學中的過程很是相相似,基因串上的「 0」或「 1」有必定概率變成與之相反的「 1」或「 0」。例以下面這串二進制編碼:
101101001011001
通過基因突變後,可能變成如下這串新的編碼:
001101011011001
(2)浮點型編碼
浮點型編碼的基因突變過程通常是對原來的浮點數增長或者減小一個小隨機數。好比原來的浮點數串以下:
1.2,3.4,5.1, 6.0, 4.5
變異後,可能獲得以下的浮點數串:
1.3,3.1,4.9, 6.3, 4.4
固然,這個小隨機數也有大小之分,咱們通常管它叫「步長」。(想一想「袋鼠跳」問題,袋鼠跳的長短就是這個步長。)通常來講步長越大,開始時進化的速度會比較快,可是後來比較難收斂到精確的點上。而小步長卻能較精確的收斂到一個點上。因此不少時候爲了加快遺傳算法的進化速度,而又能保證後期可以比較精確地收斂到最優解上面,會採起動態改變步長的方法。其實這個過程與前面介紹的模擬退火過程比較相相似。
到此爲止,基因編碼,基因適應度評估,基因選擇,基因變異都一一實現了,剩下來的就是把這些遺傳過程的「零件」裝配起來了。(寫成代碼)
下面是上例的運行結果:
紅點表明真實的最大點,由求導法可求的爲f(1.85)=3.85
總結:
編碼原則
完備性(completeness):問題空間的全部解都能表示爲所設計的基因型;
健全性(soundness):任何一個基因型都對應於一個可能解;
非冗餘性(non-redundancy):問題空間和表達空間一一對應。
適應度函數的重要性
適應度函數的選取直接影響遺傳算法的收斂速度以及可否找到最優解。通常而言,適應度函數是由目標函數變換而成的。
適應度函數設計不當有可能出現欺騙問題:
(1)進化初期,個別超常個體控制選擇過程;
(2)進化末期,個體差別過小致使陷入局部極值。
欺騙問題舉例:
仍是袋鼠問題,若是低海拔的地方出現毒霧,會殺死袋鼠,只有爬上珠穆朗瑪峯頂端的袋鼠才能生存下來。
由於喜馬拉雅山脈有不少山峯,咱們以高度做爲適應度,case(1):若是不在珠峯的猴子若比在珠峯半山腰的猴子要高,由於種羣大小不變,在珠峯的猴子可能就會被淘汰;case(2):100只猴子都不在珠峯;
1. 選擇的做用:優勝劣汰,適者生存;
2. 交叉的做用:保證種羣的穩定性,朝着最優解的方向進化;
3. 變異的做用:保證種羣的多樣性,避免交叉可能產生的局部收斂。