遗传算法代码超通俗解释(MATLAB)

这段代码展示了一个使用遗传算法求解函数极大值的MATLAB实现。通过初始化参数,如种群大小、迭代次数、交叉和变异概率,以及二进制串长度,算法随机生成初始个体并计算目标函数值。在每一代中,依据适应度(目标函数值)进行复制、交叉和变异操作,以逼近最优解。最终,算法找到使得目标函数达到最大值的x和y坐标,这里是x=10,y=20。

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

 题目:gif.latex?z%3Dx%5E3+%282*y-x%29%5E4%3B%20x%5Cin%20%5B10%2C20%5D%3By%5Cin%20%5B10%2C20%5D%3B利用遗传算法求函数极大值;

clc;clear;
%初始参数
N=100;%初始的随机自变量个数
G=100;%总的迭代次数,
Pc=0.6;%确定交叉的可能性即确定每一组xy被交叉改变的可能性
Pm=0.015;%确定变异的可能性即确实每一组xy被变异改变的可能性
n=10;%二进制串的长度,自己设置,太短随机生成的自变量则被局限了
%f=x^3+(2*y-x)^4;%目标函数,f(x,y)调用
x_min=10;x_max=20;%题目对x与y的约束
y_min=10;y_max=20;
E=round(rand(N,2*n));%随机生成100组x,y自变量,一行为一组
%time(1,G)=0;F(1,N)=0;Best_Fit(1,G)=0;temp_E(N,2*n)=0;%内存预分配
for k =1:G
    time(k)=k;
    x=zeros(1,N);%前面随机生成了100组,那么就有100个x与100个y
    y=zeros(1,N);%这两是内存预分配
    %接下来计算每一组x与y的目标函数值
    for i=1:N
        x=x_min+(er(E(i,1:n))/(2^n-1))*(x_max-x_min);%限制x在其范围内
        y=y_min+(er(E(i,n+1:end))/(2^n-1))*(y_max-y_min);%同上
        F(i)=f(x,y);%计算每一组的目标函数值保存到F
    end
    Best_F=max(F);%找到其中最大的,题目要求是求目标函数极大值
    [now_F,index_F]=sort(F);%升序排序,now_F为排序后的,index_F一一对应原位置
    Best_xy=E(index_F(N),:);%升序排的,所以最后一个(100)为最大值,找到这个最大值是哪一组xy
    Best_Fit(k)=Best_F;%记录这一次迭代的最大目标函数值
    %复制,带遗传算法中复制规定的公式
    F_sum=sum(F);
    P_num=N*now_F/F_sum;%复制公式
    copynum=floor(P_num);%取整,确定这100组中每一组是否复制,复制多少次,续下
    %这里你会发现让目标函数值越大的xy组,被复制的次数越多(因为本题是求极大值)
    k=1;
    for i =1:N
        for j=1:copynum(i)
            temp_E(k,:)=E(index_F(i),:);%进行"复制"后的新的x,y自变量
            k=k+1;
        end
    end
    for i=k:N
        temp_E(i,:)=Best_xy;%把E后面几组还没有被复制替换的这些,均替换成最优的那组xy
    end
    %复制过程完成,接下来是交叉
    for i =1:N
        rand_point=round((20-1)*rand+1);%随机选定一个开始交叉的位置,这里E一行有20列,可选的交叉位置有20个
        rand_xy=round((N-1)*rand+1);%随机选定E的一行即随机选定一组xy作为交叉替换的数
        temp_Pc=rand;
        if Pc>temp_Pc
            for j=rand_point:20
                temp_E(i,j)=temp_E(rand_xy,j);%若rand_point为10,为第10开始到第20个数都交叉替换成rand_xy10到20对应的值
            end
        end
    end
    temp_E(N,:)=Best_xy;%把最后一行还是固定为之前的最优xy组
    %交叉结果,变异开始
    for i=1:N
        for j=1:20
            temp_Pm=rand;
            if Pm>temp_Pm
                if temp_E(i,j)==1
                    temp_E(i,j)=0;%变异每一组xy内部进行,按变异概率改变二进制xy的值
                else
                    temp_E(i,j)=1;%原来是1就换0,原来是0就换1;因为有temp_Pm,所以不大可能20个二进制值均改变
                end
            end
        end
    end
    E=temp_E;%把经历了一轮复制、交叉、变异的100组xy给E,以便继续对其进行新一轮复制、交叉、变异
