进化计算简介和遗传算法的实现--AForge.NET框架的使用(六)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

进化计算简介和遗传算法的实现框架的使⽤(六)
开学了,各种忙起来了…
上⼀篇介绍了在⼈⼯神经⽹络上的⼀点点使⽤,但是⽼觉不过瘾。

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
⽤实现遗传算法
我觉得的优越就在于不是提供特定的实现,⽽是重在提供⼀个可以扩展的框架,⽅便学习和研究。

我以函数最优化为例。

函数我选⽤:x^0.5+sin(x/23)*30 范围从0到100
先⽤matlab估计⼀下最优值
建⽴适应度评价函数;
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();
效果:
基本符合,和matlab估算的值差了0.0002左右。

如果要输出最后世代的所有结果,可以使⽤
for (int i = 0; i < population.Size; i++)
{
Console.WriteLine("chromosome{0} == >{1}", i, f.Evaluate(population[i]));
}
结果如下图:
写在最后:
1.个⼈觉得⽤着⽐matlab⽅便,因为它的整体架构⽐较统⼀,⽽不像matlab是由⼯具箱提供的,使⽤风格迥异。

的进化计算这块远远⽐神经⽹络部分完整,基本不需要⾃⼰实现什么。

3.AForge.Fuzzy中的⾪属度函数的表⽰实现不够丰富,只实现了中间型的两种,我扩写了其他种类的,等整理好了就发出来。

相关文档
最新文档