遗传算法介绍并附上Matlab代码

本文介绍了遗传算法的基本原理,并通过一个二维复杂函数优化的例子展示了如何在Matlab中实现遗传算法。文章详细讲解了编码、交叉、变异、选择等关键步骤,并提供了相应的Matlab代码。
摘要由CSDN通过智能技术生成

摘自http://www.cnblogs.com/hxsyl/p/5240905.html

1、遗传算法介绍

遗传算法,模拟达尔文进化论的自然选择和遗产学机理的生物进化构成的计算模型,一种不断选择优良个体的算法。谈到遗传,想想自然界动物遗传是怎么来的,自然主要过程包括染色体的选择,交叉,变异(不明白这个的可以去看看生物学),这些操作后,保证了以后的个基本上是最优的,那么以后再继续这样下去,就可以一直最优了。

2、解决的问题

先说说自己要解决的问题吧,遗传算法很有名,自然能解决的问题很多了,在原理上不变的情况下,只要改变模型的应用环境和形式,基本上都可以。但是遗传算法主要还是解决优化类问题,尤其是那种不能直接解出来的很复杂的问题,而实际情况通常也是这样的。

本部分主要为了了解遗传算法的应用,选择一个复杂的二维函数来进行遗传算法优化,函数显示为y=10*sin(5*x)+7*abs(x-5)+10,这个函数图像为:

怎么样,还是有一点复杂的吧,当然你还可以任意假设和编写,只要符合就可以。那么现在问你要你一下求出最大值你能求出来吗?(这个貌似可以,很容易写出来----如果再复杂一点估计就不行了)这类问题如果用遗传算法或者其他优化方法九很简单了,为什么呢?说白了,其实就是计算机太笨了同时计算速度又超快,举个例子吧,我把x等分成100万份,再一下子都带值进去算,求出对应的100万个y的值,再比较他们的大小找到最大值不就可以了吗,很笨吧,人算是不可能的,但是计算机可以。而遗传算法也是很笨的一个个搜索,只不过加了一点什么了,就是人为的给它算的方向和策略,让它有目的的算,这也就是算法了。

 

3、如何开始?

不明白遗传算法的会问怎么开始呢?恩,其实每个算法都有自己的开始方式,遗传算法也是,首先是选择个体了。我们知道一个种群中可能只有一个个体吗?不可能吧,肯定很多人才对,这样相互结合的机会才多,产生的后代才会多种多样,才会有更好的优良基因,有利于种群的发展。那么算法也是如此,当然个体多少是个问题,一般来说20-100之间我觉得差不多了。那么个体究竟是什么呢?在我们这个问题中自然就是x值了。其他情况下,个体就是所求问题的变量,这里我们假设个体数选100个,也就是开始选100个不同的x值,不明白的话就假设是100个猴子吧。好了,现在有了100个猴子组成的一个种群,那么这个种群应该怎么发展才能越来越好?说到这,我们想想,如何定义这个越来越好呢?这个应该有一个评价指标吧。在我们的这个问题中,好像是对应的y值越大越好是吧。我们甚至可以给他们排个名来决定哪些好哪些不好。我们把这个叫做对于个体的适应度,这应该算是算法的后半部分才对。

 

4、编码

首先明白什么是编码?为什么要编码?如何编码?

好,什么是编码?其实编码就是把自变量(x)换一下形式而已,在这个形式下,更容易操作其他过程(比如交叉,变异什么的)而已。举个例子吧,加入我们取x=1, 2, 3,我们可以把x 编码成x=a, b, c,我就说123对应就是abc,为什么要这样做呢?比如问题里面你能够获取的都是abc的组合之类的,那么这样编码以后,你就可以再返回去成123来操作了。一般的编码都是些什么呢?二进制编码,自然数编码,矩阵编码。。等等,很多,不详细写了。而用的最多的可以说是二进制编码,感觉这和人体DNA,基因的排列很相似。想想DNA怎么排的?不就是在两条长链上一对一排的吗?那么什么是二进制编码?很简单,就是1,0,1,0对应的来回组合排列而已。比如:1100100010, 0011001001等等,这些都是位数长度为10的二进制编码。再想想1在计算机的二进制形式是什么?如果八位来表示的话,是不是就是0000 0001;8是不是就是0000 1000;以此类推,那么我们这里也是这样,把对应的x值换算成这种编码形式,我们这里可以看到x的范围是0-5吧,如何按照计算机这样的方式是不是到0000 0101这里就完事了?想想这样多短,前面五位都没有用上多浪费呀,那么要想都用上怎么办呢?也很简单,我们把0000 0001不认为是1不就可以了吗?因为1111 1111是255,那么如果说每一份为1/255的话,那么0000 0001不就是1/255了吗?这个时候1怎样表示了?不就是1111 1111吗?好了我们把范围扩大一些吧,每一份不是1/255,而是1/255*5,那么这个时候最大值是多少?是不是5,恩,这样x编码的范围不就在0-5之间了吗?这里就又有问题了,想想这样做的话,x的最小精度是多少?就是1/255*5.虽然很小,但是在0-1/255*5之间的数你能不能取到?无论如何都取不到吧。那么就又来一个问题,怎样去扩大这个精度呢?如果要保持0-5不变的话,只能增加位数了,把9位编码编程10位,20位,100位,哇,够大了吧,变成100个0,1组合,很恐怖吧,事实上,究竟是多少要视情况而定,一般20位左右感觉就可以了,虽然说越大越好,但是太大了消耗内存,速度慢了,不值。本题中,我们设置它为一个变量,先暂时取为10来实验,好了,如果还不明白为什么要编码看下面的吧。知道了交叉与变异,你就知道了。

 

