遗传算法 简单函数优化

%f(x)=11sin(6x)+7cons(5x),0<=x<=2*pi
%注意程序中num2gray函数和gray2num函数可以参照我上面的另外两个博文中有代码

%%初始化参数
L=16; %编码为16位二进制数
N=32; %初始种群规模
M=48; %M个中间体,运用算子选择出M/2对母体,进行交叉;对M个中间体进行变异
T=100; %进化代数
Pc=0.8; %交叉概率
Pm=0.03; %变异概率
%%将十进制编码成16位的二进制,再将16位的二进制转成格雷码
for i=1:1:N
   x1(1,i)=rand()*2*pi;
   x2(1,i)=uint16(x1(1,i)/(2*pi)*65535);
   grayCode(i,:)=num2gray(x2(1,i),L);
end
%% 开始遗传算子操作
for t=1:1:T
   y1=11*sin(6*x1)+7*cos(5*x1)
    fori=1:1:M/2
       [a,b]=min(y1) ;%找到y1中的最小值a,及其对应的编号b
       grayCodeNew(i,:)=grayCode(b,:);%将找到的最小数放到grayCodeNew中
       grayCodeNew(i+M/2,:)=grayCode(b,:);%与上面相同就可以有M/2对格雷码可以作为母体
       y1(1,b)=inf;%用来排除已找到的最小值
    end
    fori=1:1:M/2
       p=unidrnd(L);%生成一个大于零小于L的数,用于下面进行交叉的位置
       if rand()<Pc % Pc是交叉概率
           %将选定的染色体的点后的基因进行交换
           for j=p:1:L
               temp=grayCodeNew(i,j);
               grayCodeNew(i,j)=grayCodeNew(M-i+1,j);
               grayCodeNew(M-i+1,j)=temp;
           end
       end
    end
   %%将全部染色体按概率进行变异
    fori=1:1:M
       for j=1:1:L
           if rand()<Pm %Pm为染色体变异的概率
               grayCodeNew(i,j)=dec2bin(1-bin2dec(grayCodeNew(i,j)));
           end
       end
    end
   %%第一代结束后生成的较优的染色体,得以保存然后进行下一代操作
    fori=1:1:M
       x4(1,i)=gray2num(grayCodeNew(i,:));
    end
   x3=double(x4)*2*pi/65535;
   y3=11*sin(6*x3)+7*cos(5*x3);
    fori=1:1:N
       [a,b]=min(y3);
       x1(1,i)=x3(1,b);
       grayCode(i,:)=grayCodeNew(b,:);
       y3(1:b)=inf;
    end
end
x1
y1=11*sin(6*x1)+7*cos(5*x1)

遗传算法基本步骤


 步1 :在论域空间U上定义一个适应度函数f(x),给定种群规模N,交叉率Pc,
 

                变异率Pm,代数Gen
步2: 随机产生U中的N个染色体s1,s2…sN,  组成初始种群S={s1,s2…sN},置代
                  数t=1
步3:若终止条件满足,则取S中适应度最大的染色体作为所求结果,算法结束
步4:计算S中每个染色体的适应度f()
步5: 按选择概率p(si)所决定的选中机会,每次从S中随机选中1个染色体并将
                  其复制,共做N次,然后将复制得到的N染色体组成群体S1
步6 :按Pc所决定的参加交叉的染色体数c,从S1中随机确定c个染色体,配对
                    进行交叉操作,并用产生的染色体代替原染色体,组成群体S2
步7 :按Pm所决定的变异次数m,从S2中随机确定m个染色体,分别进行变异
                    操作,并用产生的新染色体代替原染色体,组成群体S3
步8 :将群体S3作为新种群,即用S3代替S, Gen = Gen +1,转步3

讨论遗传算法中一些初始化参数的设定方法及其影响:

(1)编码长度L。使用二进制编码时,L通常由对问题的求解精度决定,编码长度L越长,可期望的最优解的精度也就越高,但应注意过大的L会增大运算量。

(2)种群规模N。种群规模N表示每一代种群中所含个体数目。当N取之较小时,可提高遗传算法的运算速度,但却降低种群的多样性,容易引起算法早熟,出现假收敛;而N取值较大时,又会使得遗传算法效率降低。一般建议的取值范围是20~100.

