白話講解遺傳算法 (Genetic Algorithm)

2021-02-08 算法愛好者

(點擊上方公眾號,可快速關注)


來源:raochaoxun

連結:http://blog.chinaunix.net/uid-27105712-id-3886077.html


遺傳算法(Genetic Algorithm)又叫基因進化算法,或進化算法。屬於啟發式搜索算法一種,這個算法比較有趣,並且弄明白後很簡單,寫個100-200行代碼就可以實現。在某些場合下簡單有效。本文就花一些篇幅,儘量白話方式講解一下。 


首先說一下問題。在我們學校數據結構這門功課的時候,時常會有一些比較經典的問題(而且比較複雜問題)作為學習素材,如八皇后,背包問題,染色問題等等。上面列出的幾個問題都可以通過遺傳算法去解決。本文列舉的問題是TSP(Traveling Salesman Problem)類的問題。


TSP問題實際上是」哈密頓迴路問題」中的」哈密頓最短迴路問題」.如下圖,就是要把下面8個城市不重複的全部走一遍。有點像小時候玩的畫筆畫遊戲,一筆到底不能重複。TSP不光是要求全部走一遍,並且是要求路徑最短。就是有可能全部走一遍有很多走法,要找出其中總路程最短的走法。 



和這個問題有點相似的是歐拉迴路(下圖)問題,它不是要求把每個點都走一遍,而是要求把每個邊都不重複走一遍(點可以重複),當然歐拉迴路不是本算法研究的範疇。



本文會從TSP引申出下面系列問題


1、  TSP問題:要求每個點都遍歷到,而且要求每個點只被遍歷一次,並且總路程最短。


2、  最短路徑問題:要求從城市1 到城市8,找一條最短路徑。


3、  遍歷m個點,要求找出其距離最短的路線。(如果m=N總數,其實就是問題1了,所以問題1可以看成是問題3的特例 )。 


遺傳算法的理論是根據達爾文進化論而設計出來的算法: 人類是朝著好的方向(最優解)進化,進化過程中,會自動選擇優良基因,淘汰劣等基因。


在上面tsp問題中,一個城市節點可以看成是一個基因,一個最優解就是一條路徑,包含若干個點。就類似一條染色體有若干基因組成一樣。所以求最短路徑問題,可以抽象成求最優染色體的問題。


遺傳算法很簡單,沒有什麼分支判斷,只有兩個大循環,流程大概如下 


流程中有幾個關鍵元素:



1、  適度值評估函數。這個函數是算法的關鍵,就是對這個繁衍出來的後代進行評估打分,是優秀,還是一般,還是很差的畸形兒。用這個函數進行量化。在tsp中,路徑越短,分數越高。函數可以可以這樣 fitness = 1/total_distance.  或者 fitness = MAX_DISTANCE – total_distance. 不同的計算方法會影響算法的收斂速度,直接影響結果和性能。 


2、  選擇運算規則: 又稱選擇算子。對應著達爾文理論中適者生存,也有地方叫著精英主義原則,意思就是只有優秀的人才有更大的機率存活下來,擁有交配權。有權利擁有更多後代,傳承下自己血脈基因。和現實中很相像,皇帝權臣遺留下來的子孫後代比較多。選擇方法比較多。最常見的是round robin selection 算法,即輪盤賭算法, 這個算法比較簡單有效。選擇算法目前已有的有10來種之多。各種不同業務可以按需選擇。 



選擇公式如下:




//選擇運算---輪盤賭,此算法要求不能有負數.

    int32_t Genetic::Selection(Genome & selGenome)

    {

        //生成一個隨機浮點數

        //本算法在輪盤賭算法上加上了選擇概率,提高最大可行解入圍概率

        double ftmp = (((random())%100001)/(100000 + 0.0000001));

        if( ftmp > 0.9 )

        {

            GetBestGenome(selGenome);

            return ESUCCESS;

        }

        //生成一個【0, m_dTotalFitness】之間的隨機浮點數

        double dRange     = (((random()+ random())%100001)/(100000 + 0.0000001)) * m_dTotalFitness;

        double dCursor    = 0.0;

        size_t i         = 0;

        

        for(i = 0; i < m_vGenome.size(); ++i)

        {

            dCursor += m_vGenome[i].dFitness;

            

            if (dCursor > dRange)

            {

                break;

            }

        }

 

        selGenome = m_vGenome[i];

        

        return ESUCCESS;

    }


