Word害我重寫=_=順便重新整理下思路
背景:寫論文時用到遺傳算法,花了近一周時間,還算理解了算法以及能夠進行基礎的編程實現(保持謙虛)。
說明:具體的實現沒敢細講,主要是原理的方法上的介紹(講解都算不上)。
先說說算法學習,個人覺得首先需要了解這個算法是拿來干嘛的,然后學習它的理論原理,多看懂幾遍總是好的;結合實際例子,接着把算法的每一塊兒研究清楚,通篇理解后,自己試着編程實現,這樣學起來感覺也還不錯。
關於遺傳算法原理:模擬自然界優勝劣汰的進化現象,把搜索空間(問題解的組成空間)映射為遺傳空間,把可能的解編碼成一個向量——染色體,向量的每個元素稱為基因。通過不斷計算各染色體的適應值,選擇最好的染色體,獲得最優解。
簡單說,就是給你一堆人兒(解和種群),讓你選擇一部分基因優良(解的適應度更高,比如值更大)的人出來,讓他們生小孩組成后代(選擇交叉和變異),把這些后代和之前選出來的父代,再比較基因優良,再選擇,再遺傳,這樣循環,最后找出一個超級英雄(最優解)就達到目的了。
這樣類似於一種無目的的搜索式尋找最優,不過遺傳算法的效率更高。
關於原理,知乎上有些通俗好玩的文章可以看下:https://www.zhihu.com/question/23293449
關於算法步驟:從原理也可以總結出,主要步驟包括,適應度函數的設計,編碼,選擇,交叉,變異。
即是說,我們主要能用代碼實現這些操作,一個算法就能基本實現了。這也算是面向對象編程了。給一張流程圖:
這流程圖在整篇文字看完后在回來看一遍。(堅持,看完d===( ̄▽ ̄*)b)
關於算法術語(偷懶截圖):
先從個體開始,我總是樂意把個體和染色體一起理解,因為染色體就是編碼過后的個體,兩者本質一樣,只是表現方式不一樣。個體就是算法的一個解,比如一個函數在某個區間內,有無數個解。而染色體,是為了讓算法能更好的理解和操作我們的個體,進行的編碼結果。這里的編碼,就是一個轉換操作。
舉個栗子,求一個函數區間內最大值,我將一個值為13的解,按照6位長的二進制編碼,轉換為:001101,這里的13就是個體,001101就是染色體,里面的0和1就是基因。這樣來,算法操作這些二值集比實數容易得多。
然后,一大堆個體組成種群,我們需要做的,就是從種群中,挑選出優良的個體(染色體),進行交叉變異,生成下一代,組成新的種群。
評價個體是否優良的標准就是適應度函數,比如求極值函數的值哪些更大或更小。適應度函數給每個個體一個評價值,然后依據評價值,我們選出一部分——如種群數量的20%——作為優良的父代,通過交叉變異,讓他們產生子代,組成新的種群,再計算適應度和循環。
交叉和變異就是遺傳操作。交叉,就是把染色體里的基因交換,比如吧父親的優良基因與母親的優良基因組合在一起,生成下一代,如圖:
我們將左邊兩個染色體交叉,產生了右邊新的兩個染色體。這個時候用了編碼就十分好理解了,每個染色體就是一個二進制串,如圖:
這樣進行交叉比用實數表示容易實現多了去了。
然后是變異,就是染色體內部的基因變異,比如改變二進制串中的某個基因值,就能產生變異。
001101®011101,對第二個基因變異,產生新的染色體(解),也就是13產生了29。
理解了術語和步驟,接下來就是具體實現。具體的實現,我結合網上找的很實用的例子,來源應該是《遺傳算法工具箱》這類書。
環境:matlab和遺傳算法工具箱。
首先說下工具箱,這是由外國的大神們編制的一個工具箱,里面有對應的遺傳算法各個操作會用到的函數。這些函數也是重點,因為遺傳算法(或者大部分算法)都是分塊兒的,每一個塊兒就是一個操作,每一個操作都以函數形式來表達和進行。
因此具體的實現,就是對每個操作的函數實現。代碼來自《工具箱》群書,只是主要部分:
前4行為算法約定或約束。表明,我們每一個種群中有40個個體(染色體)。最多會遺傳25代,及循環25次或者說會生成25個種群。然后編碼的長度—即染色體的長度為20位(使用的二進制編碼)。代溝是選擇的比例,即每個種群,我們選出40*0.1=4個優良個體。
接下來就是循環的設計,在循環里邊,有函數:“計算目標函數值”,在這里即是適應度函數。大多時候,適應度函數都是用原函數。
二十進制轉換函數bs2rv是為了讓編碼后的個體能恢復實數形式並用以計算適應度。
里邊的選擇、重組和變異,都是通過一個函數完成:select,recombin,mut。這里的選擇,就是選出優良染色體用來產生下一代。重組就是交叉;變異就是…變異。
所以你看到,每一個操作用函數就可以完成,但是要知道,這里的一個函數只是對應了一種操作模式,二每個操作都有很多模式,比如編碼有二進制編碼、實數編碼等。選擇操作有賭輪選擇、錦標賽選擇。交叉有單點交叉、多點交叉等。變異有基本位變異、均勻變異等。
當然每一個模式,或者方法都有對應的原理和函數,這個就自行查找學習。
所以看來遺傳算法也沒那么難,搞清楚每一個操作,尋找或編寫對應的函數,再調用即可。
不過這只是基本遺傳操作,現在更在意的是遺傳算法的改進和優化,而這些改進和優化,又都是針對以上操作的模式的不足進行的優化,也是好玩。
大概就到這里,最后推薦一本書,雷英傑,老師和張善文老師主編《MATLAB遺傳算法工具箱及應用》,着實實用,實際操作也有,優化也有。