(3)交叉概率Pc。在遗传算法中交叉算子被认为是主要搜索算子,因而一般取较大值。一般说,较大的Pc容易破坏群体中已经形成的优良模式,使得搜索的随机性太大了,而较小的Pc使发现新个体(特别是优良个体)的速度太慢了。一般建议的取值范围是0.4~0.99.另外,比较理想的方式是非一致地使用交叉概率,例如在遗传算法的前期使用较大的Pc,后期降低Pc以保留优良个体。

(4)变异概率Pm。较大的变异概率Pm使得遗传算法在整个搜索空间中大部跳跃,而小的变异概率使得遗传算法聚焦在特别区域作局部搜索。一般在不使用交叉算子的情形(演化策略算法,进化程序算法),变异算子作主要搜索算子,Pm取较大值(0.4~1);而在于交叉算子联合使用的情形(遗传算法),Pm通常取较小值(0.0001~0.5).

(5)终止进化代数T。遗传算法不同于传统优化算法,它很难有明确的搜索终止规则(特别是对于非数值优化问题),于是通常需指定一个终止进化代数赖终止算法,一般设T属于【100,1000】。一般来说,事先指定T通常只能找到给定时间的在给定搜索时限内所能寻求的先对满意解,但不一定是问题的最优解或较高精度的近似解。为了获得较高精度解,通常可以根据种群适应度的稳定情况来实时调整T的设置。

    总体来说,以上参数的确定并没有明确的准则可依据,需要根据实际问题的特点以及算法的运行情况来进行实时调整,以搜索获得更为满意的最优解。



基本原理:

遗传算法是一种典型的启发式算法,属于非数值算法范畴。它是模拟达尔文的自然选择学说和自然界的生物进化过程的一种计算模型。它是采用简单的编码技术来表示各种复杂的结构,并通过对一组编码表示进行简单的遗传操作和优胜劣汰的自然选择来指导学习和确定搜索的方向。遗传算法的操作对象是一群二进制串(称为染色体、个体),即种群,每一个染色体都对应问题的一个解。从初始种群出发,采用基于适应度函数的选择策略在当前种群中选择个体,使用杂交和变异来产生下一代种群。如此模仿生命的进化进行不断演化,直到满足期望的终止条件。

运算流程:

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以及MathWorks公司推出的GADS。实际上,GADS就是大家所看到的Matlab中自带的工具箱。我在网上看到有问为什么遗传算法函数不能调用的问题,其实,主要就是因为用的工具箱不同。因为,有些人用的是GATBX带有的函数,但MATLAB自带的遗传算法工具箱是GADS,GADS当然没有GATBX里的函数,因此运行程序时会报错,当你用MATLAB来编写遗传算法代码时,要根据你所安装的工具箱来编写代码。

以GATBX为例,运用GATBX时,要将GATBX解压到Matlab下的toolbox文件夹里,同时,setpath将GATBX文件夹加入到路径当中。

例子:

这块内容主要包括两方面工作:1、将模型用程序写出来(.M文件),即目标函数,若目标函数非负,即可直接将目标函数作为适应度函数。2、设置遗传算法的运行参数。包括:种群规模、变量个数、区域描述器、交叉概率、变异概率以及遗传运算的终止进化代数等等。

求解模型: f(x)=x*sin(10*pi*x)+2.0,x的范围在【-1,2】

根据上面的求解模型,可以写出模型的.M文件如下,即适应度函数

function z=shang(x)
z=x.*sin(10*pi*x)+2.0;

然后写入遗传算法的参数:

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=shang(variable); %计算目标函数值
while genFitnV=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=shang(variable); %计算子代的目标函数值
[Chrom ObjV]=reins(Chrom, SelCh, 1, 1, ObjV, ObjVSel);%重插入子代的新种群
variable=bs2rv(Chrom, FieldD);
gen=gen+1; %代计数器增加
%输出最优解及其序号,并在目标函数图像中标出,Y为最优解,I为种群的序号
[Y, I]=max(ObjV);hold on;
plot(variable(I), Y, 'bo');
trace(1, gen)=max(ObjV); %遗传算法性能跟踪
trace(2, gen)=sum(ObjV)/length(ObjV);
end
variable=bs2rv(Chrom, FieldD); %最优个体的十进制转换
hold on, grid;
plot(variable,ObjV,'b*');
figure(2);
plot(trace(1,:));
hold on;
plot(trace(2,:),'-.');grid
legend('解的变化','种群均值的变化')


你可能感兴趣的:(遗传算法 简单函数优化)