5、关于交叉与变异

先说变异,什么是变异?简单,基因发生突变就叫变异,有了编码的概念,那就在编码基础上来说变异。首先就讲最简单的变异,但个点的变异。现在以10位长的编码来说,比如把x=3编码一下,随便假设为11000 10010吧,好了,在变异操作时,假设第5位变异了(说一下变异就是一位或者多位1或0变成0或1,也只能0,1之间变,没办法啊),那么这个时候变成什么了?是不是11001 10010再反编码回去成x是多少呢?那肯定不是3了,变了呀,是多少是肯定可以反算回去的,这里懒得算了,就假设为3.213吧,发没发现,这样一来,x是不是变了?既然变了就好啊,带到原函数(适应度函数)里面比较这两个x值对应的哪个y值大一写,如果后面变异后的大一些是不是就是说产生了好的变异啊,就可以在下一次个体选择的时候选择它了。那么想想很多x来一起变异会怎么样呢?肯定会生成很多很多的解吧,反复这么做会怎么样呢?只要每次都保留最优解的话,我来个循环100万次,也总能找到解吧,当然这么多次得花多久,也不太合适,这还只是一个点位在进行变异,若果每次我让多个点位变异呢?哇,又不可思议了,变化更大了吧。当然,变异不止如此,更多的去看专业的论文吧。知道了变异是干什么的,剩下的都好说了,好了,这还是变异,想想自然界遗传中除了变异还有什么?交叉吧,那么交叉又是什么?

学过生物的都知道,动物交配时,部分染色体干什么了?是不是交叉了?就是把相应

简单的遗传算法,计算函数最值. function ga_main() % 遗传算法程序 % n-- 种群规模% ger-- 迭代次数% pc--- 交叉概率% pm-- 变异概率 % v-- 初始种群(规模为n)% f-- 目标函数值% fit-- 适应度向量 % vx-- 最优适应度值向量% vmfit-- 平均适应度值向量 clear all; close all; clc;%清屏 tic;%计时器开始计时 n=20;ger=100;pc=0.65;pm=0.05;%初始化参数 %以上为经验值,可以更改。 % 生成初始种群 v=init_population(n,22); %得到初始种群,22串长,生成20*22的0-1矩阵 [N,L]=size(v); %得到初始规模行,列 disp(sprintf('Number of generations:%d',ger)); disp(sprintf('Population size:%d',N)); disp(sprintf('Crossover probability:%.3f',pc)); disp(sprintf('Mutation probability:%.3f',pm)); %sprintf可以控制输出格式 % 待优化问题 xmin=0;xmax=9; %变量X范围 f='x+10*sin(x.*5)+7*cos(x.*4)'; % 计算适应度,并画出初始种群图形 x=decode(v(:,1:22),xmin,xmax);"位二进制换成十进制,%冒号表示对所有行进行操作。 fit=eval(f);%eval转化成数值型的 %计算适应度 figure(1);%打开第一个窗口 fplot(f,[xmin,xmax]);%隐函数画图 grid on;hold on; plot(x,fit,'k*');%作图,画初始种群的适应度图像 title('(a)染色体的初始位置');%标题 xlabel('x');ylabel('f(x)');%标记轴 % 迭代前的初始化 vmfit=[];%平均适应度 vx=[]; %最优适应度 it=1; % 迭代计数器 % 开始进化 while it<=ger %迭代次数 0代 %Reproduction(Bi-classist Selection) vtemp=roulette(v,fit);%复制算子 %Crossover v=crossover(vtemp,pc);%交叉算子 %Mutation变异算子 M=rand(N,L)<=pm;%这里的作用找到比0.05小的分量 %M(1,:)=zeros(1,L); v=v-2.*(v.*M)+M;%两个0-1矩阵相乘后M是1的地方V就不变,再乘以2. NICE!!确实好!!!把M中为1的位置上的地方的值变反 %这里是点乘 %变异 %Results x=decode(v(:,1:22),xmin,xmax);%解码,求目标函数值 fit=eval(f); %计算数值 [sol,indb]=max(fit);% 每次迭代中最优目标函数值,包括位置 v(1,:)=v(indb,:); %用最大值代替 fit_mean=mean(fit); % 每次迭代中目标函数值的平均值。mean求均值 vx=[vx sol]; %最优适应度值 vmfit=[vmfit fit_mean];%适应度均值 it=it+1; %迭代次数计数器增加 end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值