end
plot(time,Best_Fit);%查看目标函数最大值收敛情况
x=x_min+(er(Best_xy(1:n))/(2^n-1))*(x_max-x_min)
y=y_min+(er(Best_xy(n+1:end))/(2^n-1))*(y_max-y_min)

上面代码中对应的function函数

er.m

function x=er(m)
a=length(m);x=0;
for i=1:a
    x=m(i)*2^(a-i)+x;%二进制转十进制
end
end

shi.m

function m=shi(x)
k=1;a=2;
while a>=1
    a=floor(x/2);
    b=mod(x,2);
    x=a;
    e(k)=b;
    k=k+1;
end
m=e(length(e):-1:1);%十进制转二进制

f.m

function f=f(x,y)
f=x^3+(2*y-x)^4;%目标函数(适应度函数)
end

运行结果:

c6f008beb39342adb227506b914d4ed1.bmp

对应最优xy解为x=10;y=20; 

需要了解遗传算法中复制、交叉、变异规定的公式(公式来源:http://t.csdn.cn/JlcJP

49d77a7dfbb4433880e4b2d422b25a64.jpeg

4ca7df79a4b246b99190e1dac48f1827.jpeg

简单的遗传算法,计算函数最值. function ga_main() % 遗传算法程序 % n-- 种群规模% ger-- 迭代次数% pc--- 交叉概率% pm-- 变异概率 % v-- 初始种群(规模为n)% f-- 目标函数值% fit-- 适应度向量 % vx-- 最优适应度值向量% vmfit-- 平均适应度值向量 clear all; close all; clc;%清屏 tic;%计时器开始计时 n=20;ger=100;pc=0.65;pm=0.05;%初始化参数 %以上为经验值,可以更改。 % 生成初始种群 v=init_population(n,22); %得到初始种群,22串长,生成20*22的0-1矩阵 [N,L]=size(v); %得到初始规模行,列 disp(sprintf('Number of generations:%d',ger)); disp(sprintf('Population size:%d',N)); disp(sprintf('Crossover probability:%.3f',pc)); disp(sprintf('Mutation probability:%.3f',pm)); %sprintf可以控制输出格式 % 待优化问题 xmin=0;xmax=9; %变量X范围 f='x+10*sin(x.*5)+7*cos(x.*4)'; % 计算适应度,并画出初始种群图形 x=decode(v(:,1:22),xmin,xmax);"位二进制换成十进制,%冒号表示对所有行进行操作。 fit=eval(f);%eval转化成数值型的 %计算适应度 figure(1);%打开第一个窗口 fplot(f,[xmin,xmax]);%隐函数画图 grid on;hold on; plot(x,fit,'k*');%作图,画初始种群的适应度图像 title('(a)染色体的初始位置');%标题 xlabel('x');ylabel('f(x)');%标记轴 % 迭代前的初始化 vmfit=[];%平均适应度 vx=[]; %最优适应度 it=1; % 迭代计数器 % 开始进化 while it<=ger %迭代次数 0代 %Reproduction(Bi-classist Selection) vtemp=roulette(v,fit);%复制算子 %Crossover v=crossover(vtemp,pc);%交叉算子 %Mutation变异算子 M=rand(N,L)<=pm;%这里的作用找到比0.05小的分量 %M(1,:)=zeros(1,L); v=v-2.*(v.*M)+M;%两个0-1矩阵相乘后M是1的地方V就不变,再乘以2. NICE!!确实好!!!把M中为1的位置上的地方的值变反 %这里是点乘 %变异 %Results x=decode(v(:,1:22),xmin,xmax);%解码,求目标函数值 fit=eval(f); %计算数值 [sol,indb]=max(fit);% 每次迭代中最优目标函数值,包括位置 v(1,:)=v(indb,:); %用最大值代替 fit_mean=mean(fit); % 每次迭代中目标函数值的平均值。mean求均值 vx=[vx sol]; %最优适应度值 vmfit=[vmfit fit_mean];%适应度均值 it=it+1; %迭代次数计数器增加 end
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PlatinumA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值