遗传算法

遗传算法
遗传算法

遗传算法:

遗传算法入门到掌握(一)

分类:C++模式识别2011-11-05 16:08 22066人阅读评论(7) 收藏举报算法生物randomvectorclassfunction

博主前言:此文章来自一份网络资料,原作者不明,是我看过的最好的一份遗传算法教程,如果你能耐心看完他,相信你一定能基本掌握遗传算法。

遗传算法的有趣应用很多,诸如寻路问题,8数码问题,囚犯困境,动作控制,找圆心问题(这是一个国外网友的建议:在一个不规则的多边形中,寻找一个包含在该多边形内的最大圆圈的圆心。),TSP问题(在以后的章节里面将做详细介绍。),生产调度问题,人工生命模拟等。直到最后看到一个非常有趣的比喻,觉得由此引出的袋鼠跳问题(暂且这么叫它吧),既有趣直观又直达遗传算法的本质,确实非常适合作为初学者入门的例子。

问题的提出与解决方案

让我们先来考虑考虑下面这个问题的解决办法。

已知一元函数:

现在要求在既定的区间内找出函数的最大值

极大值、最大值、局部最优解、全局最优解

在解决上面提出的问题之前我们有必要先澄清几个以后将常常会碰到的概念:极大值、最大值、局部最优解、全局最优解。学过高中数学的人都知道极大值在一个小邻域里面左边的函数值递增,右边的函数值递减,在图2.1里面的表现就是一个“山峰”。当然,在图上有很多个“山峰”,所以这个函数有很多个极大值。而对于一个函数来说,最大值就是在所有极大值当中,最大的那个。所以极大值具有局部性,而最大值则具有全局性。

因为遗传算法中每一条染色体,对应着遗传算法的一个解决方案,一般我们用适应性函数(fitness function)来衡量这个解决方案的优劣。所以从一个基因组到其解的适应度形成一个映射。所以也可以把遗传算法的过程看作是一个在多元函数里面求最优解的过程。在这个多维曲面里面也有数不清的“山峰”,而这些最优解所对应的就是局部最优解。而其中也会有一个“山峰”的海拔最高的,那么这个就是全局最优解。而遗传算法的任务就是尽量爬到最高峰,而不是陷落在一些小山峰。(另外,值得注意的是遗传算法不一定要找“最高的山峰”,如果问题的适应度评价越小越好的话,那么全局最优解就是函数的最小值,对应的,遗传算法所要找的就是“最深的谷底”)如果至今你还不太理解的话,那么你先往下看。本章的示例程序将会非常形象的表现出这个情景。

“袋鼠跳”问题

既然我们把函数曲线理解成一个一个山峰和山谷组成的山脉。那么我们可以设想所得到的每一个解就是一只袋鼠,我们希望它们不断的向着更高处跳去,直到跳到最高的山峰(尽管袋鼠本身不见得愿意那么做)。所以求最大值的过程就转化成一个“袋鼠跳”的过程。下面介绍介绍“袋鼠跳”的几种方式。

爬山法、模拟退火和遗传算法

解决寻找最大值问题的几种常见的算法:

1. 爬山法(最速上升爬山法):

从搜索空间中随机产生邻近的点,从中选择对应解最优的个体,替换原来的个体,不断重复上述过程。因为只对“邻近”的点作比较,所以目光比较“短浅”,常常只能收敛到离开初始位置比较近的局部最优解上面。对于存在很多局部最优点的问题,通过一个简单的迭代找出全局最优解的机会非常渺茫。(在爬山法中,

袋鼠最有希望到达最靠近它出发点的山顶,但不能保证该山顶是珠穆朗玛峰,或者是一个非常高的山峰。因为一路上它只顾上坡,没有下坡。)

2. 模拟退火:

这个方法来自金属热加工过程的启发。在金属热加工过程中,当金属的温度超过它的熔点(Melting Point)时,原子就会激烈地随机运动。与所有的其它的物理系统相类似,原子的这种运动趋向于寻找其能量的极小状态。在这个能量的变迁过程中,开始时。温度非常高,使得原子具有很高的能量。随着温度不断降低,金属逐渐冷却,金属中的原子的能量就越来越小,最后达到所有可能的最低点。利用模拟退火的时候,让算法从较大的跳跃开始,使到它有足够的“能量”逃离可能“路过”的局部最优解而不至于限制在其中,当它停在全局最优解附近的时候,逐渐的减小跳跃量,以便使其“落脚”到全局最优解上。(在模拟退火中,袋鼠喝醉了,而且随机地大跳跃了很长时间。运气好的话,它从一个山峰跳过山谷,到了另外一个更高的山峰上。但最后,它渐渐清醒了并朝着它所在的峰顶跳去。)

3. 遗传算法:

模拟物竞天择的生物进化过程,通过维护一个潜在解的群体执行了多方向的搜索,并支持这些方向上的信息构成和交换。以面为单位的搜索,比以点为单位的搜索,更能发现全局最优解。(在遗传算法中,有很多袋鼠,它们降落到喜玛拉雅山脉的任意地方。这些袋鼠并不知道它们的任务是寻找珠穆朗玛峰。但每过几年,就在一些海拔高度较低的地方射杀一些袋鼠,并希望存活下来的袋鼠是多产的,在它们所处的地方生儿育女。)(后来,一个叫天行健的网游给我想了一个更恰切的故事:从前,有一大群袋鼠,它们被莫名其妙的零散地遗弃于喜马拉雅山脉。于是只好在那里艰苦的生活。海拔低的地方弥漫着一种无色无味的毒气,海拔越高毒气越稀薄。可是可怜的袋鼠们对此全然不觉,还是习惯于活蹦乱跳。于是,不断有袋鼠死于海拔较低的地方,而越是在海拔高的袋鼠越是能活得更久,也越有机会生儿育女。就这样经过许多年,这些袋鼠们竟然都不自觉地聚拢到了一个个的山峰上,可是在所有的袋鼠中,只有聚拢到珠穆朗玛峰的袋鼠被带回了美丽的澳洲。)

下面主要介绍介绍遗传算法实现的过程。

遗传算法的实现过程

遗传算法的实现过程实际上就像自然界的进化过程那样。首先寻找一种对问题潜在解进行“数字化”编码的方案。(建立表现型和基因型的映射关系。)然后用随机数初始化一个种群(那么第一批袋鼠就被随意地分散在山脉上。),种群里面的个体就是这些数字化的编码。接下来,通过适当的解码过程之后,(得到袋鼠的位置坐标。)用适应性函数对每一个基因个体作一次适应度评估。(袋鼠爬得越高,越是受我们的喜爱,所以适应度相应越高。)用选择函数按照某种规定择优选择。(我们要每隔一段时间,在山上射杀一些所在海拔较低的袋鼠,以保证袋鼠总体数目持平。)让个体基因交叉变异。(让袋鼠随机地跳一跳)然后产生子代。(希望存活下来的袋鼠是多产的,并在那里生儿育女。)遗传算法并不保证你能获得问题的最优解,但是使用遗传算法的最大优点在于你不必去了解和操心如何去“找”最优解。(你不必去指导袋鼠向那边跳,跳多远。)而只要简单的“否定”一些表现不好的个体就行了。(把那些总是爱走下坡路的袋鼠射杀。)以后你会慢慢理解这句话,这是遗传算法的精粹!

所以我们总结出遗传算法的一般步骤:

开始循环直至找到满意的解。

1.评估每条染色体所对应个体的适应度。

2.遵照适应度越高,选择概率越大的原则,从种群中选择两个个体作为父方和母方。

3.抽取父母双方的染色体,进行交叉,产生子代。

4.对子代的染色体进行变异。

5.重复2,3,4步骤,直到新种群的产生。

结束循环。

接下来,我们将详细地剖析遗传算法过程的每一个细节。

编制袋鼠的染色体----基因的编码方式

通过前一章的学习,读者已经了解到人类染色体的编码符号集,由4种碱基的两种配合组成。共有4种情况,相当于2 bit的信息量。这是人类基因的编码方式,那么我们使用遗传算法的时候编码又该如何处理呢?

受到人类染色体结构的启发,我们可以设想一下,假设目前只有“0”,“1”两种碱基,我们也用一条链条把他们有序的串连在一起,因为每一个单位都能表现出1 bit的信息量,所以一条足够长的染色体就能为我们勾勒出一个个体的所有特征。这就是二进制编码法,染色体大致如下:

010010011011011110111110

上面的编码方式虽然简单直观,但明显地,当个体特征比较复杂的时候,需要大量的编码才能精确地描述,相应的解码过程(类似于生物学中的DNA翻译过程,就是把基因型映射到表现型的过程。)将过份繁复,为改善遗传算法的计算复杂性、提高运算效率,提出了浮点数编码。染色体大致如下:

1.2 – 3.3 –

2.0 –5.4 – 2.7 – 4.3

那么我们如何利用这两种编码方式来为袋鼠的染色体编码呢?因为编码的目的是建立表现型到基因型的映射关系,而表现型一般就被理解为个体的特征。比如人的基因型是46条染色体所描述的(总长度两米的纸条?),却能解码成一个个眼,耳,口,鼻等特征各不相同的活生生的人。所以我们要想为“袋鼠”的染色体编码,我们必须先来考虑“袋鼠”的“个体特征”是什么。也许有的人会说,袋鼠的特征很多,比如性别,身长,体重,也许它喜欢吃什么也能算作其中一个特征。但具体在解决这个问题的情况下,我们应该进一步思考:无论这只袋鼠是长短,肥瘦,只要它在低海拔就会被射杀,同时也没有规定身长的袋鼠能跳得远一些,身短的袋鼠跳得近一些。当然它爱吃什么就更不相关了。我们由始至终都只关心一件事情:袋鼠在哪里。因为只要我们知道袋鼠在那里,我们就能做两件必须去做的事情:

(1)通过查阅喜玛拉雅山脉的地图来得知袋鼠所在的海拔高度(通过自变量求函数值。)以判断我们有没必要把它射杀。

(2)知道袋鼠跳一跳后去到哪个新位置。

如果我们一时无法准确的判断哪些“个体特征”是必要的,哪些是非必要的,我们常常可以用到这样一种思维方式:比如你认为袋鼠的爱吃什么东西非常必要,那么你就想一想,有两只袋鼠,它们其它的个体特征完全同等的情况下,一只爱吃草,另外一只爱吃果。你会马上发现,这不会对它们的命运有丝毫的影响,它们应该有同等的概率被射杀!只因它们处于同一个地方。(值得一提的是,如果你的基因编码设计中包含了袋鼠爱吃什么的信息,这其实不会影响到袋鼠的进化的过程,而那只攀到珠穆朗玛峰的袋鼠吃什么也完全是随机的,但是它所在的位置却是非常确定的。)

以上是对遗传算法编码过程中经常经历的思维过程,必须把具体问题抽象成数学模型,突出主要矛盾,舍弃次要矛盾。只有这样才能简洁而有效的解决问题。希望初学者仔细琢磨。

既然确定了袋鼠的位置作为个体特征,具体来说位置就是横坐标。那么接下来,我们就要建立表现型到基因型的映射关系。就是说如何用编码来表现出袋鼠所在的横坐标。由于横坐标是一个实数,所以说透了我们就是要对这个实数编码。回顾我们上面所介绍的两种编码方式,读者最先想到的应该就是,对于二进制编码方式来说,编码会比较复杂,而对于浮点数编码方式来说,则会比较简洁。恩,正如你所想的,用浮点数编码,仅仅需要一个浮点数而已。而下面则介绍如何建立二进制编码到一个实数的映射。

明显地,一定长度的二进制编码序列,只能表示一定精度的浮点数。譬如我们要求解精确到六位小数,由于区间长度为2 – (-1) = 3 ,为了保证精度要求,至少把区间[-1,2]分为3 × 106等份。又因为

所以编码的二进制串至少需要22位。

把一个二进制串(b0,b1,....bn)转化位区间里面对应的实数值通过下面两个步骤。

(1)将一个二进制串代表的二进制数转化为10进制数:

(2)对应区间内的实数:

例如一个二进制串<1000101110110101000111>表示实数值0.637197。

二进制串<0000000000000000000000>和<1111111111111111111111>则分别表示区间的两个端点值-1和2。

由于往下章节的示例程序几乎都只用到浮点数编码,所以这个“袋鼠跳”问题的解决方案也是采用浮点数编码的。往下的程序示例(包括装载基因的类,突变函数)都是针对浮点数编码的。(对于二进制编码这里只作简单的介绍,不过这个“袋鼠跳”完全可以用二进制编码来解决的,而且更有效一些。所以读者可以自己尝试用二进制编码来解决。)

我们定义一个类作为袋鼠基因的载体。(细心的人会提出这样的疑问:为什么我用浮点数的容器来储藏袋鼠的基因呢?袋鼠的基因不是只用一个浮点数来表示就行吗?恩,没错,事实上对于这个实例,我们只需要用上一个浮点数就行了。我们这里用上容器是为了方便以后利用这些代码处理那些编码需要一串浮点数的问题。)

[cpp]view plaincopy

1.class Genome

2.{

3.public:

4.

5.friend class GenAlg;

6.friend class GenEngine;

7.

8. Genome():fitness(0){}

9.

10. Genome(vector vec, double f): vecGenome(vec), fitness(f){} //

类的带参数初始化参数。

11.private:

12. vector vecGenome; // 装载基因的容器

13.

14.double fitness; //适应度

15.

16.};

好了,目前为止我们把袋鼠的染色体给研究透了,让我们继续跟进袋鼠的进化旅程。

物竞天择--适应性评分与及选择函数。

1.物竞――适应度函数(fitness function)

自然界生物竞争过程往往包含两个方面:生物相互间的搏斗与及生物与客观环境的搏斗过程。但在我们这个实例里面,你可以想象到,袋鼠相互之间是非常友好的,它们并不需要互相搏斗以争取生存的权利。它们的生死存亡更多是取决于你的判断。因为你要衡量哪只袋鼠该杀,哪只袋鼠不该杀,所以你必须制定一个衡量的标准。而对于这个问题,这个衡量的标准比较容易制定:袋鼠所在的海拔高度。(因为你单纯地希望袋鼠爬得越高越好。)所以我们直接用袋鼠的海拔高度作为它们的适应性评分。即适应度函数直接返回函数值就行了。

2.天择――选择函数(selection)

自然界中,越适应的个体就越有可能繁殖后代。但是也不能说适应度越高的就肯定后代越多,只能是从概率上来说更多。(毕竟有些所处海拔高度较低的袋鼠很幸运,逃过了你的眼睛。)那么我们怎么来建立这种概率关系呢?下面我们介绍一种常用的选择方法――轮盘赌(Roulette Wheel Selection)选择法。假设种群数目,某个个体其适应度为,则其被选中的概率为:

比如我们有5条染色体,他们所对应的适应度评分分别为:5,7,10,13,15。

所以累计总适应度为:

所以各个个体被选中的概率分别为:

呵呵,有人会问为什么我们把它叫成轮盘赌选择法啊?其实你只要看看图2-2的轮盘就会明白了。这个轮盘是按照各个个体的适应度比例进行分块的。你可以想象一下,我们转动轮盘,轮盘停下来的时候,指针会随机地指向某一个个体所代表的区域,那么非常幸运地,这个个体被选中了。(很明显,适应度评分越高的个体被选中的概率越大。)

那么接下来我们看看如何用代码去实现轮盘赌。

[cpp]view plaincopy

1.Genome GenAlg:: GetChromoRoulette()

2.