3、  交叉運算規則:又稱交配規則,交叉算子。對應遺傳學中的精子和卵子產生的受精卵含有精子的部分基因,也含有卵子的部分基因的現象。就像孩子有點像父親,又有點像母親的規律。交叉運算算法更多。作者可以天馬行空的自己去想像。只要達到交叉結果中含有父母的基因就可以。最常見的是k-opt 交換。其中k可以是 1,2,3….等等。簡稱單點交換,兩點交換,3點交換等等:


單點交換



其中修復重複基因根據業務需要看是否需要。 


兩點交換



4、  變異運算規則:又叫變異算子。在人類遺傳進化過程中。會發生一些基因突變。這些突變有可能是好的突變,有可能是壞的突變。像癌細胞就是壞的突變。愛因斯坦的大腦估計是好的突變。突變方法也是可以天馬行空的自己去發揮創造。 


這裡討論一下,為什麼要有突變這道流程呢。從人類進化角度來說。人類基因有數十萬種,在遠古交流比較少的年代。都是部落內部通婚,但是整個部落內部居民可能都缺少某種好的基因,這樣無論他們怎麼交配,都不會產生好的基因,那麼他們需要引入好的基因,於是和其他部落通婚。引入其他自己沒有的基因,其實對於這個種群來說這就是一次基因變異。如果是好的變異,那麼這個後代就很優秀,結果就是會產生更多子孫,把這個好的變異基因傳承下去,如果不是好的變異基因,自然而然會在前面選擇算子下淘汰,就是現實生活中的所謂的年幼夭折,痴呆無後,或先天畸形被淘汰,不會傳承下去。 


從計算機算法角度看:所有的啟發式算法無外乎2種手段結合。局域搜索和全域搜索。局域搜索是在鄰域範圍內找出最優解。對應的是選擇算子和交叉算子。在自己部落裡面找最優秀的人。如果只有局域搜索的話,就容易陷入局域最優解。算法結果肯定是要找出全域最優解。這就要求跳出局域搜索。我們稱之為「創新」。創新就是一次打破常規的突破——就是我們的「變異」算子。 


這裡拿最短路徑路徑舉例子,求點1到點8之間的最短路徑, 初始解是1——2——3——6——8


 

  

內變異:所謂內變異就是在自己內部發生變異。嚴格來說其實不是一種變異。但是它又是一種比較有效的手段。



外變異外變異是引入創新,突破傳統的質的飛躍, 也是啟發算法中所謂的全域搜索。下面是充當前基因中引入外部基因(當前集合的補集)。 



尾:遺傳算法除了上述這些幾個主要算子之外,還有一些細節。如交叉概率pc,變異概率pm,這些雖然都是輔助手段,但是有時候對整個算法結果和性能帶來截然不同的效果。這也是啟發式算法的一個缺點。參數需要不停的在實踐中摸索,沒有萬能的推薦參數。 


還有細心的讀者可能發現幾個疑問,就是最短路徑中變異或交叉結果可能產生無效解,如前面最短路徑 1——6——3——2——8.  其中1和6之間根本沒有通路。碰到這種情況,可以拋棄這條非法解,重新生成一條隨機新解(其實這也是一次變異創新)。或者自己修復成可行解。反正框框在那裡。具體手段可以自己天馬行空發揮。 


另一個比較實際的問題是:在最短路徑中並不知道染色體長度是多少,不錯。大部分人還是用定長染色體去解決問題,這樣性能低下。算法不直觀。這時候可以使用變長染色體來解決。其實我建議不管何種情況,都設計變長染色體模式。因為定長也是變長的一種特例。使用變長可以解決任何問題。不管是tsp還是最短路徑問題。 


還有一個編解碼問題,就是把現實問題轉換成基因,這些問題都比較容易解決,最簡單的就是直接用數組下標表示。


關注「算法愛好者」

看更多精選算法技術文章

↓↓↓

