赞
踩
遗传算法(Genetic Algorithm,GA)关键是把问题参数编码成染色体,再利用迭代方式进行选择、交叉、变异等运算交换种群中的染色体信息,根据适应度的好坏选择一定数量优秀的染色体,经过若干代的进化后,最终收敛于最好的符合优化目标染色体。
特点:
术语:
步骤:
参数:
改进:

Genetic Algorithm and Direct Search Toolbox,GADST
命令行输入:
optimtool('ga')
注意:GADST是对目标函数去最小值进行优化,若要最大值优化,将适应度函数*-1


![]()
1.初始化种群:实数编码:不必进行数值转换,可以直接在解的表现型上进行遗传算法操作
- function ret=Code(lenchrom, bound)
- % lenchrom input : 染色体长度
- % bound input : 变量的取值范围
- % ret output: 染色体的编码值
-
- flag=0;
-
- while flag==0
- pick=rand(1,length(lenchrom));
- ret=bound(:,1)'+(bound(:,2)-bound(:,1))'.*pick; % 线性插值
- flag=test(lenchrom,bound,ret); % 检验染色体的可行性
- end
2.适应度函数:求函数最小值,将函数值的倒数作为个体的适应度值,即函数值越小的个体越优
- function y = fun(x)
- y=-5*sin(x(1))*sin(x(2))*sin(x(3))*sin(x(4))*sin(x(5))-sin(5*x(1))*sin(5*x(2))*sin(5*x(3))*sin(5*x(4))*sin(5*x(5))+8;
3.选择操作:轮盘赌:基于适应度比例的选择策略

- function ret=Select(individuals,sizepop)
- % individuals input : 种群信息
- % sizepop input : 种群规模
- % opts input : 选择方法的选择
- % ret output : 经过选择后的种群
-
- individuals.fitness= 1./(individuals.fitness);
- sumfitness=sum(individuals.fitness);
- sumf=individuals.fitness./sumfitness;
- index=[];
- for i=1:sizepop % 转sizepop次轮盘
- pick=rand;
- while pick==0
- pick=rand;
- end
- for j=1:sizepop
- pick=pick-sumf(j);
- if pick<0
- index=[index j];
- break; % 寻找落入的区间,此次转轮盘选中了染色体i,注意:在转sizepop次轮盘的过程中,有可能会重复选择某些染色体
- end
- end
- end
- individuals.chrom=individuals.chrom(index,:);
- individuals.fitness=individuals.fitness(index);
- ret=individuals;

4.交叉操作:实数交叉

- function ret=Cross(pcross, lenchrom, chrom, sizepop, bound)
- % pcorss input : 交叉概率
- % lenchrom input : 染色体的长度
- % chrom input : 染色体群
- % sizepop input : 种群规模
- % ret output : 交叉后的染色体
-
- for i=1:sizepop
- % 随机选择两个染色体进行交叉
- pick=rand(1,2);
- while prod(pick)==0
- pick=rand(1,2);
- end
- index=ceil(pick.*sizepop);
- % 交叉概率决定是否进行交叉
- pick=rand;
- while pick==0
- pick=rand;
- end
- if pick>pcross
- continue;
- end
- flag=0;
- while flag==0
- % 随机选择交叉位置
- pick=rand;
- while pick==0
- pick=rand;
- end
- % 随机选择进行交叉的位置,即选择第几个变量进行交叉,注意:两个染色体交叉的位置相同
- pos=ceil(pick.*sum(lenchrom));
- pick=rand; % 交叉开始
- v1=chrom(index(1),pos);
- v2=chrom(index(2),pos);
- chrom(index(1),pos)=pick*v2+(1-pick)*v1;
- chrom(index(2),pos)=pick*v1+(1-pick)*v2; % 交叉结束
- flag1=test(lenchrom,bound,chrom(index(1),:)); % 检验染色体1的可行性
- flag2=test(lenchrom,bound,chrom(index(2),:)); % 检验染色体2的可行性
- if flag1*flag2==0
- flag=0;
- else flag=1;
- end % 如果两个染色体不是都可行,则重新交叉
- end
- end
-
- ret=chrom;

5.变异操作

- function ret=Mutation(pmutation, lenchrom, chrom, sizepop, pop, bound)
- % pcorss input : 变异概率
- % lenchrom input : 染色体长度
- % chrom input : 染色体群
- % sizepop input : 种群规模
- % pop input : 当前种群的进化代数和最大的进化代数信息
- % ret output : 变异后的染色体
-
- for i=1:sizepop
- % 随机选择一个染色体进行变异
- pick=rand;
- while pick==0
- pick=rand;
- end
- index=ceil(pick*sizepop);
- % 变异概率决定该轮循环是否进行变异
- pick=rand;
- if pick>pmutation
- continue;
- end
- flag=0;
- while flag==0
- % 变异位置
- pick=rand;
- while pick==0
- pick=rand;
- end
- % 随机选择了染色体变异的位置,即选择了第pos个变量进行变异
- pos=ceil(pick*sum(lenchrom));
- v=chrom(i,pos);
- v1=v-bound(pos,1);
- v2=bound(pos,2)-v;
- pick=rand; % 变异开始
- if pick>0.5
- delta=v2*(1-pick^((1-pop(1)/pop(2))^2));
- chrom(i,pos)=v+delta;
- else
- delta=v1*(1-pick^((1-pop(1)/pop(2))^2));
- chrom(i,pos)=v-delta;
- end % 变异结束
- flag=test(lenchrom,bound,chrom(i,:)); % 检验染色体的可行性
- end
- end
-
- ret=chrom;

6.收敛寻优
基本GA寻优
- %% 清空环境
- clc
- clear
-
- %% 遗传算法参数
- maxgen=30; % 进化代数
- sizepop=100; % 种群规模
- pcross=[0.6]; % 交叉概率
- pmutation=[0.01]; % 变异概率
- lenchrom=[1 1 1 1 1]; % 变量字串长度
- bound=[0 0.9*pi;0 0.9*pi;0 0.9*pi;0 0.9*pi;0 0.9*pi]; % 变量范围
-
- %% 个体初始化
- individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]); % 种群结构体
- avgfitness=[]; % 种群平均适应度
- bestfitness=[]; % 种群最佳适应度
- bestchrom=[]; % 适应度最好染色体
- % 初始化种群
- for i=1:sizepop
- individuals.chrom(i,:)=Code(lenchrom,bound); % 随机产生个体
- x=individuals.chrom(i,:);
- individuals.fitness(i)=fun(x); % 个体适应度
- end
-
- % 找最好的染色体
- [bestfitness bestindex]=min(individuals.fitness);
- bestchrom=individuals.chrom(bestindex,:); % 最好的染色体
- avgfitness=sum(individuals.fitness)/sizepop; % 染色体的平均适应度
- % 记录每一代进化中最好的适应度和平均适应度
- trace=[];
-
- %% 进化开始
- for i=1:maxgen
- % 选择操作
- individuals=Select(individuals,sizepop);
- avgfitness=sum(individuals.fitness)/sizepop;
- % 交叉操作
- individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
- % 变异操作
- individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,[i maxgen],bound);
-
- % 计算适应度
- for j=1:sizepop
- x=individuals.chrom(j,:);
- individuals.fitness(j)=fun(x);
- end
-
- % 找到最小和最大适应度的染色体及它们在种群中的位置
- [newbestfitness,newbestindex]=min(individuals.fitness);
- [worestfitness,worestindex]=max(individuals.fitness);
- % 代替上一次进化中最好的染色体
- if bestfitness>newbestfitness
- bestfitness=newbestfitness;
- bestchrom=individuals.chrom(newbestindex,:);
- end
- individuals.chrom(worestindex,:)=bestchrom;
- individuals.fitness(worestindex)=bestfitness;
-
- avgfitness=sum(individuals.fitness)/sizepop;
- % 记录每一代进化中最好的适应度和平均适应度
- trace=[trace;avgfitness bestfitness];
- end %进化结束
-
-
- %% 结果显示
- [r c]=size(trace);
- figure
- plot([1:r]',trace(:,1),'r-',[1:r]',trace(:,2),'b--');
- title(['函数值曲线 ' '终止代数=' num2str(maxgen)],'fontsize',12);
- xlabel('进化代数','fontsize',12);ylabel('函数值','fontsize',12);
- legend('各代平均值','各代最佳值');
- disp('函数值 变量');
- ylim([1.5 8])
- %xlim([1,size(trace,1)])
- grid on
- % 窗口显示
- disp([bestfitness x]);

工具箱fmincon函数优化
- function ret = nonlinear(chrom,sizepop)
-
- for i=1:sizepop
- x=fmincon(inline('-5*sin(x(1))*sin(x(2))*sin(x(3))*sin(x(4))*sin(x(5))-sin(5*x(1))*sin(5*x(2))*sin(5*x(3))*sin(5*x(4))*sin(5*x(5))'),chrom(i,:)',[],[],[],[],[0 0 0 0 0],[2.8274 2.8274 2.8274 2.8274 2.8274]);
- ret(i,:)=x';
- end
- %% 清空环境
- clc
- clear
- warning off
-
- %% 遗传算法参数
- maxgen=30; % 进化代数
- sizepop=100; % 种群规模
- pcross=[0.6]; % 交叉概率
- pmutation=[0.01]; % 变异概率
- lenchrom=[1 1 1 1 1]; % 变量字串长度
- bound=[0 0.9*pi;0 0.9*pi;0 0.9*pi;0 0.9*pi;0 0.9*pi]; %变量范围
-
- %% 个体初始化
- individuals=struct('fitness',zeros(1,sizepop), 'chrom',[]); % 种群结构体
- avgfitness=[]; % 种群平均适应度
- bestfitness=[]; % 种群最佳适应度
- bestchrom=[]; % 适应度最好染色体
- % 初始化种群
- for i=1:sizepop
- individuals.chrom(i,:)=Code(lenchrom,bound); % 随机产生个体
- x=individuals.chrom(i,:);
- individuals.fitness(i)=fun(x); % 个体适应度
- end
-
- %找最好的染色体
- [bestfitness bestindex]=min(individuals.fitness);
- bestchrom=individuals.chrom(bestindex,:); % 最好的染色体
- avgfitness=sum(individuals.fitness)/sizepop; % 染色体的平均适应度
- % 记录每一代进化中最好的适应度和平均适应度
- trace=[];
-
- %% 进化开始
- for i=1:maxgen
-
- % 选择操作
- individuals=Select(individuals,sizepop);
- avgfitness=sum(individuals.fitness)/sizepop;
- % 交叉操作
- individuals.chrom=Cross(pcross,lenchrom,individuals.chrom,sizepop,bound);
- % 变异操作
- individuals.chrom=Mutation(pmutation,lenchrom,individuals.chrom,sizepop,[i maxgen],bound);
-
- if mod(i,10)==0
- individuals.chrom=nonlinear(individuals.chrom,sizepop);
- end
-
- % 计算适应度
- for j=1:sizepop
- x=individuals.chrom(j,:);
- individuals.fitness(j)=fun(x);
- end
-
- % 找到最小和最大适应度的染色体及它们在种群中的位置
- [newbestfitness,newbestindex]=min(individuals.fitness);
- [worestfitness,worestindex]=max(individuals.fitness);
- % 代替上一次进化中最好的染色体
- if bestfitness>newbestfitness
- bestfitness=newbestfitness;
- bestchrom=individuals.chrom(newbestindex,:);
- end
- individuals.chrom(worestindex,:)=bestchrom;
- individuals.fitness(worestindex)=bestfitness;
-
- avgfitness=sum(individuals.fitness)/sizepop;
- % 记录每一代进化中最好的适应度和平均适应度
- trace=[trace;avgfitness bestfitness];
- end % 进化结束
-
- %% 结果显示
- figure
- [r c]=size(trace);
- plot([1:r]',trace(:,1),'r-',[1:r]',trace(:,2),'b--');
- title(['函数值曲线 ' '终止代数=' num2str(maxgen)],'fontsize',12);
- xlabel('进化代数','fontsize',12);ylabel('函数值','fontsize',12);
- legend('各代平均值','各代最佳值','fontsize',12);
- ylim([1.5 8])
- disp('函数值 变量');
- % 窗口显示
- disp([bestfitness x]);
- grid on

7.结果
基本GA优化迭代到第30次函数值收敛于2,工具箱优化迭代到第10次函数值收敛于2

TSP:从一个城市出发,访问每个城市且只去一次,最后回到出发城市,使路径最短(一条遍历n个城市的最短曼哈顿回路)
| 城市编号 | X坐标 | Y坐标 | 城市编号 | X坐标 | Y坐标 |
| 1 | 16.47 | 96.1 | 8 | 17.2 | 96.29 |
| 2 | 16.47 | 94.44 | 9 | 16.3 | 9 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。