遺傳算法的概念
是建立在自然選擇和自然遺傳學機理基礎上的迭代自適應概率性搜索算法,在1975年由Holland教授提出。
生物的進化是一個奇妙的優化過程,它通過選擇淘汰,突然變異,基因遺傳等規律產生適應環境變化的優良物種。遺傳算法是根據生物進化思想而啟發得出的一種全局優化算法。
遺傳算法的概念最早是由Bagley J.D在1967年提出的;而開始遺傳算法的理論和方法的系統性研究的是1975年,這一開創性工作是由Michigan大學的J.H.Holland所實行。當時,其主要目的是說明自然和人工系統的自適應過程。
遺傳算法簡稱GA(Genetic Algorithm),在本質上是一種不依賴具體問題的直接搜索方法。遺傳算法在模式識別、神經網絡、圖像處理、機器學習、工業優化控制、自適應控制、生物科學、社會科學等方面都得到應用。在人工智能研究中,現在人們認為“遺傳算法、自適應系統、細胞自動機、混沌理論與人工智能一樣,都是對今后十年的計算技術有重大影響的關鍵技術”。
3.2.1 遺傳算法的基本概念
遺傳算法的基本思想是基於Darwin進化論和Mendel的遺傳學說的。
Darwin進化論最重要的是適者生存原理。它認為每一物種在發展中越來越適應環境。物種每個個體的基本特征由后代所繼承,但后代又會產生一些異於父代的新變化。在環境變化時,只有那些熊適應環境的個體特征方能保留下來。
Mendel遺傳學說最重要的是基因遺傳原理。它認為遺傳以密碼方式存在細胞中,並以基因形式包含在染色體內。每個基因有特殊的位置並控制某種特殊性質;所以,每個基因產生的個體對環境具有某種適應性。基因突變和基因雜交可產生更適應於環境的后代。經過存優去劣的自然淘汰,適應性高的基因結構得以保存下來。
由於遺傳算法是由進化論和遺傳學機理而產生的直接搜索優化方法;故而在這個算法中要用到各種進化和遺傳學的概念。這些概念如下:
一、串(String)
它是個體(Individual)的形式,在算法中為二進制串,並且對應於遺傳學中的染色體(Chromosome)。
二、群體(Population)
個體的集合稱為群體,串是群體的元素
三、群體大小(Population Size)
在群體中個體的數量稱為群體的大小。
四、基因(Gene)
基因是串中的元素,基因用於表示個體的特征。例如有一個串S=1011,則其中的1,0,1,1這4個元素分別稱為基因。它們的值稱為等位基因(Alletes)。
五 、基因位置(Gene Position)
一個基因在串中的位置稱為基因位置,有時也簡稱基因位。基因位置由串的左向右計算,例如在串S=1101中,0的基因位置是3。基因位置對應於遺傳學中的地點(Locus)。
六、基因特征值(Gene Feature)
在用串表示整數時,基因的特征值與二進制數的權一致;例如在串S=1011中,基因位置3中的1,它的基因特征值為2;基因位置1中的1,它的基因特征值為8。
七、串結構空間SS
在串中,基因任意組合所構成的串的集合。基因操作是在結構空間中進行的。串結構空間對應於遺傳學中的基因型(Genotype)的集合。
八、參數空間SP
這是串空間在物理系統中的映射,它對應於遺傳學中的表現型(Phenotype)的集合。
九、非線性
它對應遺傳學中的異位顯性(Epistasis)
十、適應度(Fitness)
表示某一個體對於環境的適應程度。
遺傳算法還有一些其它的概念,這些概念在介紹遺傳算法的原理和執行過程時,再進行說明。
3.2.2遺傳算法的原理
遺傳算法GA把問題的解表示成“染色體”,在算法中也即是以二進制編碼的串。並且,在執行遺傳算法之前,給出一群“染色體”,也即是假設解。然后,把這些假設解置於問題的“環境”中,並按適者生存的原則,從中選擇出較適應環境的“染色體”進行復制,再通過交叉,變異過程產生更適應環境的新一代“染色體”群。這樣,一代一代地進化,最后就會收斂到最適應環境的一個“染色體”上,它就是問題的最優解。
一、遺傳算法的目的
典型的遺傳算法CGA(Canonical Genetic Algorithm)通常用於解決下面這一類的靜態最優化問題:
考慮對於一群長度為L的二進制編碼bi,i=1,2,…,n;有
bi∈{0,1}L (3-84)
給定目標函數f,有f(bi),並且
0<f(bi)<∞
同時
f(bi)≠f(bi+1)
求滿足下式
max{f(bi)|bi∈{0,1}L} (3-85)
的bi。
很明顯,遺傳算法是一種最優化方法,它通過進化和遺傳機理,從給出的原始解群中,不斷進化產生新的解,最后收斂到一個特定的串bi處,即求出最優解。
二、遺傳算法的基本原理
長度為L的n個二進制串bi(i=1,2,…,n)組成了遺傳算法的初解群,也稱為初始群體。在每個串中,每個二進制位就是個體染色體的基因。根據進化術語,對群體執行的操作有三種:
1.選擇(Selection)
這是從群體中選擇出較適應環境的個體。這些選中的個體用於繁殖下一代。故有時也稱這一操作為再生(Reproduction)。由於在選擇用於繁殖下一代的個體時,是根據個體對環境的適應度而決定其繁殖量的,故而有時也稱為非均勻再生(differential reproduction)。
2.交叉(Crossover)
這是在選中用於繁殖下一代的個體中,對兩個不同的個體的相同位置的基因進行交換,從而產生新的個體。
3.變異(Mutation)
這是在選中的個體中,對個體中的某些基因執行異向轉化。在串bi中,如果某位基因為1,產生變異時就是把它變成0;反亦反之。
遺傳算法的原理可以簡要給出如下:
choose an intial population
determine the fitness of each individual
perform selection
repeat
perform crossover
perform mutation
determine the fitness of each individual
perform selection
until some stopping criterion applies
這里所指的某種結束准則一般是指個體的適應度達到給定的閥值;或者個體的適應度的變化率為零。
三、遺傳算法的步驟和意義
1.初始化
選擇一個群體,即選擇一個串或個體的集合bi,i=1,2,...n。這個初始的群體也就是問題假設解的集合。一般取n=30-160。
通常以隨機方法產生串或個體的集合bi,i=1,2,...n。問題的最優解將通過這些初始假設解進化而求出。
2.選擇
根據適者生存原則選擇下一代的個體。在選擇時,以適應度為選擇原則。適應度准則體現了適者生存,不適應者淘汰的自然法則。
給出目標函數f,則f(bi)稱為個體bi的適應度。以
...(3-86)
為選中bi為下一代個體的次數。
顯然.從式(3—86)可知:
(1)適應度較高的個體,繁殖下一代的數目較多。
(2)適應度較小的個體,繁殖下一代的數目較少;甚至被淘汰。
這樣,就產生了對環境適應能力較強的后代。對於問題求解角度來講,就是選擇出和最優解較接近的中間解。
選擇的方法有:
- 適應度比例法
- 期望值法
- 排位次法
- 精華保存法
3.交叉
對於選中用於繁殖下一代的個體,隨機地選擇兩個個體的相同位置,按交叉概率P。在選中的位置實行交換。這個過程反映了隨機信息交換;目的在於產生新的基因組合,也即產生新的個體。交叉時,可實行單點交叉或多點交叉。
例如有個體
S1=100101
S2=010111
選擇它們的左邊3位進行交叉操作,則有
S1=010101
S2=100111
一般而言,交叉幌宰P。取值為0.25—0.75。
4.變異
根據生物遺傳中基因變異的原理,以變異概率Pm對某些個體的某些位執行變異。在變異時,對執行變異的串的對應位求反,即把1變為0,把0變為1。變異概率Pm與生物變異極小的情況一致,所以,Pm的取值較小,一般取0.01-0.2。
例如有個體S=101011。
對其的第1,4位置的基因進行變異,則有
S'=001111
單靠變異不能在求解中得到好處。但是,它能保證算法過程不會產生無法進化的單一群體。因為在所有的個體一樣時,交叉是無法產生新的個體的,這時只能靠變異產生新的個體。也就是說,變異增加了全局優化的特質。
5.全局最優收斂(Convergence to the global optimum)
當最優個體的適應度達到給定的閥值,或者最優個體的適應度和群體適應度不再上升時,則算法的迭代過程收斂、算法結束。否則,用經過選擇、交叉、變異所得到的新一代群體取代上一代群體,並返回到第2步即選擇操作處繼續循環執行。
圖3—7中表示了遺傳算法的執行過程。
3.2.3遺傳算法的應用
遺傳算法在很多領域都得到應用;從神經網絡研究的角度上考慮,最關心的是遺傳算法在神經網絡的應用。在遺傳算法應用中,應先明確其特點和關鍵問題,才能對這種算法深入了解,靈活應用,以及進一步研究開發。
一、遺傳算法的特點
1.遺傳算法從問題解的中集開始嫂索,而不是從單個解開始。
這是遺傳算法與傳統優化算法的極大區別。傳統優化算法是從單個初始值迭代求最優解的;容易誤入局部最優解。遺傳算法從串集開始搜索,復蓋面大,利於全局擇優。
2.遺傳算法求解時使用特定問題的信息極少,容易形成通用算法程序。
由於遺傳算法使用適應值這一信息進行搜索,並不需要問題導數等與問題直接相關的信息。遺傳算法只需適應值和串編碼等通用信息,故幾乎可處理任何問題。
3.遺傳算法有極強的容錯能力
遺傳算法的初始串集本身就帶有大量與最優解甚遠的信息;通過選擇、交叉、變異操作能迅速排除與最優解相差極大的串;這是一個強烈的濾波過程;並且是一個並行濾波機制。故而,遺傳算法有很高的容錯能力。
4.遺傳算法中的選擇、交叉和變異都是隨機操作,而不是確定的精確規則。
這說明遺傳算法是采用隨機方法進行最優解搜索,選擇體現了向最優解迫近,交叉體現了最優解的產生,變異體現了全局最優解的復蓋。
5.遺傳算法具有隱含的並行性
遺傳算法的基礎理論是圖式定理。它的有關內容如下:
(1)圖式(Schema)概念
一個基因串用符號集{0,1,*}表示,則稱為一個因式;其中*可以是0或1。例如:H=1x x 0 x x是一個圖式。
(2)圖式的階和長度
圖式中0和1的個數稱為圖式的階,並用0(H)表示。圖式中第1位數字和最后位數字間的距離稱為圖式的長度,並用δ(H)表示。對於圖式H=1x x0x x,有0(H)=2,δ(H)=4。
(3)Holland圖式定理
低階,短長度的圖式在群體遺傳過程中將會按指數規律增加。當群體的大小為n時,每代處理的圖式數目為0(n3)。
遺傳算法這種處理能力稱為隱含並行性(Implicit Parallelism)。它說明遺傳算法其內在具有並行處理的特質。
二、遺傳算法的應用關鍵
遺傳算法在應用中最關鍵的問題有如下3個
1.串的編碼方式
這本質是問題編碼。一般把問題的各種參數用二進制編碼,構成子串;然后把子串拼接構成“染色體”串。串長度及編碼形式對算法收斂影響極大。
2.適應函數的確定
適應函數(fitness function)也稱對象函數(object function),這是問題求解品質的測量函數;往往也稱為問題的“環境”。一般可以把問題的模型函數作為對象函數;但有時需要另行構造。
3.遺傳算法自身參數設定
遺傳算法自身參數有3個,即群體大小n、交叉概率Pc和變異概率Pm。
群體大小n太小時難以求出最優解,太大則增長收斂時間。一般n=30-160。交叉概率Pc太小時難以向前搜索,太大則容易破壞高適應值的結構。一般取Pc=0.25-0.75。變異概率Pm太小時難以產生新的基因結構,太大使遺傳算法成了單純的隨機搜索。一般取Pm=0.01—0.2。
三、遺傳算法在神經網絡中的應用
遺傳算法在神經網絡中的應用主要反映在3個方面:網絡的學習,網絡的結構設計,網絡的分析。
1.遺傳算法在網絡學習中的應用
在神經網絡中,遺傳算法可用於網絡的學習。這時,它在兩個方面起作用
(1)學習規則的優化
用遺傳算法對神經網絡學習規則實現自動優化,從而提高學習速率。
(2)網絡權系數的優化
用遺傳算法的全局優化及隱含並行性的特點提高權系數優化速度。
2.遺傳算法在網絡設計中的應用
用遺傳算法設計一個優秀的神經網絡結構,首先是要解決網絡結構的編碼問題;然后才能以選擇、交叉、變異操作得出最優結構。編碼方法主要有下列3種:
(1)直接編碼法
這是把神經網絡結構直接用二進制串表示,在遺傳算法中,“染色體”實質上和神經網絡是一種映射關系。通過對“染色體”的優化就實現了對網絡的優化。
(2)參數化編碼法
參數化編碼采用的編碼較為抽象,編碼包括網絡層數、每層神經元數、各層互連方式等信息。一般對進化后的優化“染色體”進行分析,然后產生網絡的結構。
(3)繁衍生長法
這種方法不是在“染色體”中直接編碼神經網絡的結構,而是把一些簡單的生長語法規則編碼入“染色體”中;然后,由遺傳算法對這些生長語法規則不斷進行改變,最后生成適合所解的問題的神經網絡。這種方法與自然界生物地生長進化相一致。
3.遺傳算法在網絡分析中的應用
遺傳算法可用於分析神經網絡。神經網絡由於有分布存儲等特點,一般難以從其拓撲結構直接理解其功能。遺傳算法可對神經網絡進行功能分析,性質分析,狀態分析。
遺傳算法雖然可以在多種領域都有實際應用,並且也展示了它潛力和寬廣前景;但是,遺傳算法還有大量的問題需要研究,目前也還有各種不足。首先,在變量多,取值范圍大或無給定范圍時,收斂速度下降;其次,可找到最優解附近,但無法精確確定最擾解位置;最后,遺傳算法的參數選擇尚未有定量方法。對遺傳算法,還需要進一步研究其數學基礎理論;還需要在理論上證明它與其它優化技術的優劣及原因;還需研究硬件化的遺傳算法;以及遺傳算法的通用編程和形式等。
(http://star.aust.edu.cn/~xjfang/AiPrinciple/ch8.html)
遺傳算法代碼
遺傳算法 ( GA , Genetic Algorithm ) ,也稱進化算法 。遺傳算法是計算機科學人工智能領域中用於解決最優化的一種搜索啟發式算法,是進化算法的一種。這種啟發式通常用來生成有用的解決方案來優化和搜索問題。進化算法最初是借鑒了進化生物學中的一些現象而發展起來的,這些現象包括遺傳、突變、自然選擇以及雜交等。遺傳算法通常實現方式為一種計算機模擬。對於一個最優化問題,一定數量的候選解(稱為個體)的抽象表示(稱為染色體)的種群向更好的解進化。傳統上,解用二進制表示(即0和1的串),但也可以用其他表示方法。進化從完全隨機個體的種群開始,之后一代一代發生。在每一代中,整個種群的適應度被評價,從當前種群中隨機地選擇多個個體(基於它們的適應度),通過自然選擇和突變產生新的生命種群,該種群在算法的下一次迭代中成為當前種群。
遺傳算法是受達爾文的進化論的啟發,借鑒生物進化過程而提出的一種啟發式搜索算法。因此在介紹遺傳算法前有必要簡單的介紹生物進化知識。
種群(Population):生物的進化以群體的形式進行,這樣的一個群體稱為種群。
個體:組成種群的單個生物。
基因 ( Gene ) :一個遺傳因子。
染色體 ( Chromosome ) :包含一組的基因。
生存競爭,適者生存:對環境適應度高的、牛B的個體參與繁殖的機會比較多,后代就會越來越多。適應度低的個體參與繁殖的機會比較少,后代就會越來越少。
遺傳與變異:新個體會遺傳父母雙方各一部分的基因,同時有一定的概率發生基因變異。
遺傳算法是如何運行的
程遺傳算法的基本過是:
- 初始化 – 創建一個初始種群。這種群通常是隨機生成的,種群的大小根據實際情況而定。(demo中大小為50,個體隨機生成)。
- 評價 – 計算每一個個體的適應值。適應值是根據我們所期望的要求進行計算。這些要求可以是簡單的“更快的算法更好”,或復雜的 “堅固的材料更好,但不要太重”。(demo中getFitness函數根據設定的預期結果solution計算個體的適應值)。
- 選擇-我們要不斷提高種群的整體適應值。我們選擇當前這一代種群中較優秀的,即適應值高的。有幾個不同的選擇方法,但基本思想是一樣的。(demo中tournamentSelection函數進行選擇)
- 交叉-交叉過程中,利用上面一步選擇到的優秀個體進行交叉(暫且理解為make love的過程吧~)。主要目的是通過由兩個或兩個以上優秀的個體,來創建下一代,讓下一代繼承一些優秀的特征,即所謂虎父無犬子。(demo中crossover函數進行交叉操作)
- 突變- 突變是一個小概率的事件,我們需要為算法添加一些隨機性。(demo中mutate進行突變操作)
- 重復2-5,直到達到我們期望的結果。
限制
想象一下,你被告知要戴上眼罩,然后你被放置在同一座山的底部,讓你找最高峰 。你是唯一的選擇就是不斷爬山,直到你發現你不能在往上爬了。你可能會宣布你已經找到了高峰,但你怎么知道?看下面這個圖,Local optimum就是局部最優,Peak就是全局最優。雖然遺傳算法往往可以避免掉最優最優,當不是我們不能保證一定能找到全局最優解。遺傳算法是屬於近似算法,適合解決復雜問題。
代碼實現
下面是java代碼的實現。源代碼已經放在github:https://github.com/gaotong2055/Advanced-Algorithm
下面使用的面向對象的設計,主要的類如下:
- Population – 一個種群,管理所有的個體
- Individual – 個體,包含一個基因序列
- Algorithm – 算法類,進行遺傳算法的主要操作
- FitnessCalc – 輔助類,計算個體的適應值等
- MainTest- 測試類
Population.java
01 package simpleGa; 02 03 public class Population { 04 Individual[] individuals; 05 // 創建一個種群 06 public Population(int populationSize, boolean initialise) { 07 individuals = new Individual[populationSize]; 08 // 初始化種群 09 if (initialise) { 10 for (int i = 0; i < size(); i++) { 11 Individual newIndividual = new Individual(); 12 newIndividual.generateIndividual(); 13 saveIndividual(i, newIndividual); 14 } 15 } 16 } 17 18 public Individual getIndividual(int index) { 19 return individuals[index]; 20 } 21 22 public Individual getFittest() { 23 Individual fittest = individuals[0]; 24 // Loop through individuals to find fittest 25 for (int i = 0; i < size(); i++) { 26 if (fittest.getFitness() <= getIndividual(i).getFitness()) { 27 fittest = getIndividual(i); 28 } 29 } 30 return fittest; 31 } 32 33 // Get population size 34 public int size() { 35 return individuals.length; 36 } 37 38 // Save individual 39 public void saveIndividual(int index, Individual indiv) { 40 individuals[index] = indiv; 41 } 42 }
01 package simpleGa; 02 03 public class Individual { 04 05 static int defaultGeneLength = 64; 06 //基因序列 07 private byte[] genes = new byte[defaultGeneLength]; 08 // 個體的 適應值 09 private int fitness = 0; 10 11 // 創建一個隨機的 基因個體 12 public void generateIndividual() { 13 for (int i = 0; i < size(); i++) { 14 byte gene = (byte) Math.round(Math.random()); 15 genes[i] = gene; 16 } 17 } 18 19 // Use this if you want to create individuals with different gene lengths 20 public static void setDefaultGeneLength(int length) { 21 defaultGeneLength = length; 22 } 23 24 public byte getGene(int index) { 25 return genes[index]; 26 } 27 28 public void setGene(int index, byte value) { 29 genes[index] = value; 30 fitness = 0; 31 } 32 33 /* Public methods */ 34 public int size() { 35 return genes.length; 36 } 37 38 public int getFitness() { 39 if (fitness == 0) { 40 fitness = FitnessCalc.getFitness(this); 41 } 42 return fitness; 43 } 44 45 @Override 46 public String toString() { 47 String geneString = ""; 48 for (int i = 0; i < size(); i++) { 49 geneString += getGene(i); 50 } 51 return geneString; 52 } 53 }
Algorithm.java
01 package simpleGa; 02 03 public class Algorithm { 04 05 /* GA 算法的參數 */ 06 private static final double uniformRate = 0.5; //交叉概率 07 private static final double mutationRate = 0.015; //突變概率 08 private static final int tournamentSize = 5; //淘汰數組的大小 09 private static final boolean elitism = true; //精英主義 10 11 // 進化一個種群 12 public static Population evolvePopulation(Population pop) { 13 // 存放新一代的種群 14 Population newPopulation = new Population(pop.size(), false); 15 16 // 把最優秀的那個 放在第一個位置. 17 if (elitism) { 18 newPopulation.saveIndividual(0, pop.getFittest()); 19 } 20 21 // Crossover population 22 int elitismOffset; 23 if (elitism) { 24 elitismOffset = 1; 25 } else { 26 elitismOffset = 0; 27 } 28 // Loop over the population size and create new individuals with 29 // crossover 30 for (int i = elitismOffset; i < pop.size(); i++) { 31 //隨機選擇兩個 優秀的個體 32 Individual indiv1 = tournamentSelection(pop); 33 Individual indiv2 = tournamentSelection(pop); 34 //進行交叉 35 Individual newIndiv = crossover(indiv1, indiv2); 36 newPopulation.saveIndividual(i, newIndiv); 37 } 38 39 // Mutate population 突變 40 for (int i = elitismOffset; i < newPopulation.size(); i++) { 41 mutate(newPopulation.getIndividual(i)); 42 } 43 44 return newPopulation; 45 } 46 47 // 進行兩個個體的交叉 (暫且想象為make love的過程吧)。 交叉的概率為uniformRate 48 private static Individual crossover(Individual indiv1, Individual indiv2) { 49 Individual newSol = new Individual(); 50 // 隨機的從 兩個個體中選擇 51 for (int i = 0; i < indiv1.size(); i++) { 52 if (Math.random() <= uniformRate) { 53 newSol.setGene(i, indiv1.getGene(i)); 54 } else { 55 newSol.setGene(i, indiv2.getGene(i)); 56 } 57 } 58 return newSol; 59 } 60 61 // 突變個體。 突變的概率為 mutationRate 62 private static void mutate(Individual indiv) { 63 for (int i = 0; i < indiv.size(); i++) { 64 if (Math.random() <= mutationRate) { 65 // 生成隨機的 0 或 1 66 byte gene = (byte) Math.round(Math.random()); 67 indiv.setGene(i, gene); 68 } 69 } 70 } 71 72 // 隨機選擇一個較優秀的個體,用了進行交叉 73 private static Individual tournamentSelection(Population pop) { 74 // Create a tournament population 75 Population tournamentPop = new Population(tournamentSize, false); 76 //隨機選擇 tournamentSize 個放入 tournamentPop 中 77 for (int i = 0; i < tournamentSize; i++) { 78 int randomId = (int) (Math.random() * pop.size()); 79 tournamentPop.saveIndividual(i, pop.getIndividual(randomId)); 80 } 81 // 找到淘汰數組中最優秀的 82 Individual fittest = tournamentPop.getFittest(); 83 return fittest; 84 } 85 }
FitnessCalc.java
01 package simpleGa; 02 03 public class FitnessCalc { 04 05 static byte[] solution = new byte[64]; 06 07 /* Public methods */ 08 // 設置候選結果為一個 byte array 09 public static void setSolution(byte[] newSolution) { 10 solution = newSolution; 11 } 12 13 // 就是把01 字符串轉換為 01數組, 放在 solution中 14 static void setSolution(String newSolution) { 15 solution = new byte[newSolution.length()]; 16 // Loop through each character of our string and save it in our byte 17 for (int i = 0; i < newSolution.length(); i++) { 18 String character = newSolution.substring(i, i + 1); 19 if (character.contains("0") || character.contains("1")) { 20 solution[i] = Byte.parseByte(character); 21 } else { 22 solution[i] = 0; 23 } 24 } 25 } 26 27 // 通過和solution比較 ,計算個體的適應值 28 static int getFitness(Individual individual) { 29 int fitness = 0; 30 for (int i = 0; i < individual.size() && i < solution.length; i++) { 31 if (individual.getGene(i) == solution[i]) { 32 fitness++; 33 } 34 } 35 return fitness; 36 } 37 38 //最優的適應值,即為基因序列的長度 39 static int getMaxFitness() { 40 int maxFitness = solution.length; 41 return maxFitness; 42 } 43 }
下面開始測試:
MainTest.java
01 package simpleGa; 02 03 public class MainTest { 04 public static void main(String[] args) { 05 06 // 選擇一個期望的基因序列。這個是由自己任意定 07 FitnessCalc 08 .setSolution("1111000000000000000000000000000000000000000000000000000000001111"); 09 10 // 初始化一個種群 11 Population myPop = new Population(50, true); 12 13 // 不段迭代,進行進化操作。 直到找到期望的基因序列 14 int generationCount = 0; 15 while (myPop.getFittest().getFitness() < FitnessCalc.getMaxFitness()) { 16 generationCount++; 17 System.out.println("Generation: " + generationCount + " Fittest: " 18 + myPop.getFittest().getFitness()); 19 myPop = Algorithm.evolvePopulation(myPop); 20 } 21 System.out.println("Solution found!"); 22 System.out.println("Generation: " + generationCount); 23 System.out.println("Final Fittest Genes:"); 24 System.out.println(myPop.getFittest()); 25 26 } 27 } 輸出的解應該是類似這樣的: 01 Generation: 1 Fittest: 39 02 Generation: 2 Fittest: 45 03 Generation: 3 Fittest: 46 04 Generation: 4 Fittest: 48 05 Generation: 5 Fittest: 52 06 Generation: 6 Fittest: 55 07 Generation: 7 Fittest: 58 08 Generation: 8 Fittest: 60 09 Generation: 9 Fittest: 62 10 Generation: 10 Fittest: 63 11 Generation: 11 Fittest: 63 12 Solution found! 13 Generation: 11 14 Final Fittest Genes: 15 1111000000000000000000000000000000000000000000000000000000001111
注意,每次的運行結果會不一樣,因為里面有很多隨機因素。
本文代碼參考自國外網站:http://www.theprojectspot.com/tutorial-post/creating-a-genetic-algorithm-for-beginners/3
(http://www.acmerblog.com/genetic-algorithm-for-beginners-java-demo-5755.html)
(http://blog.chinaunix.net/uid-27105712-id-3886077.html)
(http://wenku.baidu.com/view/73aafc0a7cd184254b3535c4.html)