3.{

4.

5.//产生一个0到人口总适应性评分总和之间的随机数.

6.

7.//中m_dTotalFitness记录了整个种群的适应性分数总和)

8.

9.double Slice = (random()) * totalFitness;

10.

11.//这个基因将承载转盘所选出来的那个个体.

12.

13. Genome TheChosenOne;

14.

15.//累计适应性分数的和.

16.

17.double FitnessSoFar = 0;

18.

19.//遍历总人口里面的每一条染色体。

20.

21.for (int i=0; i

22.

23. {

24.

25.//累计适应性分数.

26.

27. FitnessSoFar += vecPop[i].fitness;

28.

29.//如果累计分数大于随机数,就选择此时的基因.

30.

31.if (FitnessSoFar >= Slice)

32.

33. {

34.

35. TheChosenOne = vecPop[i];

36.

37.break;

38.

39. }

40.

41. }

42.

43.//返回转盘选出来的个体基因

44.

45.return TheChosenOne;

46.

47.}

遗传变异――基因重组(交叉)与基因突变。

应该说这两个步骤就是使到子代不同于父代的根本原因(注意,我没有说是子代优于父代的原因,只有经过自然的选择后,才会出现子代优于父代的倾向。)。对于这两种遗传操作,二进制编码和浮点型编码在处理上有很大的差异,其中二进制编码的遗传操作过程,比较类似于自然界里面的过程,下面将分开讲述。

1.基因重组/交叉(recombination/crossover)

(1)二进制编码

回顾上一章介绍的基因交叉过程:同源染色体联会的过程中,非姐妹染色单体(分别来自父母双方)之间常常发生交叉,并且相互交换一部分染色体,如图2-3。事实上,二进制编码的基因交换过程也非常类似这个过程――随机把其中几个位于同一位置的编码进行交换,产生新的个体,如图2-4所示。

(2)浮点数编码

如果一条基因中含有多个浮点数编码,那么也可以用跟上面类似的方法进行基因交叉,不同的是进行交叉的基本单位不是二进制码,而是浮点数。而如果对于单个浮点数的基因交叉,就有其它不同的重组方式了,比如中间重组:

这样只要随机产生就能得到介于父代基因编码值和母代基因编码值之间的值作为子代基因编码的值。

考虑到“袋鼠跳”问题的具体情况――袋鼠的个体特征仅仅表现为它所处的位置。可以想象,同一个位置的袋鼠的基因是完全相同的,而两条相同的基因进行交叉后,相当于什么都没有做,所以我们不打算在这个例子里面使用交叉这一个遗传操作步骤。(当然硬要这个操作步骤也不是不行的,你可以把两只异地的袋鼠捉到一起,让它们交配,然后产生子代,再把它们送到它们应该到的地方。)

2.基因突变(Mutation)

(1)二进制编码

同样回顾一下上一章所介绍的基因突变过程:基因突变是染色体的某一个位点上基因的改变。基因突变使一个基因变成它的等位基因,并且通常会引起一定的表现型变化。恩,正如上面所说,二进制编码的遗传操作过程和生物学中的过程非常相类似,基因串上的“ 0”或“ 1”有一定几率变成与之相反的“ 1”或“ 0”。例如下面这串二进制编码:

101101001011001

经过基因突变后,可能变成以下这串新的编码:

001101011011001

(2)浮点型编码

浮点型编码的基因突变过程一般是对原来的浮点数增加或者减少一个小随机数。比如原来的浮点数串如下:

1.2,3.4, 5.1, 6.0, 4.5

变异后,可能得到如下的浮点数串:

1.3,3.1, 4.9, 6.3, 4.4

当然,这个小随机数也有大小之分,我们一般管它叫“步长”。(想想“袋鼠跳”问题,袋鼠跳的长短就是这个步长。)一般来说步长越大,开始时进化的速度会比较快,但是后来比较难收敛到精确的点上。而小步长却能较精确的收敛到一个点上。所以很多时候为了加快遗传算法的进化速度,而又能保证后期能够比较精确地收敛到最优解上面,会采取动态改变步长的方法。其实这个过程与前面介绍的模拟退火过程比较相类似,读者可以做简单的回顾。

下面是针对浮点型编码的基因突变函数的写法:

[cpp]view plaincopy

1.void GenAlg::Mutate(vector &chromo)

2.{

3.

4.//遵循预定的突变概率,对基因进行突变

5.

6.for (int i=0; i

7.

8. {

9.

10.//如果发生突变的话

11.

12.if (random() < mutationRate)

13.

14. {

15.

16.//使该权值增加或者减少一个很小的随机数值

17.

18. chromo[i] += ((random()-0.5) * maxPerturbation);

19.

20.//保证袋鼠不至于跳出自然保护区.

21.

22.if(chromo[i] < leftPoint)

23.

24. {

25.

26. chromo[i] = rightPoint;

27.

28. }

29.

30.else if(chromo[i] > rightPoint)

31.

32. {

33.

34. chromo[i] = leftPoint;

35.

36. }

37.

38.//以上代码非基因变异的一般性代码只是用来保证基因编码的可行性。

39.

40. }

41.

42.

43. }

44.}

值得一提的是遗传算法中基因突变的特点和上一章提到的生物学中的基因突变的特点非常相类似,这里回顾一下:

1.基因突变是随机发生的,且突变频率很低。(不过某些应用中需要高概率的变异)

2.大多数基因变异对生物本身是有害的。

3.基因突变是不定向的。

好了,到此为止,基因编码,基因适应度评估,基因选择,基因变异都一一实现了,剩下来的就是把这些遗传过程的“零件”装配起来了。

遗传算法入门到掌握(二)

分类:C++模式识别2011-11-05 16:55 7347人阅读评论(14) 收藏举报算法generationvectormfcoutput引擎

此文承接上篇遗传算法入门到掌握(一)

https://www.360docs.net/doc/1b10723383.html,/emiyasstar__/article/details/6938608

遗传算法引擎――GenAlg

[cpp]view plaincopy

1./遗传算法

2.class GenAlg

3. {

4.

5.public:

6.

7.//这个容器将储存每一个个体的染色体

8.

9. vector vecPop;

10.

11.//人口(种群)数量

12.

13.int popSize;

14.

15.//每一条染色体的基因的总数目

16.

17.int chromoLength;

18.

19.//所有个体对应的适应性评分的总和

20.

21.double totalFitness;

22.

23.//在所有个体当中最适应的个体的适应性评分

24.

25.double bestFitness;

26.

27.//所有个体的适应性评分的平均值

28.

29.double averageFitness;

30.

31.//在所有个体当中最不适应的个体的适应性评分

32.

33.double worstFitness;

34.

35.//最适应的个体在m_vecPop容器里面的索引号

36.

37. Genome fittestGenome;

38.

39.//基因突变的概率,一般介于0.05和0.3之间

40.

41.double mutationRate;

42.

43.//基因交叉的概率一般设为0.7

44.

45.double crossoverRate;

46.

47.//代数的记数器

48.

49.int generation;

50.

51.//最大变异步长

52.

53.double maxPerturbation;

54.

55.double leftPoint;

56.

57.double rightPoint;

58.

59.//构造函数

60.

61. GenAlg();

62.

63.//初始化变量

64.

65.void Reset();

66.

67.//初始化函数

68.

69.void init(int popsize, double MutRate, double CrossRate, int GenLenght,d

ouble LeftPoint,double RightPoint);

70.

71.//计算TotalFitness, BestFitness, WorstFitness, AverageFitness等变量

72.

73.void CalculateBestWorstAvTot();

74.

75.//轮盘赌选择函数

76.

77. Genome GetChromoRoulette();

78.

79.

80.//基因变异函数

81.

82.void Mutate(vector &chromo);

83.

84.//这函数产生新一代基因

85.

86.void Epoch(vector &vecNewPop);

87.

88. Genome GetBestFitness();

89.

90.double GetAverageFitness();

91. };

其中Reset()函数,init()函数和CalculateBestWorstAvTot()函数都比较简单,读者查看示例程序的代码就能明白了。而下面分别介绍init函数和Epoch 函数。

类的初始化函数――init函数

init函数主要充当CGenAlg类的初始化工作,把一些成员变量都变成可供重新开始遗传算法的状态。(为什么我不在构造函数里面做这些工作呢?因为我的程序里面CGenAlg类是View类的成员变量,只会构造一次,所以需要另外的初始化函数。)下面是init函数的代码:

[cpp]view plaincopy

1.void GenAlg::init(int popsize, double MutRate, double CrossRate, int GenLeng

ht,double LeftPoint,double RightPoint)

2.

3.{

4.

5. popSize = popsize;

6.

7. mutationRate = MutRate;

8.

9. crossoverRate = CrossRate;

10.

11. chromoLength = GenLenght;

12.

13. totalFitness = 0;

14.

15. generation = 0;

16.

17.//fittestGenome = 0;

18.

19. bestFitness = 0.0;

20.

21. worstFitness = 99999999;

22.

23. averageFitness = 0;

24.

25. maxPerturbation=0.004;

26.

27. leftPoint=LeftPoint;

28.

29. rightPoint=RightPoint;

30.

31.//清空种群容器,以初始化

32.

33. vecPop.clear();

34.

35.for (int i=0; i

36.

37. {

38.

39.//类的构造函数已经把适应性评分初始化为0

40.

41. vecPop.push_back(Genome());

42.

43.//把所有的基因编码初始化为函数区间内的随机数。

44.

45.for (int j=0; j

46.

47. {

48.

49. vecPop[i].vecGenome.push_back(random() *

50.

51. (rightPoint - leftPoint) + leftPoint);

52.

53. }

54.

55. }

56.

恩,正如我之前说的,我们这个程序不但要应付基因编码只有一个浮点数的“袋鼠跳”问题的情况,还希望以后在处理一串浮点数编码的时候也一样适用,所以从这里开始我们就把基因当成串来对待。

开创新的纪元――Epoch函数

现在万事具备了,只差把所有现成的“零件”装配起来而已。而Epoch函数就正好充当这个职能。下面是这个函数的实现:

[cpp]view plaincopy

1.void GenEngine:: OnStartGenAlg()

2.

3.{

4.

5.

6.//产生随机数

7.

8. srand( (unsigned)time( NULL ) );

9.

10.//初始化遗传算法引擎

11.

12. genAlg.init(g_popsize, g_dMutationRate, g_dCrossoverRate, g_numGen,g_Lef

tPoint,g_RightPoint);

13.

14.//清空种群容器

15.

16. m_population.clear();

17.

18.//种群容器装进经过随机初始化的种群

19.

20. m_population = genAlg.vecPop;

21.

22.//定义两个容器,以装进函数的输入与及输出(我们这个函数是单输入单输出的,但是以后

往往不会那么简单,所以我们这里先做好这样的准备。)

23.

24. vector input;

25.double output;

27. input.push_back(0);

28.

29.for(int Generation = 0;Generation <= g_Generation;Generation++)

30.

31. {

32.

33.//里面是对每一条染色体进行操作

34.

35.for(int i=0;i

36.

37. {

38.

39. input = m_population[i].vecGenome;

40.

41.//为每一个个体做适应性评价,如之前说的,评价分数就是函数值。其

42.

43.//Function函数的作用是输入自变量返回函数值,读者可以参考其代码。

44.

45. output = (double)curve.function(input);

46.

47. m_population[i].fitness = output;

48.

49. }

50.

51.//由父代种群进化出子代种群(长江后浪退前浪。)

52.

53. genAlg.Epoch(m_population);

54.

55.

56.//if(genAlg.GetBestFitness().fitness>=bestFitness)

57. bestSearch=genAlg.GetBestFitness().vecGenome[0];

58. bestFitness=genAlg.GetBestFitness().fitness;

59. averageFitness=genAlg.GetAverageFitness();

60.//cout<

61. report(Generation+1);

62. }

63.

64.//return bestSearch;

65.

66.}

恩,到这里“袋鼠跳”的主要代码就完成了。(其它一些代码,比如图形曲线的显示,和MFC的相关代码在这就不作介绍了,建议初学者不必理会那些代码,只要读懂算法引擎部分就可以了。)下面就只等着我们下达命令了!

让袋鼠在你的电脑里进化――程序的运行

我想没有什么别的方法比自己亲手写一个程序然后通过修改相关参数不断调试程序,更能理解并且掌握一种算法了。不知道你还记不记得你初学程序的日子,我想你上机动手写程序比坐在那里看一本厚厚的程序开发指南效率不知高上多少倍,兴趣也特命浓厚,激情也特别高涨。恩,你就是需要那样的感觉,学遗传算法也是一样的。你需要把自己的代码运行起来,然后看看程序是否按照你所想象的去运行,如果没有,你就要思考原因,按照你的想法去改善代码,试着去弄清其中的内在联系。这是一个思维激活的过程,你大脑中的神经网络正在剧烈抖动(呵呵,或许学到后面你就知道你大脑的神经网络是如何“抖动”的。),试图去接受这新鲜而有趣的知识。遗传算法(包括以后要学到的人工神经网络)包含大量的可控参数,比如进化代数、人口数目、选择概率、交叉概率、变异概率、变异的步长还有以后学到的很多。这些参数之间的搭配关系,不能指望别人用“灌输”的方式让你被动接受,这需要你自己在不断的尝试,不断的调整中去形成一种“感觉”的。很多时候一个参数的量变在整个算法中会表现出质的变化。而算法的效果又能从宏观上反映参数的设置。

现在就让我们来对这个程序做简单的说明。

参数的设置:

这个程序有很多的需要预先设置好的参数,为了方便修改,我把它们都定义为全局变量,定义和初始化都放在Parameter.h的头文件里面。下面对几个主要参数的说明:

1.//目标函数的左右区间,目前的设置是[-1,2]

2.

3.double g_LeftPoint = -1;

4.

5.double g_RightPoint = 2;

6.

4遗传算法与函数优化

第四章遗传算法与函数优化 4.1 研究函数优化的必要性: 首先,对很多实际问题进行数学建模后,可将其抽象为一个数值函数的优化问题。由于问题种类的繁多,影响因素的复杂,这些数学函数会呈现出不同的数学特征。除了在函数是连续、可求导、低阶的简单情况下可解析地求出其最优解外,大部分情况下需要通过数值计算的方法来进行近似优化计算。 其次,如何评价一个遗传算法的性能优劣程度一直是一个比较难的问题。这主要是因为现实问题种类繁多,影响因素复杂,若对各种情况都加以考虑进行试算,其计算工作量势必太大。由于纯数值函数优化问题不包含有某一具体应用领域中的专门知识,它们便于不同应用领域中的研究人员能够进行相互理解和相互交流,并且能够较好地反映算法本身所具有的本质特征和实际应用能力。所以人们专门设计了一些具有复杂数学特征的纯数学函数,通过遗传算法对这些函数的优化计算情况来测试各种遗传算法的性能。 4.2 评价遗传算法性能的常用测试函数 在设计用于评价遗传算法性能的测试函数时,必须考虑实际应用问题的数学模型中所可能呈现出的各种数学特性,以及可能遇到的各种情况和影响因素。这里所说的数学特性主要包括: ●连续函数或离散函数; ●凹函数或凸函数; ●二次函数或非二次函数; ●低维函数或高维函数; ●确定性函数或随机性函数; ●单峰值函数或多峰值函数,等等。 下面是一些在评价遗传算法性能时经常用到的测试函数: (1)De Jong函数F1: 这是一个简单的平方和函数,只有一个极小点f1(0, 0, 0)=0。

(2)De Jong 函数F2: 这是一个二维函数,它具有一个全局极小点f 2(1,1) = 0。该函数虽然是单峰值的函数,但它却是病态的,难以进行全局极小化。 (3)De Jong 函数F3: 这是一个不连续函数,对于]0.5,12.5[--∈i x 区域内的每一个点,它都取全局极小值 30),,,,(543213-=x x x x x f 。

遗传算法的优缺点

遗传算法属于进化算法( Evolutionary Algorithms) 的一种, 它通过模仿自然界的选择与遗传的机理来寻找最优解. 遗传算法有三个基本算子: 选择、交叉和变异. 。数值方法求解这一问题的主要手段是迭代运算。一般的迭代方法容易陷入局部极小的陷阱而出现"死循环"现象,使迭代无法进行。遗传算法很好地克服了这个缺点,是一种全局优化算法。 生物在漫长的进化过程中,从低等生物一直发展到高等生物,可以说是一个绝妙的优化过程。这是自然环境选择的结果。人们研究生物进化现象,总结出进化过程包括复制、杂交、变异、竞争和选择。一些学者从生物遗传、进化的过程得到启发,提出了遗传算法( GA)。算法中称遗传的生物体为个体( individual ),个体对环境的适应程度用适应值( fitness )表示。适应值取决于个体的染色体(chromosome),在算法中染色体常用一串数字表示,数字串中的一位对应一个基因 (gene)。一定数量的个体组成一个群体(population )。对所有个体进 行选择、交叉和变异等操作,生成新的群体,称为新一代( new generation )。遗传算法计算程序的流程可以表示如下[3]:第一步准备工作 (i)选择合适的编码方案,将变量(特征)转换为染色体(数字串,串长为m。通常用二 进制编码。 (2 )选择合适的参数,包括群体大小(个体数M)、交叉概率PC和变异概率Pm (3、确定适应值函数f (x、。f (x、应为正值。 第二步形成一个初始群体(含M个个体)。在边坡滑裂面搜索问题中,取已分析的可能滑裂 面组作为初始群体。 第三步对每一染色体(串)计算其适应值fi ,同时计算群体的总适应值。 第四步选择 计算每一串的选择概率Pi=fi/F 及累计概率。选择一般通过模拟旋转滚花轮 ( roulette ,其上按Pi大小分成大小不等的扇形区、的算法进行。旋转M次即可选出M个串来。在计算机 上实现的步骤是:产生[0,1]间随机数r,若rpc ,则该串参加交叉操作,如此选出参加交叉的一组后,随机配对。 (2)对每一对,产生[1 , m]间的随机数以确定交叉的位置。 第六步变异 如变异概率为Pm则可能变异的位数的期望值为Pm x mx M,每一位以等概率变异。具体为 对每一串中的每一位产生[0 , 1]间的随机数r,若r

第三章-遗传算法的理论基础

第三章 遗传算法的理论基础 遗传算法有效性的理论依据为模式定理和积木块假设。模式定理保证了较优的模式(遗传算法的较优解)的样本呈指数级增长,从而满足了寻找最优解的必要条件,即遗传算法存在着寻找到全局最优解的可能性。而积木块假设指出,遗传算法具备寻找到全局最优解的能力,即具有低阶、短距、高平均适应度的模式(积木块)在遗传算子作用下,相互结合,能生成高阶、长距、高平均适应度的模式,最终生成全局最优解。Holland 的模式定理通过计算有用相似性,即模式(Pattern)奠定了遗传算法的数学基础。该定理是遗传算法的主要定理,在一定程度上解释了遗传算法的机理、数学特性以及很强的计算能力等特点。 3.1 模式定理 不失一般性,本节以二进制串作为编码方式来讨论模式定理(Pattern Theorem)。 定义3.1 基于三值字符集{0,1,*}所产生的能描述具有某些结构相似性的0、1字符串集的字符串称作模式。 以长度为5的串为例,模式*0001描述了在位置2、3、4、5具有形式“0001”的所有字符串,即(00001,10001) 。由此可以看出,模式的概念为我们提供了一种简洁的用于描述在某些位置上具有结构相似性的0、1字符串集合的方法。 引入模式后,我们看到一个串实际上隐含着多个模式(长度为 n 的串隐含着2n 个模式) ,一个模式可以隐含在多个串中,不同的串之间通过模式而相互联系。遗传算法中串的运算实质上是模式的运算。因此,通过分析模式在遗传操作下的变化,就可以了解什么性质被延续,什么性质被丢弃,从而把握遗传算法的实质,这正是模式定理所揭示的内容 定义3.2 模式H 中确定位置的个数称作该模式的阶数,记作o(H)。比如,模式 011*1*的阶数为4,而模式 0* * * * *的阶数为1。 显然,一个模式的阶数越高,其样本数就越少,因而确定性越高。 定义3.3 模式H 中第一个确定位置和最后一个确定位置之间的距离称作该模式的定义距,记作)(H δ。比如,模式 011*1*的定义距为4,而模式 0* * * * *的定义距为0。 模式的阶数和定义距描述了模式的基本性质。 下面通过分析遗传算法的三种基本遗传操作对模式的作用来讨论模式定理。令)(t A 表示第t 代中串的群体,以),,2,1)((n j t A j =表示第t 代中第j 个个体串。 1.选择算子 在选择算子作用下,与某一模式所匹配的样本数的增减依赖于模式的平均适值,与群体平均适值之比,平均适值高于群体平均适值的将呈指数级增长;而平均适值低于群体平均适值的模式将呈指数级减少。其推导如下: 设在第t 代种群)(t A 中模式所能匹配的样本数为m ,记为),(t H m 。在选择中,一个位串 j A 以概率/j j i P f f =∑被选中并进行复制,其中j f 是个体)(t A j 的适应度。假设一代中群体 大小为n ,且个体两两互不相同,则模式H 在第1+t 代中的样本数为:

遗 传 算 法 详 解 ( 含 M A T L A B 代 码 )

GATBX遗传算法工具箱函数及实例讲解 基本原理: 遗传算法是一种典型的启发式算法,属于非数值算法范畴。它是模拟达尔文的自然选择学说和自然界的生物进化过程的一种计算模型。它是采用简单的编码技术来表示各种复杂的结构,并通过对一组编码表示进行简单的遗传操作和优胜劣汰的自然选择来指导学习和确定搜索的方向。遗传算法的操作对象是一群二进制串(称为染色体、个体),即种群,每一个染色体都对应问题的一个解。从初始种群出发,采用基于适应度函数的选择策略在当前种群中选择个体,使用杂交和变异来产生下一代种群。如此模仿生命的进化进行不断演化,直到满足期望的终止条件。 运算流程: Step 1:对遗传算法的运行参数进行赋值。参数包括种群规模、变量个数、交叉概率、变异概 率以及遗传运算的终止进化代数。 Step 2:建立区域描述器。根据轨道交通与常规公交运营协调模型的求解变量的约束条件,设置变量的取值范围。 Step 3:在Step 2的变量取值范围内,随机产生初始群体,代入适应度函数计算其适应度值。 Step 4:执行比例选择算子进行选择操作。 Step 5:按交叉概率对交叉算子执行交叉操作。

Step 6:按变异概率执行离散变异操作。 Step 7:计算Step 6得到局部最优解中每个个体的适应值,并执行最优个体保存策略。 Step 8:判断是否满足遗传运算的终止进化代数,不满足则返回Step 4,满足则输出运算结果。 运用遗传算法工具箱: 运用基于Matlab的遗传算法工具箱非常方便,遗传算法工具箱里包括了我们需要的各种函数库。目前,基于Matlab的遗传算法工具箱也很多,比较流行的有英国设菲尔德大学开发的遗传算法工具箱GATBX、GAOT以及Math Works公司推出的GADS。实际上,GADS就是大家所看到的Matlab中自带的工具箱。我在网上看到有问为什么遗传算法函数不能调用的问题,其实,主要就是因为用的工具箱不同。因为,有些人用的是GATBX带有的函数,但MATLAB自带的遗传算法工具箱是GADS,GADS当然没有GATBX里的函数,因此运行程序时会报错,当你用MATLAB来编写遗传算法代码时,要根据你所安装的工具箱来编写代码。 以GATBX为例,运用GATBX时,要将GATBX解压到Matlab下的toolbox文件夹里,同时,set path将GATBX文件夹加入到路径当中。 这块内容主要包括两方面工作:1、将模型用程序写出来(.M文件),即目标函数,若目标函数非负,即可直接将目标函数作为适应度函数。2、设置遗传算法的运行参数。包括:种群规模、变量个数、区域描述器、交叉概率、变异概率以及遗传运算的终止进化代数等等。

遗传算法

基于新的混合遗传算法的订单生产工序顺序相关的流水车 间调度问题研究 A novel hybrid genetic algorithm to solve the make-to-order sequence-dependent flow-shop scheduling problem Mohammad Mirabi ?S. M. T. Fatemi Ghomi ?F. Jolai 2013年5月29号收到该文献,2014年3月18号录取,2014年4月9日出版.作者(2014).这篇文章在开放存取的https://www.360docs.net/doc/1b10723383.html, 网站发表 摘要流水车间调度问题(FSP)用于处理m台机器n个工序的流水作业。尽管FSP是典 型的NP-hard问题,依然没有有效的算法以找到这个问题的最优解。为了减少库存,延迟和安装成本,在工作时间一定,序列相关的每台机器上解决流水车间调度排序问题,在这提出了一种有三个遗传算子的新型混合遗传算法(HGA)。该算法应用一种改进的方法来生成初始种群,并使用一种应用迭代交换过程改进初始解的改进启发式算法。我们认为订单式生产方式,工序间隔时间是基于最大安装成本的禁忌搜索算法的解。此外,与最近开发的启发式算法通过计算实验结果比较表明,该算法在解\的精度和效率方面表现出非常强的竞争力。 关键词:混合遗传算法流水作业调度序列相关 引言 流车间调度问题(FSP)作为在制造业研究的主要问题已经近七十年。在一个有M台机器的流水作业车间中有m个工位,每个工序又有一台或几台机器。此外,有n个工件在m个工位上依次加工。在经典的流水作业问题里,每个工位都有一台机器,这一领域的研究吸引了最多的人次。FSP的两个主要子问题是序列独立时间设置(SIST)和顺序相关时间设置(SDST)。SDST流水作业问题更具有现实意义,但是吸引的注意力却少得多,特别是2000年以前(Allahverdi等,2008) 在流水车间调度问题的目标是找到一个序列的机器加工的作业,以便一个给定的标准进行了优化。这里有n个工件在每台机器上操作的可能的顺序,以及(N!)*M个的可能处理顺序。流水作业调度的研究通常只参加置换序列,其中操作的处理顺序是所有机器。在这里,我们也采用这种限制。 最小化所有最大完工时间作业(成为完工期并通过的Cmax表示)是公知的,也是在文献M. Mirabi (&) Group of Industrial Engineering, Ayatollah Haeri University of Meybod, P.O. Box 89619-55133, Meybod, Iran e-mail: M.Mirabi@https://www.360docs.net/doc/1b10723383.html, S. M. T. Fatemi Ghomi Department of Industrial Engineering, Amirkabir University of Technology, P.O. Box 15916-34311, Tehran, Iran e-mail: Fatemi@aut.ac.ir F. Jolai Department of Industrial Engineering, College of Engineering, University of Tehran, P.O. Box 14395-515, Tehran, Iran

遗传算法经典MATLAB代码

遗传算法经典学习Matlab代码 遗传算法实例: 也是自己找来的,原代码有少许错误,本人都已更正了,调试运行都通过了的。 对于初学者,尤其是还没有编程经验的非常有用的一个文件 遗传算法实例 % 下面举例说明遗传算法 % % 求下列函数的最大值 % % f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] % % 将 x 的值用一个10位的二值形式表示为二值问题,一个10位的二值数提供的分辨率是每为 (10-0)/(2^10-1)≈0.01。 % % 将变量域 [0,10] 离散化为二值域 [0,1023], x=0+10*b/1023, 其 中 b 是 [0,1023] 中的一个二值数。 % % % %--------------------------------------------------------------------------------------------------------------% %--------------------------------------------------------------------------------------------------------------% % 编程 %----------------------------------------------- % 2.1初始化(编码) % initpop.m函数的功能是实现群体的初始化,popsize表示群体的大小,chromlength表示染色体的长度(二值数的长度),

% 长度大小取决于变量的二进制编码的长度(在本例中取10位)。 %遗传算法子程序 %Name: initpop.m %初始化 function pop=initpop(popsize,chromlength) pop=round(rand(popsize,chromlength)); % rand随机产生每个单元 为 {0,1} 行数为popsize,列数为chromlength的矩阵, % roud对矩阵的每个单元进行圆整。这样产生的初始种群。 % 2.2 计算目标函数值 % 2.2.1 将二进制数转化为十进制数(1) %遗传算法子程序 %Name: decodebinary.m %产生 [2^n 2^(n-1) ... 1] 的行向量,然后求和,将二进制转化为十进制function pop2=decodebinary(pop) [px,py]=size(pop); %求pop行和列数 for i=1:py pop1(:,i)=2.^(py-i).*pop(:,i); end pop2=sum(pop1,2); %求pop1的每行之和 % 2.2.2 将二进制编码转化为十进制数(2) % decodechrom.m函数的功能是将染色体(或二进制编码)转换为十进制,参数spoint表示待解码的二进制串的起始位置

遗传算法的计算性能的统计分析

第32卷 第12期2009年12月 计 算 机 学 报 CH INESE JOURNA L OF COMPU TERS Vol.32No.12 Dec.2009 收稿日期:2008210219;最终修改稿收到日期:2009209227.本课题得到国家自然科学基金(60774084)资助.岳 嵚,男,1977年生,博士研究生,主要研究方向为进化算法.E 2mail:yueqqin@si https://www.360docs.net/doc/1b10723383.html,.冯 珊,女,1933年生,教授,博士生导师,主要研究领域为智能决策支持系统. 遗传算法的计算性能的统计分析 岳 嵚 冯 珊 (华中科技大学控制科学与工程系 武汉 430074) 摘 要 通过对多维解析函数的多次重复计算并对计算结果进行统计分析来讨论遗传算法的可靠性和可信度,结果表明:遗传算法的计算结果具有一定的稳定性,可以通过采用多次重复计算的方法提高计算结果的可信度,并用以评价算法及其改进的实际效果.关键词 遗传算法;计算可靠性;置信区间 中图法分类号TP 18 DOI 号:10.3724/SP.J.1016.2009.02389 The Statistical Analyses for Computational Performance of the Genetic Algorithms YU E Qin FENG Shan (Dep artment of Contr ol Science and Eng ineering ,H uazhong University of Science and T ech nology ,W u han 430074) Abstr act In this paper,the author s discuss the reliability of the GAs by reiteratively computing the multi 2dimensional analytic functions and statistical analysis of the results.The analysis re 2sults show that the GAs have certain stability;it could improve the reliability by reiteratively computation and estimates the effects of improvements. Keywor ds genetic algorithms;computational stability;confidence interval 1 遗传算法的随机性 遗传算法是将生物学中的遗传进化原理和随机优化理论相结合的产物,是一种随机性的全局优化算法[1].遗传算法作为一种启发式搜索算法,其计算结果具有不稳定性和不可重现性;遗传算法的进化过程具有有向随机性,整体上使种群的平均适应度不断提高.现在学术界对遗传算法中的某些遗传操作的作用机制还不十分清楚,遗传算法的许多性能特点无法在数学上严格证明.遗传算法的计算过程会受到各种随机因素的影响,如随机产生的初始种群和随机进行的变异操作等,尤其初始种群对计算结果影响较大.但另一方面,大量的实算结果表明,遗传算法的计算结果具有一定的规律性,在统计意义上具有一定的可靠性,这样就可以对待求解问题 进行多次重复计算后取平均值的方法,提高遗传算 法在实际计算中的准确性和可信度. 包括遗传算法在内的启发式搜索算法主要用于解决大型的复杂优化问题,这些问题一般难以使用传统的优化算法解决.遗传算法对这类问题的计算结果也难达到精确的最优解.这给对用遗传算法解决实际工程优化问题的计算结果的评价带来了困难,在实际工程计算中也难以评价遗传算法及其改进型的计算效果的优劣. 为了分析遗传算法的计算性能,本文采用的计算对象是一个复杂的多维解析函数.使用这类函数评价遗传算法计算性能的好处是可以事先通过其他方法求得最优解,这样便于评价遗传算法及其改进型的计算效果.本文从统计学角度对多次重复计算的结果进行分析,试图得到遗传算法的稳定性和可信度方面的相关结论,通过分析遗传算法及其改进

三个遗传算法matlab程序实例

遗传算法程序(一): 说明: fga.m 为遗传算法的主程序; 采用二进制Gray编码,采用基于轮盘赌法的非线性排名选择, 均匀交叉,变异操作,而且还引入了倒位操作! function [BestPop,Trace]=fga(FUN,LB,UB,eranum,popsize,pCross,pMutation,pInversion,options) % [BestPop,Trace]=fmaxga(FUN,LB,UB,eranum,popsize,pcross,pmutation) % Finds a maximum of a function of several variables. % fmaxga solves problems of the form: % max F(X) subject to: LB <= X <= UB % BestPop - 最优的群体即为最优的染色体群 % Trace - 最佳染色体所对应的目标函数值 % FUN - 目标函数 % LB - 自变量下限 % UB - 自变量上限 % eranum - 种群的代数,取100--1000(默认200) % popsize - 每一代种群的规模;此可取50--200(默认100) % pcross - 交叉概率,一般取0.5--0.85之间较好(默认0.8) % pmutation - 初始变异概率,一般取0.05-0.2之间较好(默认0.1) % pInversion - 倒位概率,一般取0.05-0.3之间较好(默认0.2) % options - 1*2矩阵,options(1)=0二进制编码(默认0),option(1)~=0十进制编 %码,option(2)设定求解精度(默认1e-4) % % ------------------------------------------------------------------------ T1=clock; if nargin<3, error('FMAXGA requires at least three input arguments'); end if nargin==3, eranum=200;popsize=100;pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];end if nargin==4, popsize=100;pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];end if nargin==5, pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];end if nargin==6, pMutation=0.1;pInversion=0.15;options=[0 1e-4];end if nargin==7, pInversion=0.15;options=[0 1e-4];end if find((LB-UB)>0) error('数据输入错误,请重新输入(LB

遗传算法的计算性能的统计分析

遗传算法遗传算法的计算性能的统计分析 岳嵚冯珊 (华中科技大学控制科学与工程系) 摘要:本文通过对多维解析函数的多次重复计算并对计算结果的进行统计分析来讨论遗传算法的可靠性和可信度,结果表明:遗传算法的计算结果具有一定的稳定性,可以通过采用多次重复计算的方法提高计算结果的可信度,并用以评价算法及其改进的实际效果。 关键词:遗传算法;计算可靠性;置信区间 分类号:TP18 1遗传算法的随机性 遗传算法是将生物学中的遗传进化原理和随机优化理论相结合的产物,是一种随机性的全局优化算法[1]。遗传算法作为一种启发式搜索算法,其计算结果具有不稳定性和不可重现性;遗传算法的进化过程具有有向随机性,整体上使种群的平均适应度不断提高。现在学术界对遗传算法中的某些遗传操作的作用机制还不十分清楚,遗传算法的许多性能特点无法在数学上严格证明。遗传算法的计算过程会受到各种随机因素的影响,如随机产生的初始种群和随机进行的变异操作等,尤其初是始种群对计算结果影响较大。但另一方面,大量的实算结果表明,遗传算法的计算结果具有一定的规律性,在统计意义上具有一定的可靠性,这样就可以对待求解问题进行多次重复计算后取平均值的方法,提高遗传算法在实际计算中的准确性和可信度。 包括遗传算法在内的启发式搜索算法主要用于解决大型的复杂优化问题,这些问题一般难以使用传统的优化算法解决。遗传算法对这类问题的计算结果也难达到精确的最优解。这给对用遗传算法解决实际工程优化问题的计算结果的评价带来了困难,在实际工程计算中也难以评价遗传算法及其改进型的计算效果的优劣。 为了分析遗传算法的计算性能,本文采用的计算对象是一个复杂的多维解析函数。使用这类函数评价遗传算法计算性能的好处是可以事先通过其他方法求得最优解,这样便于评价遗传算法及其改进型的计算效果。本文从统计学角度对多次重复计算的结果进行分析,试图得到遗传算法的稳定性和可信度方面的相关结论,通过分析遗传算法及其改进型求解解析问题的计算效果,再把所得到的相关结论推广应用到复杂的工程实际问题中去。 遗传算法在实际使用中有多种形式的变型,经典遗传算法是遗传算法的最简单的形式,但是经典遗传算法并不理想。本文使用的是粗粒度并行遗传算法。粗粒度并行遗传算法是遗传算法的一个重要改进型。它具有比经典遗传算法更好的计算性能。 2算例、实验方法和实验结果 2.1算例 本文所使用的算例是Deb 函数: ]10,10[,)]4cos(10[10)(12?∈??+=∑=i n i i i Deb x n x x x f i π(1) Deb 函数是一个高维的非凸函数,该函数在点(9.7624,9.7624,…,9.7624)上取得最大

最新最全的遗传算法工具箱及说明

最新最全的遗传算法工具箱Gaot_v5及说明 Gaot_v5下载地址:https://www.360docs.net/doc/1b10723383.html,/mirage/GAToolBox/gaot/gaotv5.zip 添加遗传算法路径: 1、 matlab的file下面的set path把它加上,把路径加进去后在 2、 file→Preferences→General的Toolbox Path Caching里点击update Toolbox Path Cache更新一下,就OK了

遗传算法工具箱Gaot_v5包括许多实用的函数,各种算子函数,各种类型的选择方式,交叉、变异方式。这些函数按照功能可以分成以下几类:

主程序 ga.m提供了 GAOT 与外部的接口。它的函数格式如下: [x endPop bPop traceInfo]=ga(bounds,evalFN,evalOps,startPop,opts,termFN,termOps, selectFn,selectOps,xOverFNs,xOverOps,mutFNs,mutOps) 输出参数及其定义如表 1 所示。输入参数及其定义如表 2 所示。 表1 ga.m的输出参数 输出参数 定义 x 求得的最好的解,包括染色体和适应度 endPop 最后一代染色体(可选择的) bPop 最好染色体的轨迹(可选择的) traceInfo 每一代染色体中最好的个体和平均适应度(可选择的) 表2 ga.m的输入参数 表3 GAOT核心函数及其它函数

核心函数: (1)function [pop]=initializega(num,bounds,eevalFN,eevalOps,options)--初始种群的生成函数 【输出参数】 pop--生成的初始种群 【输入参数】 num--种群中的个体数目 bounds--代表变量的上下界的矩阵 eevalFN--适应度函数 eevalOps--传递给适应度函数的参数 options--选择编码形式(浮点编码或是二进制编码)[precision F_or_B],如 precision--变量进行二进制编码时指定的精度 F_or_B--为1时选择浮点编码,否则为二进制编码,由precision指定精度) (2)function [x,endPop,bPop,traceInfo] = ga(bounds,evalFN,evalOps,startPop,opts,... termFN,termOps,selectFN,selectOps,xOverFNs,xOverOps,mutFNs,mutOps)--遗传算法函数 【输出参数】 x--求得的最优解 endPop--最终得到的种群 bPop--最优种群的一个搜索轨迹 【输入参数】

遗传算法基本理论实例

目录 _ 一、遗产算法的由来 (2) 二、遗传算法的国内外研究现状 (3) 三、遗传算法的特点 (5) 四、遗传算法的流程 (7) 五、遗传算法实例 (12) 六、遗传算法编程 (17) 七、总结 ......... 错误!未定义书签。附录一:运行程序.. (19)

遗传算法基本理论与实例 一、遗产算法的由来 遗传算法(Genetic Algorithm,简称GA)起源于对生物系统所进行的计算机模拟研究。20世纪40年代以来,科学家不断努力从生物学中寻求用于计算科学和人工系统的新思想、新方法。很多学者对关于从生物进化和遗传的激励中开发出适合于现实世界复杂适应系统研究的计算技术——生物进化系统的计算模型,以及模拟进化过程的算法进行了长期的开拓性的探索和研究。John H.Holland教授及其学生首先提出的遗传算法就是一个重要的发展方向。 遗传算法借鉴了达尔文的进化论和孟德尔、摩根的遗传学说。按照达尔文的进化论,地球上的每一物种从诞生开始就进入了漫长的进化历程。生物种群从低级、简单的类型逐渐发展成为高级复杂的类型。各种生物要生存下去及必须进行生存斗争,包括同一种群内部的斗争、不同种群之间的斗争,以及生物与自然界无机环境之间的斗争。具有较强生存能力的生物个体容易存活下来,并有较多的机会产生后代;具有较低生存能力的个体则被淘汰,或者产生后代的机会越来越少。,直至消亡。达尔文把这一过程和现象叫做“自然选择,适者生存”。按照孟德尔和摩根的遗传学理论,遗传物质是作为一种指令密码封装在每个细胞中,并以基因的形式排列在染色体上,每个基因有特殊的位置并控制生物的某些特性。不同的基因组合产生的个体对环境的适应性不一样,通过基因杂交和突变可以产生对环境适应性强的后代。经过优胜劣汰的自然选择,适应度值高的基因结构就得以保存下来,从而逐渐形成了经典的遗传学染色体理论,揭示了遗传和变异的

人工智能之遗传算法论文含源代码

30维线性方程求解 摘要:非线性方程组的求解是数值计算领域中最困难的问题,大多数的数值求解算法例如牛顿法的收敛性和性能特征在很大程度上依赖于初始点。但是对于很多高维的非线性方程组,选择好的初始点是一件非常困难的事情。本文采用了遗传算法的思想,提出了一种用于求解非线性方程组的混合遗传算法。该混合算法充分发挥了遗传算法的群体搜索和全局收敛性。选择了几个典型非线性方程组,考察它们的最适宜解。 关键词:非线性方程组;混合遗传算法;优化 1. 引言遗传算法是一种通用搜索算法,它基于自然选择机制和自然遗传规律来模拟自然界的进化过程,从而演化出解决问题的最优方法。它将适者生存、结构化但同时又是 随机的信息交换以及算法设计人的创造才能结合起来,形成一种独特的搜索算法,把一些解决方案用一定的方式来表示,放在一起成为群体。每一个方案的优劣程度即为适应性,根据自然界进化“优胜劣汰”的原则,逐步产生它们的后代,使后代具有更强的适应性,这样不断演化下去,就能得到更优解决方案。 随着现代自然科学和技术的发展,以及新学科、新领域的出现,非线性科学在工农业、经济政治、科学研究方面逐渐占有极其重要的位置。在理论研究和应用实践中,几乎绝大多数的问题都最终能化为方程或方程组,或者说,都离不开方程和方程组的求解。因此,在非线性问题中尤以非线性方程和非线性方程组的求解最为基本和重要。传统的解决方法,如简单迭代法、牛顿法、割线法、延拓法、搜索法、梯度法、共轭方向法、变尺度法,无论从算法的选择还是算法本身的构造都与所要解决的问题的特性有很大的关系。很多情况下,算法中算子的构造及其有效性成为我们解决问题的巨大障碍。而遗传算法无需过多地考虑问题的具体形式,因为它是一种灵活的自适应算法,尤其在一些非线性方程组没有精确解的时候,遗传算法显得更为有效。而且,遗传算法是一种高度并行的算法,且算法结构简单,非常便于在计算机上实现。本文所研究的正是将遗传算法应用于求解非线性方程组的问题。 2. 遗传算法解非线性方程组为了直观地观察用遗传算法求解非线性方程组的效果,我们这里用代数非线性方程组作为求解的对象问题描述:非线性方程组指的是有n 个变量(为了简化讨论,这里只讨论实变量方程组)的方程组 中含有非线性方程。其求解是指在其定义域内找出一组数能满足方程组中的每 个方程。这里,我们将方程组转化为一个函数则求解方程组就转化为求一组值使得成立。即求使函数取得最小值0 的一组数,于是方程组求解问题就转变为函数优化问题 3. 遗传算子 遗传算子设计包括交叉算子、变异算子和选择算子的设计。

一个简单实用的遗传算法c程序

一个简单实用的遗传算法c程序(转载) c++ 2009-07-28 23:09:03 阅读418 评论0 字号:大中小 这是一个非常简单的遗传算法源代码,是由Denis Cormier (North Carolina State University)开发的,Sita S.Raghavan (University of North Carolina at Charlotte)修正。代码保证尽可能少,实际上也不必查错。对一特定的应用修正此代码,用户只需改变常数的定义并且定义“评价函数”即可。注意代码的设计是求最大值,其中的目标函数只能取正值;且函数值和个体的适应值之间没有区别。该系统使用比率选择、精华模型、单点杂交和均匀变异。如果用Gaussian变异替换均匀变异,可能得到更好的效果。代码没有任何图形,甚至也没有屏幕输出,主要是保证在平台之间的高可移植性。读者可以从https://www.360docs.net/doc/1b10723383.html,,目录coe/evol 中的文件prog.c中获得。要求输入的文件应该命名为…gadata.txt?;系统产生的输出文件为…galog.txt?。输入的文件由几行组成:数目对应于变量数。且每一行提供次序——对应于变量的上下界。如第一行为第一个变量提供上下界,第二行为第二个变量提供上下界,等等。 /**************************************************************************/ /* This is a simple genetic algorithm implementation where the */ /* evaluation function takes positive values only and the */ /* fitness of an individual is the same as the value of the */ /* objective function */ /**************************************************************************/ #include #include #include /* Change any of these parameters to match your needs */

遗传算法基本理论与方法

摘要:基本遗传算法的操作是以个体为对象,只使用选择、交叉和变异遗传算子,遗传进化操作过程的简单框架。模式定理和积木块假设是解释遗传算法有效性的理论基础,理论分析与实际应用都表明基本的遗传算法不能处处收敛于全局最优解,因此基本遗传算法有待进一步改进。 关键词:遗传算法;遗传算法的改进 1.标准遗传算法 基本遗传算法包括选择、交叉和变异这些基本遗传算子。其数学模型可表示为: sag=(c,e,p0,n,φ,г,ψ,t) 其中c为个体的编码方法;e为个体适应度评价函数;p0为初始种群;n为种群大小;φ为选择算子;г为交叉算子;ψ为变异算子;t为遗传运算终止条件; 2 遗传算法基本方法及其改进 2.1编码方式 编码方式决定了个体的染色体排列形式,其好坏直接影响遗传算法中的选择算子、交叉算子和变异算子的运算,也决定了解码方式。 二进制编码 二进制编码使用的字符号{0,1}作为编码符号,即用一个{0,1}所组成的二进制符号串构成的个体基因型。二进制编码方法应用于遗传算法中有如下优点: 1)遗传算法中的遗传操作如交叉、变异很容易实现,且容易用生物遗传理论来解释; 2)算法可处理的模式多,增强了全局搜索能力; 3)便于编码、解码操作; 4)符合最小字符集编码原则; 5)并行处理能力较强。 二进制编码在存着连续函数离散化的映射误差,不能直接反应出所求问题的本身结构特征,不便于开发专门针对某类问题的遗传运算算子。 2.2初始种群的设定 基本遗传算法是按随机方法在可能解空间内产生一个一定规模的初始群体,然后从这个初始群体开始遗传操作,搜索最优解。初始种群的设定一般服从下列准则:1)根据优化问题,把握最优解所占空间在整个问题空间的分布范围,然后,在此分布范围内设定合适的初始群体。 2)先随机生成一定数目的个体,然后从中挑出最好的个体加入到初始群体中。该过程不断迭代,直到初始群体中个体数目达到了预先确定的种群大小。 2.3选择算子的分析 选择算子的作用是选择优良基因参与遗传运算,目的是防止有用的遗传信息丢失,从而提高全局收敛效率。常用的遗传算子: (1)轮盘赌选择机制 轮盘赌选择也称适应度比例选择,是遗传算法中最基本的选择机制,每个个体被选择进入下一代的概率为这个个体的适应度值占全部个体适应度值之和的比例。但是轮盘赌选择机制选择误差较大,不是所有高适应度值的个体都能被选中,适应度值较低但具有优良基因模式的个体被选择的概率也很低,这样就会导致早熟现象的产生。 (2)最优保存选择机制 最优保存选择机制的基本思想是直接把群体中适应度最高的个体复制到下一代,而不进行配对交叉等遗传操作。具体步骤如下: 1)找出当前群体中适应度值最高和最低的个体的集合;

第七章遗传算法应用举例

第七章 遗传算法应用举例 遗传算法提供了一种求解非线性、多模型、多目标等复杂系统优化问题的通用框架,它不依赖于问题具体的领域。随着对遗传算法技术的不断研究,人们对遗传算法的实际应用越来越重视,它已经广泛地应用于函数优化、组合优化、自动控制、机器人学、图象处理、人工生命、遗传编码、机器学习等科技领域。遗传算法已经在求解旅行商问题、背包问题、装箱问题、图形划分问题等多方面的应用取得了成功。本章通过一些例子,介绍如何利用第五章提供的遗传算法通用函数,编写MATLAB 程序,解决实际问题。 7.1 简单一元函数优化实例 利用遗传算法计算下面函数的最大值: ()sin(10) 2.0[1,2]f x x x x π=?+∈-, 选择二进制编码,种群中个体数目为40,每个种群的长度为20,使用代沟为0.9,最大遗传代数为25。 下面为一元函数优化问题的MA TLAB 代码。 figure(1); fplot ('variable.*sin(10*pi*variable)+2.0',[-1,2]); %画出函数曲线 % 定义遗传算法参数 NIND= 40; % 个体数目(Number of individuals) MAXGEN = 25; % 最大遗传代数(Maximum number of generations) PRECI = 20; % 变量的二进制位数(Precision of variables) GGAP = 0.9; % 代沟(Generation gap) trace=zeros (2, MAXGEN); % 寻优结果的初始值 FieldD = [20;-1;2;1;0;1;1]; % 区域描述器(Build field descriptor) Chrom = crtbp(NIND, PRECI); % 初始种群 gen = 0; % 代计数器 variable=bs2rv(Chrom,FieldD); % 计算初始种群的十进制转换 ObjV = variable.*sin (10*pi*variable)+2.0; % 计算目标函数值 while gen < MAXGEN, FitnV = ranking (-ObjV); % 分配适应度值(Assign fitness values) SelCh = select ('sus', Chrom, FitnV , GGAP); % 选择 SelCh = recombin ('xovsp',SelCh,0.7); % 重组 SelCh = mut(SelCh); % 变异 variable=bs2rv(SelCh,FieldD); % 子代个体的十进制转换 ObjVSel =variable.*sin(10*pi*variable)+2.0; % 计算子代的目标函数值 [Chrom ObjV]=reins(Chrom,SelCh,1,1,ObjV ,ObjVSel); % 重插入子代的新种群 gen = gen+1; % 代计数器增加 % 输出最优解及其序号,并在目标函数图象中标出,Y 为最优解,I 为种群的序号 [Y,I]=max(ObjV),hold on; plot (variable (I),Y , 'bo'); trace (1,gen)=max (ObjV); %遗传算法性能跟踪

相关文档
最新文档