進化計算簡介和遺傳算法的實現--AForge.NET框架的使用(六)


開學了,各種忙起來了…

上一篇介紹了AForge.NET在人工神經網絡上的一點點使用,但是老覺不過癮。matlab用着實在不習慣,就又琢磨了一下進化計算。

進化計算簡介

進化計算算不上新的方法了,已經有大量研究人員作出了努力,這導致了大量的進化計算算法出現。他們不僅研究算法本身,還致力於擴大算法的應用范圍。

眾所周知,現實世界存在大量復雜問題,它們中一部分無法用常規方法在合理的時間內獲得精確解,而另一部分甚至沒有行之有效的解決方案。

最著名的例子就是TSP問題,該問題意在尋求單一旅行者由起點出發,通過所有給定的需求點之后,最后再回到原點的最小路徑成本。

而進化計算可以應用於這些問題,因為大多數情況下這類問題允許我們在合理時間內給出較優解。

進化計算並不能保證找到特定問題的最佳解決方案,但是可以找到一個很好的解決辦法,該方案可能是非常接近的最佳解決方案。

進化算法的分支和運用

進化計算是一些算法的統稱,主要包括Genetic Algorithms (GA遺傳算法), Genetic Programming (GP遺傳規划) 和 Gene Expression Programming (GEP基因表達式編程)。

進化算法主要可以解決以下類別問題:

1.函數優化

2.符號回歸

3.時間序列預測

4.旅行商問題

遺傳算法簡介

Genetic Algorithms(遺傳算法)最早由John Holland基於進化觀點在1960提出。從那時起相關研究不斷進行。

大部分研究成果運用到很多領域,並取得了很好的效果。雖然遺傳算法的歷史悠久,但是目前還是不斷有新的方法被提出,擴寬了運用領域。

 

遺傳算法基於達爾文的“適者生存”理論和遺傳學機理的生物進化過程。算法作用於每一代的基因,而每個基因都是問題的可能解。

一般遺傳算法的運用有以下4個步驟:

1.隨機選擇個體,並進行交叉

2.變異

3.計算適應度

4.選擇下一個世代的個體

算法的停止條件一般是指定的迭代數目完成或者得到一個可靠解。

交叉算法中最簡單的單點交叉,即隨機選擇兩個基因的一個點,交換兩個基因的一部分。

基因1:0 0 0 1 1 0 1
基因2:1 0 0 1 0 0 0
結果  :0 0 0 1 0 0 0

還有一種不錯的方式是兩點交叉,隨機選擇兩個基因的兩個點,交換兩個點之間的部分。

變異一般用單點變異

基因1:0 1 0 0 1 0 1
結果  :0 1 0 0 0 0 1

用Aforge.Net實現遺傳算法

我覺得Aforge.Net的優越就在於不是提供特定的實現,而是重在提供一個可以擴展的框架,方便學習和研究。

s3

我以函數最優化為例。函數我選用:x^0.5+sin(x/23)*30 范圍從0到100

s3

先用matlab估計一下最優值

output

建立適應度評價函數;

public class MyOwnFunction : OptimizationFunction1D 
{
public MyOwnFunction()
: base(new AForge.Range(0, 100))
{
}

public override double OptimizationFunction(double x)
{
return Math.Sqrt(x)+ Math.Sin(x/23)*30;

}
}

遺傳算法主要的類是Population類。它容納了所有的染色體,提供了適應度評價方法、編碼方式和選擇方式。

MyOwnFunction f = new MyOwnFunction(); 
Population population = new Population(40,new BinaryChromosome(32),f,new EliteSelection());

這段代碼的意思是適應度函數使用自定義的MyOwnFunction,編碼使用二進制編碼,長度為32,每個世代個體數目為40,選擇方式為“精英取舍”。

這個名字很霸氣,其實就是排個序,然后把不好的移除而已,代碼如下;

public class EliteSelection : ISelectionMethod 
{
/// <summary>
/// Initializes a new instance of the <see cref="EliteSelection"/> class.
/// </summary>
public EliteSelection( ) { }

/// <summary>
/// Apply selection to the specified population.
/// </summary>
///
/// <param name="chromosomes">Population, which should be filtered.</param>
/// <param name="size">The amount of chromosomes to keep.</param>
///
/// <remarks>Filters specified population keeping only specified amount of best
/// chromosomes.</remarks>
///
public void ApplySelection( List<IChromosome> chromosomes, int size )
{
// sort chromosomes
chromosomes.Sort( );

// remove bad chromosomes
chromosomes.RemoveRange( size, chromosomes.Count - size );
}
}

一般情況可以使用賭輪盤的方式進行下一個世代的選擇。完整代碼:

Console.WriteLine("Start!"); 
MyOwnFunction f = new MyOwnFunction();
Population population = new Population(40,
new BinaryChromosome(32),f,new EliteSelection());
population.RunEpoch();
double goodX=f.Translate(population.BestChromosome);
Console.WriteLine("Best Chromosome === >{0}", goodX);
Console.WriteLine("Best Result === >{0}", f.OptimizationFunction(goodX));
Console.WriteLine("Over!");
Console.ReadLine();

效果:

data

基本符合,和matlab估算的值差了0.0002左右。

如果要輸出最后世代的所有結果,可以使用

for (int i = 0; i < population.Size; i++) 
{
Console.WriteLine("chromosome{0} == >{1}", i, f.Evaluate(population[i]));
}

結果如下圖:
data2

寫在最后:

1.個人覺得AForge.NET用着比matlab方便,因為它的整體架構比較統一,而不像matlab是由工具箱提供的,使用風格迥異。

2.AForge.Net的進化計算這塊遠遠比神經網絡部分完整,基本不需要自己實現什么。

3.AForge.Fuzzy中的隸屬度函數的表示實現不夠豐富,只實現了中間型的兩種,我擴寫了其他種類的,等整理好了就發出來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM