实值遗传算法求解函数极值问题(基于MATLAB)

实值遗传算法求解函数极值问题(基于MATLAB)

声明:

1.本文源代码来自书目《智能优化算法及其MATLAB实例(第3版)》,目的在于为MATLAB初学者提供更简明的代码解析,方便读者了解算法及MATLAB编程基本原理。

2.文中代码每一行后都有相应注释,因此本文是一篇适合所有代码水平的学习者阅读的文章。

在例2.1中我们采用的是标准遗传算法,即采用二进制来进行基因编码。而另一种常用的编码方式为实值编码,即每个基因位不再是0或1,变成了一个实数。本文就是讨论在这样的编码机制下,利用MATLAB编程求解函数的极值问题。
补充知识:”君主法“选择交叉方式
在定义适应度函数后,对种群按适应度值升序排列,选取最优个体作为君主染色体,并按照排列后的顺序选取偶数位的染色体依次与君主染色体交叉,完成交叉过程。将得到的子代与父代合并后,再次按适应度值排序后取前NP个染色体作为下一次循环的种群,这就完成了选择过程。

例2.2 计算函数f(x)=x12+x22+···xn2(-20<=xi<=20)的最小值,其中个体x的维数n=10。这是一个简单的平方和函数,只有一个极小点在0处取得为0。

基于实值遗传算法的MATLAB求解代码如下:

%%%%%实值遗传算法求解求和函数极值问题%%%%%%%%
%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%
clear all;             %清除所有变量
close all;             %清图
clc;                   %清屏
D=10;                  %单条染色体上基因数目为10
NP=100;                %染色体数目,即种群规模或取样样本数目
Xs=20;                 %上限
Xx=-20;                %下限
G=1000;                %最大遗传代数
f=zeros(D,NP);         %创建并初始化初始种群二维数组
nf=zeros(D,NP);        %创建并初始化子代种群二维数组由于我们选择和交叉采用君主方案,所以每代数目都为NP
Pc=0.8;                %交叉概率
Pm=0.1;                %变异概率
f=rand(D,NP)*(Xs-Xx)+Xx;%随机生成初始种群,rand(A,B)表示生成A行B列【0,1】随机小数矩阵
%%%%%%%%%%%%按适应度升序排列%%%%%%%%%%%%%%%%
for np=1:NP            %对于初始种群中的每条染色体
    FIT(np)=func2(f(:,np));%定义第np个体的适应度函数,以第np个个体的染色体基因序列数组为自变量
end
[SortFIT,Index]=sort(FIT);%按照升序对适应度函数值排序,
                          %返回的SortFIT是排序好的适应度函数值数组,
                          %返回Index是新数组中元素对应原索引值数组。
Sortf=f(:,Index);         %sortf为排序好的种群矩阵
%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%
for gen=1:G
    %%%%%%%采用君主方案进行选择和交叉操作%%%%%%%%%%%%%%
    Emper=Sortf(:,1);     %选出君主染色体数组(由于最终求的是最小值,故适应度最低的是最优个体)
    NoPoint=round(D*Pc);  %每次交叉点的个数,round为四舍五入取整
    PoPoint=randi([1,D],NoPoint,NP/2);%随机生成发生交叉的偶数染色体上发生交叉基因的位置矩阵
    nf=Sortf;
    for i=1:NP/2          %进行交叉
        nf(:,2*i-1)=Emper;%在排序好的种群中把所有奇数位(不参与交叉的那些)替换为君主染色体
        nf(:,2*i)=Sortf(:,2*i);
        for k=1:NoPoint 
            nf(PoPoint(k,i),2*i-1)=nf(PoPoint(k,i),2*i);%奇数位和偶数位染色体在前面求得的交叉位置发生交叉     
            nf(PoPoint(k,i),2*i)=Emper(PoPoint(k,i));
        end
    end
   %%%%%%%%变异操作%%%%%%%%%%%%%
    for m=1:NP          %对种群中每一个个体
        for n=1:D       %对第m个个体的第n个基因位
            r=rand(1,1);%生成一个【0,1】随机数
            if r<Pm
                nf(n,m)=rand(1,1)*(Xs-Xx)+Xx;%若满足变异条件,则随机生成题述范围内的实值替换相应位置完成变异
            end
        end
    end
    %%%%%%%子种群按适应度升序排列%%%%%%%%%
    for np=1:NP         %模仿对初始种群操作即可
        NFIT(np)=func2(nf(:,np));
    end
    [NSortFIT,Index]=sort(NFIT);
    NSortf=nf(:,Index);
    %%%%%%产生新种群%%%%%%%%%%%%%%%%%%%%%%
    f1=[Sortf,NSortf];  %先对父代和子代进行合并
    FIT1=[SortFIT,NSortFIT];%对父代和子代的适应度值合并
    [SortFIT1,Index]=sort(FIT1);%对新的适应度函数值数组进行升序排列
    Sortf1=f1(:,Index);      %按适应度排列个体
    SortFIT=SortFIT1(1:NP); %排序后取前NP个个体构成下一次循环种群适应度值数组
    Sortf=Sortf1(:,1:NP);   %下一次循环种群矩阵
    trace(gen)=SortFIT(1);  %记录历代最优适应度值
end
Bestf=Sortf(:,1)            %输出最优个体基因序列数组,即取最小值时的【xi】取值
disp(['最终得到最优个体适应度值,即函数最小值为:']);
trace(end)                 %命令行中输出函数最小值(想要把值输出来就不要加分号)
figure                      %画出适应度进化曲线
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%适应度进化函数%%%%%%%%%%%%%
function result=func2(x)
summ=sum(x.^2);%以目标函数作为适应度函数
result=summ;
end

最终运行结果如下所示:
在这里插入图片描述

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值