遗传算法及其Matlab实现(二元函数实现)

5. 遗传算法实例

参考文献:
1.《遗传算法原理及应用》
2.https://www.cnblogs.com/LoganChen/p/7509702.html
求下列二元函数的最大值:
image-20200723104502134

运算过程如下:
(1)个体编码

​ 将x1,x2的定义域编码为一种符号串,该例题使用二进制编码。将编码后的x1,x2连接在一起形成个体的基因型

例如:基因型 X = 100 010

​ 其表现型 x = [4,2]
​ 基因型与表现型可通过解码程序与编码程序相互转换。

(2)初始群体产生

​ 本例中,选取初始群体为4,实际使用中应远远大于4。随机产生的群体如下:
image-20200723104939570

(3)适应度计算

​ 适应度大小决定了该个体的优劣程度,从而决定其遗传机会的大小。由于目标函数总是非负数,因此可直接选取目标函数的函数值作为个体的适应值。
对初始群体解码后计算得出:
image-20200723105155489

(4)选择运算

​ 运用了轮盘选择的原理,不懂的可以看我上一篇文章。
​ 选择的具体操作过程如下:
计算出群体中所有个体的适应度总和image-20200723105359691
其次计算出每个个体的相对适应度image-20200723105408298

结果即为该个体遗传到下一代的概率:
image-20200723105451802

由上图可见,全部概率值之和位1.这之后再随机且顺序产生4个0<= x <= 1之间的数,依据该随机数出现的区间来选择个体。

选择结果如下:
image-20200723105646033

(5)交叉运算

首先说明,交叉以及变异全部都是概率事件,他是可能不发生的,实例中为了方便大家理解,使交叉与变异全部发生。

​ 本例的交叉运算使用单点交叉方法。其原理如图:
image-20200723105844593

​ 具体操作过程是:先对群体进行随机配对,其次随机设置交叉点位置,这之后进行交叉运算:
image-20200723110001384

(6)变异运算:
本例中,采用基本位变异的方法,其原理如下:
image-20200723110053336

image-20200723110058807

​ 与交叉运算相同,变异点的选择同样是概率事件,这里为了方便所有个体都进行了变异。随机选择变异点后,变异结果如下:
image-20200723110612051

​ 经过了上面6个步骤后,得到了新的子代群体:
image-20200723110749361

这之后根据我们设置的算法停止条件,例如迭代200次,判断算法是否继续进行,若进行则回到第3步进行循环计算:
image-20200723110854542

否则,输出子代群体中是适应度最大的解码答案。
整个运算过程如下表所示:
image-20200723110945851

6. 基本遗传算法原理解释

​ 根据上述实例,我们对遗传算法的基本运算过程有了简单理解。接下来我们通过Matlab来实现计算机计算。
​ 我们将实例计算的6个过程转换为流程图,如下所示:
image-20200723112225302

计算实例中的函数最大值:
image-20200723104502134

不过此时x1与x2的定义域为[0,10]。
我们选择0.01的精度

精度计算原理如下:

image-20200721120723135

计算结果为:
L1 = 10
L2 = 10
L = L1 + L2 = 20

因此我们可以了解,当二进制位数为10的时候,可以满足我们要求的0.01的精度。

解释:我们所谓的编码过程其实是计算长度的过程,我们不需要将定义域的十进制数转换为二进制数进行计算,只需要获得个体的总长度就行,因为遗传算法在计算过程中是利用个体基因进行计算的。

当我们得到二进制长度后,就需要一个方法将二进制数转换为十进制数,解码方法就来了,原理如下:

image-20200721120923540

x1 = 10*X/(2^L - 1);

x2 = 10*X/(2^L - 1);

这里的X理解为二进制数转换为十进制数之后的数值(理解:此时X的十进制数与我们所求的十进制数不同)。

7.Matlab代码实现

代码中将会用的名词及其解释:

名词解释
chromlength二进制编码长度
popsize种群大小
pc交叉概率
pm变异概率
pop种群
fitvalue适应度值
bestindividual最优个体
bestfit最佳适应度值

代码中将会用到的文件名及其功能:

文件名功能
main.m遗传算法框架
initpop.m二进制种群生成
cal_objvalue.m适应度计算
selection.m选择
crossover.m交叉
mutation.m变异
best.m求最优解
binary2decimal.m二进制转十进制

(1)main.m:

function main()
clear;
clc;
%种群大小
popsize=500;
%二进制编码长度,这里填计算出来的L值
chromlength=20;
%交叉概率
pc = 0.6;
%变异概率
pm = 0.05;
%初始种群
pop = initpop(popsize,chromlength);

for i = 1:1000
    %计算适应度值(函数值)
    objvalue = cal_objvalue(pop);
    fitvalue = objvalue;
    %选择操作
    newpop = selection(pop,fitvalue);
    %交叉操作
    newpop = crossover(newpop,pc);
    %变异操作
    newpop = mutation(newpop,pm);
    %更新种群
    pop = newpop;
    %寻找最优解
    [bestindividual,bestfit] = best(pop,fitvalue);
    bsi1 = bestindividual( :, 1:1:chromlength/2);
    bsi2 = bestindividual( :, chromlength/2 + 1:1:end);
    popA = newpop( :, end:-1:chromlength/2 + 1);
    popB = newpop( :, chromlength/2:-1:1);
    x1 = binary2decimal(popA);
    x2 = binary2decimal(popB);
    %转化二进制数为x变量的变化域范围的数值
    y1=x1.^2 + x2.^2;
    x1 = binary2decimal(bsi1);
    x2 = binary2decimal(bsi2);
    y1=x1.^2 + x2.^2;
    if mod(i,200) == 0
    figure;
    o1 = 0:0.5:10;
    o2 = o1;
    [O1,O2] = meshgrid(o1);
    k = O1.^2 + O2.^2;
    surf(o1,o2,k)
    hold on;
    title(['迭代次数为n=' num2str(i)]);
    %plot(x1,y1,'*');
    end
    plot3(x1,x2,y1,'*');
end
fprintf('The best X1、X2 is --->>%5.2f\n >>%5.2f\n',x1,x2);
fprintf('The best Y is --->>%5.2f\n',bestfit);

(2)initpop.m

%初始化种群大小
%输入变量:
%popsize:种群大小
%chromlength:染色体长度-->>转化的二进制长度
%输出变量:
%pop:种群
function pop=initpop(popsize,chromlength)
pop = round(rand(popsize,chromlength));
%rand(5,5)生成5行5列的0-1之间的随机数
% rand(5,5)
% 
%ans =
%
%   0.8147    0.0975    0.1576    0.1419    0.6557
%    0.9058    0.2785    0.9706    0.4218    0.0357
%    0.1270    0.5469    0.9572    0.9157    0.8491
%    0.9134    0.9575    0.4854    0.7922    0.9340
%    0.6324    0.9649    0.8003    0.9595    0.6787
%round就是四舍五入
% round(ans)=
%ans =
%     1     0     0     0     1
%     1     0     1     0     0
%     0     1     1     1     1
%     1     1     0     1     1
%     1     1     1     1     1
%所以返回的种群就是每行是一个个体,列数是染色体长度

(3)binary2decimal.m

%二进制转化成十进制函数
%输入变量:
%二进制种群
%输出变量
%十进制数值
function pop2 = binary2decimal(pop)
[px,py]=size(pop);
for i = 1:py
    pop1(:,i) = 2.^(py-i).*pop(:,i);
end
%sum(.,2)对行求和,得到列向量
temp = sum(pop1,2);
pop2 = temp*10/1023;

(4)cal_objvalue.m

%计算函数目标值
%输入变量:二进制数值
%输出变量:目标函数值
function [objvalue] = cal_objvalue(pop)
x = binary2decimal(pop);
%转化二进制数为x变量的变化域范围的数值
objvalue=10*sin(5*x)+7*abs(x-5)+10;

(5)selection.m

%如何选择新的个体
%输入变量:pop二进制种群,fitvalue:适应度值
%输出变量:newpop选择以后的二进制种群
function [newpop] = selection(pop,fitvalue)
%构造轮盘
[px,py] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
p_fitvalue = cumsum(p_fitvalue);%概率求和排序
ms = sort(rand(px,1));%从小到大排列
fitin = 1;
newin = 1;
while newin<=px
    if(ms(newin))<p_fitvalue(fitin)
        newpop(newin,:)=pop(fitin,:);
        newin = newin+1;
    else
        fitin=fitin+1;
    end
end

(6)crossover.m

%交叉变换
%输入变量:pop:二进制的父代种群数,pc:交叉的概率
%输出变量:newpop:交叉后的种群数
function [newpop] = crossover(pop,pc)
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:2:px-1
    if(rand<pc)
        cpoint = round(rand*py);
        newpop(i,:) = [pop(i,1:cpoint),pop(i+1,cpoint+1:py)];
        newpop(i+1,:) = [pop(i+1,1:cpoint),pop(i,cpoint+1:py)];
    else
        newpop(i,:) = pop(i,:);
        newpop(i+1,:) = pop(i+1,:);
    end
end

(7)mutation.m

%关于编译
%函数说明
%输入变量:pop:二进制种群,pm:变异概率
%输出变量:newpop变异以后的种群
function [newpop] = mutation(pop,pm)
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:px
    if(rand<pm)
        mpoint = round(rand*py);
        if mpoint <= 0;
            mpoint = 1;
        end
        newpop(i,:) = pop(i,:);
        if newpop(i,mpoint) == 0
            newpop(i,mpoint) = 1;
        else newpop(i,mpoint) == 1
            newpop(i,mpoint) = 0;
        end
    else newpop(i,:) = pop(i,:);
    end
end

(8)best.m

%求最优适应度函数
%输入变量:pop:种群,fitvalue:种群适应度
%输出变量:bestindividual:最佳个体,bestfit:最佳适应度值
function [bestindividual bestfit] = best(pop,fitvalue)
[px,py] = size(pop);
bestindividual = pop(1,:);
bestfit = fitvalue(1);
for i = 2:px
    if fitvalue(i)>bestfit
        bestindividual = pop(i,:);
        bestfit = fitvalue(i);
    end
end
  • 8
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
二元函数遗传算法(Binary Function Genetic Algorithm)是一种基于自然选择和遗传变异的优化算法。它通过模拟进化过程,搜索并找到二元函数的最优解。 该算法实现可以使用MATLAB编程语言,下面简要介绍其步骤: 1. 初始化种群:随机生成一组个体(即二元编码),个体数量根据问题的复杂程度决定。 2. 评估适应度:将每个个体的二进制编码转化为对应的十进制值,并计算函数的目标值作为个体的适应度。 3. 选择操作:按照适应度值选择一些个体作为繁殖池,较好的个体有更高的概率被选中,以保持种群的优良特性。 4. 交叉操作:从繁殖池中选择两个个体进行交叉操作,即将它们的二进制编码按照一定规则进行交换,生成两个新的个体。 5. 变异操作:以一定的概率对新生成的个体进行变异。变异操作是为了增加种群的多样性,防止算法陷入局部最优。 6. 更新种群:根据选择、交叉和变异操作生成的新个体,更新当前种群。 7. 判断停止条件:通过迭代判断是否满足停止条件,如达到最大迭代次数或目标函数值满足要求等。 8. 输出结果:输出最优解的十进制值及对应的函数值,即为问题的最优解。 MATLAB提供了丰富的工具和函数,如随机数生成函数、矩阵操作函数等,可用于实现二元函数遗传算法的各个步骤。通过编写合适的代码,调用这些函数和工具,即可完成对二元函数的优化求解。 总之,二元函数遗传算法是一种应用广泛且有效的优化算法,通过模拟自然进化过程来寻找函数的最优解。在MATLAB中,可以使用各种工具和函数实现算法,从而解决各种二元函数优化问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值