相關焦點

  • 遺傳算法(Genetic Algorithm)概述
    (Genetic Algorithm)又叫基因進化算法,或進化算法。屬於啟發式搜索算法一種,這個算法比較有趣,並且弄明白後很簡單,寫個100-200行代碼就可以實現。在某些場合下簡單有效。本文就花一些篇幅,儘量白話方式講解一下。  首先說一下問題。在我們學校數據結構這門功課的時候,時常會有一些比較經典的問題(而且比較複雜問題)作為學習素材,如八皇后,背包問題,染色問題等等。上面列出的幾個問題都可以通過遺傳算法去解決。
  • 利用遺傳算法優化GANs
    遺傳算法是根據大自然中生物體進化規律而設計提出的,是根據大自然中生物體進化規律而設計提出的。是模擬達爾文生物進化論的自然選擇和遺傳學機理的生物進化過程的計算模型,是一種通過模擬自然進化過程搜索最優解的方法。在本片文章中,我們嘗試使用遺傳算法來對訓練GANs進行優化,我們的訓練模型是生成手寫數字。
  • 【源碼】基於遺傳算法的VST混響插件
    一個用MATLAB編寫的VST 2音頻效果插件,它使用遺傳算法生成描述人工房間混響的隨機脈衝響應
  • 【優化】遺傳算法介紹
    [2]葛繼科,邱玉輝,吳春明,蒲國林.遺傳算法研究綜述[J].計算機應用研究,2008(10):2911-2916.[3]雷德明.多維實數編碼遺傳算法[J].控制與決策,2000(02):239-241.[4]臧文科. DNA遺傳算法的集成研究與應用[D].山東師範大學,2018.
  • 遺傳算法概述
    遺傳算法(Genetic Algorithm)又叫基因進化算法,或進化算法。
  • 遺傳算法簡述
    遺傳算法(Genetic Algorithm)又叫基因進化算法,或進化算法。
  • AUTOML算法之Genetic CNN算法
    Genetic CNN算法是一種可以自動學習卷積神經網絡的方法,該方法使用遺傳算法作為主導,將遺傳算法應用到CNN的架構搜索中,從而學習和構建最優的CNN架構。首先,為了不讓該方法構建的架構無限的發展,在使用該方法時要先給一個約束,設定網絡的有限層數,這些層(層:Stage)是由池化層為界進行劃分的,並且每一層都包含一系列預定義的構建塊(Block),這些預定義的構建塊由卷積或池化操作組成,然後使用一種新的編碼方式將網絡結構用固定長度的二進位編碼表示,最後利用遺傳算法在一個大的搜索空間內進行優化,從而提高遍歷搜索空間的效率。
  • 論文速遞--上位效應對遺傳算法可靠性的影響
    ,並分析基於相互作用產生的上位效應對遺傳算法可靠性的影響。指出遺傳算法缺陷的根源;2. 基於測試樣本函數定義目標函數,以判斷遺傳算法的適用性。方法:1. 基於非上位效應函數(表1)和上位效應函數(表2),以及非上位效應函數F4和上位效應函數F6的結構圖來驗證遺傳算法可靠性;2. 通過計算樣本函數(公式(1))和遺傳算法流程(圖3)表達遺傳算法的工作原理。3.
  • 【白話機器學習】算法理論+實戰之AdaBoost算法
    ,曾經看過西瓜書,統計學習方法,機器學習實戰等書,也聽過一些機器學習的課程,但總感覺話語裡比較深奧,讀起來沒有耐心,並且理論到處有,而實戰最重要, 所以在這裡想用最淺顯易懂的語言寫一個白話機器學習算法理論+實戰系列。
  • 一文讀懂遺傳算法工作原理(附Python實現)
    其中重點介紹了遺傳算法的數據科學應用。目錄1、遺傳算法理論的由來2、生物學的啟發3、遺傳算法定義4、遺傳算法具體步驟初始化適應度函數選擇交叉變異5、遺傳算法的應用4、遺傳算法具體步驟為了讓講解更為簡便,我們先來理解一下著名的組合優化問題「背包問題」。如果你還不太懂,這裡有一個我的解釋版本。比如,你準備要去野遊 1 個月,但是你只能背一個限重 30 公斤的背包。現在你有不同的必需物品,它們每一個都有自己的「生存點數」(具體在下表中已給出)。
  • ​隨機算法(randomized algorithm)概述——概念、方法、類型、複雜度、設計方法和計算舉例(14k字)
    algorithm)是一個概率圖靈機,也就是在算法中引入隨機因素,即通過隨機數選擇算法的下一步操作。本文概述隨機算法(randomized algorithm)的概念、方法、類型、複雜度、設計方法和計算舉例。關鍵詞:隨機算法(randomized algorithm)、隨機、計算。
  • npj: 多目標遺傳訓練——量化反應力場的不確定度量化
    來自美國南加利福尼亞大學的中野愛一郎教授領導的團隊,使用了一種基於反應分子動力學(RMD)模擬的算法來訓練反應力場參數和對模擬量進行了不確定性的量化。ReaxFF參數的訓練是通過直接擬合反應分子動力學軌跡與量子分子動力學軌跡的動力學過程來進行的,在這個過程中,多個感興趣量的Pareto最優前沿為不確定度的量化提供了一系列ReaxFF模型。
  • Myers 差分算法 (Myers Difference Algorithm) —— DiffUtils 之核心算法(一)
    Myers's difference algorithm這個算法,我們可以簡單的翻譯成Myers 差分算法,來計算兩個列表最小的更新操作數。在這個類的頭部注釋的最後,也給出了相關性能的數據: 1這個性能非常可觀呀,如果結合我們的業務實際,這種計算性能,再考慮把計算操作放置到非 UI 線程中操作,那麼我們得到的就是一個非常平滑的操作體驗了。
  • 數據挖掘十大算法 ——The k-means algorithm(二)
    不僅僅是選中的十大算法,其實參加評選的18 種算法,實際上隨便拿出一種來都可以稱得上是經典算法,它們在數據挖掘領域都產生了極為深遠的影響。算法綜述:k-means algorithm算法是一個聚類算法,把n的對象根據他們的屬性分為k個分割,k < n。
  • 遺傳算法簡介、基本原理及算法實現
    遺傳算法算是一個比較複雜的算法,本文主要分為三個部分,第一部分遺傳算法的發展、功能、主要思想以及簡單的代碼命令;第二部分詳細介紹遺傳算法的機理,第三部分舉例並給出一個簡單地使用方法。雖然遺傳算法存在諸如陷入局部最優解,收斂速度緩慢等問題,人們也進行了很多的修改,但是鑑於遺傳算法本身就具有很高的性能,而且各種修正方案都存在一定的複雜性和非普適性,所以經典遺傳算法在應用領域還是幾乎絕對的主流。二、遺傳算法的原理遺傳的算法的背景是達爾文的進化論,沒錯!
  • 什麼是遺傳算法?怎樣繪製遺傳算法流程圖
    遺傳算法是一種通過模擬自然進化過程搜索最優解的操作方法,遺傳算法有三個基本算子選擇、交叉和變異。對於遺傳算法我們也可以使用流程圖對其整個過程進行總結歸納,那要怎樣繪製遺傳算法流程圖呢?下面是分享的簡單操作方法,希望可以幫助大家。
  • 人工智慧-啟發式算法(Heuristic Algorithm)簡談
    求解要選擇算法,只有我們對各種算法的優缺點都很熟悉後才能根據實際問題選出有效的算法。但是對各種算法都了如指掌是不現實的,但多知道一些,會使你的選擇集更大,找出最好算法的概率越大。大自然是神奇的,它造就了很多巧妙的手段和運行機制。受大自然的啟發,人們從大自然的運行規律中找到了許多解決實際問題的方法。
  • Matlab算法系列-遺傳算法
    遺傳算法(Genetic Algorithm,GA)是20世紀70年代初興起的一門新興學科。遺傳算法的基本思想來源於達爾文的進化論和孟德爾的遺傳學說,它通過模擬生物進化的過程來求解問題。      遺傳算法已經發展得很成熟,廣泛應用於優化問題的求解。①遺傳算法只對個體的基因進行操作,所以無論實際問題多麼複雜,其穩定性都不會受到太大的影響。②遺傳算法的搜索過程屬於並行計算,能夠很好地搜索解空間。③穩定性、魯棒性強,適用於非線性、高維複雜優化問題。      其流程如下: