基于二进制编码的遗传算法求解函数最大值

本文介绍使用遗传算法寻找特定函数在指定区间内的最大值。通过二进制编码、轮盘赌选择法等策略实现种群进化,最终找到函数最大值约24.86,出现在x=7.86附近。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

求函数 f(x)=x+10sin(5x)+7cos(4x) 的最大值,其中 x 的取值范围是[0,10]

该函数有多个局部极值

f(x)=x+10sin(5x)+7cos(4x)


Matlab遗传算法代码


  • 采用二进制编码
  • 轮盘赌选择法

脚本

初始化参数

clear all;      %清除所有变量
close all;      %清图
clc;            %清屏
NP=50;          %种群数量,一般取10~200,即染色体数目,将定义域划分50个(不等距)
L=20;           %二进制位串长度,即染色体上基因数目,和计算要求的精度有关,如
                %精10^-5,则2^19<10*10^5<2^20,至少需要20位
Pc=0.8;         %交叉率,一般取0.25~1
Pm=0.1;         %变异率,一般取0.001~0.1
G=100;          %最大遗传代数,一般100~1000
Xs=10;          %定义域上限
Xx=0;           %定义域下限
f=randi([0,1],NP,L);  %随机获得初始种群
trace=zeros(1,G);     %预先分配内存

解码

     for i=1:NP
        U=f(i,:);               %一条染色体
        m=0;
        for j=1:L
            m=U(j)*2^(j-1)+m;       %二进制转十进制的过程
        end
        x(i)=Xx+m*(Xs-Xx)/(2^L-1);  %将染色体解码在函数定义域
        Fit(i)=func1(x(i));         %适应度,即目标函数值   
    end

求适应度最优

    maxFit=max(Fit);            %适应度最优
    minFit=min(Fit);            %适应度最差
    rr=find(Fit==maxFit);      
    %最大值在Fit数组中的位置,返回一个数组,因为可能有几个相同的最大值
    %这点要特别注意,所以下面不能直接用rr
    fBest=f(rr(1,1),:);         %最优适应度,有多个相同值时只取第一个
    xBest=x(rr(1,1));           %最优适应度对应的染色体
    Fit=(Fit-minFit)/(maxFit-minFit);   %归一化适应度值

在本代挑选交配的父母染色体

sum_Fit=sum(Fit);
    fitvalue=Fit./sum_Fit;      %可以看作概率密度f
    fitvalue=cumsum(fitvalue);  %可以看作概率累计F
    ms=sort(rand(NP,1));        %随机生成(0,1)的升序概率密度NP向量
    fiti=1;
    newi=1;
    %由ms可以看出这是一种随机的复制方式,但总趋势是将适应度比较大的遗传下去
        while newi <=NP   %父母双方以同样的方式挑选
        if (ms(newi)<fitvalue(fiti))
            nf(newi,:)=f(fiti,:);
            newi=newi+1;
        else
            fiti=fiti+1;
        end
    end

随机交叉

 for i=1:2:NP
        p=rand;
        if p<Pc                     %控制交叉的染色体总数
            q=randi([0,1],1,L);     %随机生成要交叉的基因位置  
            for j=1:L
                if q(j)==1
                    temp=nf(i+1,j);
                    nf(i+1,j)=nf(i,j);
                    nf(i,j)=temp;   %父母染色体在指定位置进行交叉
                end
            end
        end
    end

变异操作

    i=1;
    while i<=round(NP*Pm)       %控制变异染色体总数
        h=randi([1,NP],1,1);    %随机选取一个染色体
        for j=1:round(L*Pm)     %控制染色体上变异基因总数
            g=randi([1,L],1,1); %随机选取一个基因进行变异
            nf(h,g)=~nf(h,g);   %变异,即取反
        end
        i=i+1;
    end

完整代码

%%%%%标准遗传算法求函数极值%%%%
%%%%%初始化参数%%%%%
clear all;      %清除所有变量
close all;      %清图
clc;            %清屏
NP=50;          %种群数量,一般取10~200,即染色体数目,将定义域划分50个(不等距)
L=20;           %二进制位串长度,即染色体上基因数目,和计算要求的精度有关,如
                %精度10^-5,则2^19<10*10^5<2^20,至少需要20Pc=0.8;         %交叉率,一般取0.25~1
Pm=0.1;         %变异率,一般取0.001~0.1
G=100;          %最大遗传代数,一般100~1000
Xs=10;          %定义域上限
Xx=0;           %定义域下限
f=randi([0,1],NP,L);  %随机获得初始种群
trace=zeros(1,G);     %预先分配内存
%%%%%%%%遗传算法循环%%%%%%%%
for k=1:G
  %%%%%%解码%%%%
    for i=1:NP
        U=f(i,:);               %一条染色体
        m=0;
        for j=1:L
            m=U(j)*2^(j-1)+m;       %二进制转十进制的过程
        end
        x(i)=Xx+m*(Xs-Xx)/(2^L-1);  %将染色体解码在函数定义域
        Fit(i)=func1(x(i));         %适应度,即目标函数值   
    end
    %%%%%%求适应度最优%%%%
    maxFit=max(Fit);            %目标函数最大值
    minFit=min(Fit);            %目标函数最小值
    rr=find(Fit==maxFit);      
    %最大值在Fit数组中的位置,返回一个数组,因为可能有几个相同的最大值
    %这点要特别注意,所以下面不能直接用rr
    fBest=f(rr(1,1),:);         %最优适应度,有多个相同值时只取第一个
    xBest=x(rr(1,1));           %最优适应度对应的染色体
    Fit=(Fit-minFit)/(maxFit-minFit);   %归一化适应度值
    %%%%%至此本代最优已筛选出来,下面开始为下一代作准备%%%%
    %%%%%基于轮盘赌的复制操作,在本代挑选出交配的父母双方%%%%
    sum_Fit=sum(Fit);
    fitvalue=Fit./sum_Fit;      %可以看作概率密度f
    fitvalue=cumsum(fitvalue);  %可以看作概率累计F
    ms=sort(rand(NP,1));        %随机生成(0,1)的有序概率密度NP大小向量
    fiti=1;
    newi=1;
    %由ms可以看出这是一种随机的复制方式,但总趋势是将适应度比较大的遗传下去
    while newi <=NP
        if (ms(newi)<fitvalue(fiti))
            nf(newi,:)=f(fiti,:);
            newi=newi+1;
        else
            fiti=fiti+1;
        end
    end
    %%%%%%%%基于概率的交叉操作%%%%%%%%
    for i=1:2:NP
        p=rand;
        if p<Pc                     %控制交叉的染色体总数
            q=randi([0,1],1,L);     %随机生成要交叉的基因位置  
            for j=1:L
                if q(j)==1
                    temp=nf(i+1,j);
                    nf(i+1,j)=nf(i,j);
                    nf(i,j)=temp;   %两条相邻染色体在指定位置进行交叉
                end
            end
        end
    end
    %%%%%%%%%基于概率的变异操作%%%%%%%%%%%%
    i=1;
    while i<=round(NP*Pm)       %控制变异染色体总数
        h=randi([1,NP],1,1);    %随机选取一个染色体进行变异
        for j=1:round(L*Pm)     %控制染色体上变异基因总数
            g=randi([1,L],1,1); %随机选取一个基因进行变异
            nf(h,g)=~nf(h,g);   %变异,即取反
        end
        i=i+1;
    end
    f=nf;                    %新一代种群                   
    f(1,:)=fBest;            %保留最优个体在新种群中
    trace(k)=maxFit;         %历代最优是应当由,即最大函数值
end
disp('最优解');
disp(xBest);                 %最优个体,也就是最优解
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')

函数

function fit=func1(x)
fit=x+10*sin(5*x)+7*cos(4*x);
end

计算结果

函数最大值出现在 x=7.86 附近,约为24.86


这里写图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值