关于遗传算法的思考

一、底层逻辑

达尔文进化论中,生物遗传会让种群在一代代的优化中不断趋向于适应环境。遗传算法就是如此,给出初始的一个种群,通过一次次的迭代,达到不断的优化。我们在不断进化中,会产生“适应度函数值”很高的个体(适应度值越高,越容易活下来),你可以理解成“优质个体”,这些“优质个体”不容易被淘汰。那么如何要让计算机实现我们这种思想呢?

二、代码思维

遗传三种方式:

遗传的过程有复制、交叉、突变三种方式,弄成二进制形式比较好处理解。所谓复制,就是直接让子代继承上一代的某个个体的全部信息(00111->00111)。所谓交叉,就是让子代继承上一代中多个个体的部分信息拼凑起来(00111和11000->11111,后面的这个数继承了第一个数的后面三位和第二个数的前面两位)。所谓突变,就是继承上一代的信息不完全,在复制的过程中发生了信息的改变(00111->01111,正常复制应该是一模一样的,但是这里子代出岔子了,第二位从0变成了1,发生了突变)。

逻辑自洽环节:

1、想要遗传开始进化,总得有那么一批个体才行吧?我一开始不知道这个种群里面的整体的优劣程度如何,但是从这些个体开始迭代,咱就假设好这些个体的每次迭代的后的个体总数不变。

2、我每次迭代,我都会根据我之前主观设定的“适应度函数值”排名,对这批个体进行筛选,我让前面优秀的10%的个体直接保留,因为这批适应度强嘛,比较牛逼,我就留这批个体,再让剩下一批去迭代看下有没有更好的优化结果。

3、假如我迭代的次数越来越多,一代就会比一代更好,而且最终我们的这批个体的适应度值也达到了极限。最终我们就可以选择到理论上最优的这批个体,这批个体的基因已经到他们的天花板了。

直接开干:

clc 
clear
N=100;%种群内个体的数目,也就是刚开始那一批个体,方便后面开始优化
N_chrom=2;%有多少个因素影响适应度函数,这里就表示 适应度函数值=f(x1,x2)
iter=1000;%迭代次数,你要进行几轮的优化行动
mut=0.2;%突变的概率
acr=0.2;%交叉的概率
best=1;%不知道什么东西先放着
chrom_range=[-10 -10;10 10];%把上面的x1和x2的范围划定 
chrom=zeros(N,N_chrom);%保存这批个体全部影响因素因子数值的矩阵
fitness=zeros(N,1);%存放这批个体的适应度评分
fitness_ave=zeros(1,iter);%存放每一代的平均适应度
fitness_best=zeros(1,iter);%存放没一代的最优适应度
%初始化,这里随机分配一批个体给这个种群
chrom=Initialize(N,N_chrom,chrom_range);
fitness=CalFitness(chrom,N,N_chrom);%计算适应度
chrom_best=FindBest(chrom,fitness,N_chrom);%寻找最优个体
fitness_best(1)=chrom_best(end);%将当前的最优解存入矩阵中
fitness_ave(1)=CalAveFitness(fitness);%将当前平均适应度存入矩阵中
for t=2:iter
    chrom=MutChrom(chrom,mut,N,N_chrom,chrom_range,t,iter);
    chrom=AcrChrom(chrom,acr,N,N_chrom);
    fitness=CalFitness(chrom,N,N_chrom);
    chrom_best_temp=FindBest(chrom,fitness,N_chrom);
    if chrom_best_temp(end)>chrom_best(end)
        chrom_best=chrom_best_temp;
    end
    %%替换掉最劣
    [chrom,fitness]=ReplaceWorse(chrom,chrom_best,fitness);
    fitness_best(t)=chrom_best(end);
    fitness_ave(t)=CalAveFitness(fitness);
end
figure(1)
plot(1:iter,fitness_ave,'r',1:iter,fitness_best,'b')
grid on
legend('平均适应度''最优适应度')
e=PlotModel(chrom_best);
%5输出结果
disp(['最优染色体为',num2str(chrom_best(1:end-1))])
disp(['最优适应度为',num2str(chrom_best(end))])

%% 种群的初始化函数
function chrom_new =Initialize(N,N_chrom,chrom_range)
chrom_new=rand(N,N_chrom);
for i=1:N_chrom
    chrom_new(:,i)=chrom_new(:,i)*(chrom_range(2,i)-chrom_range(1,i))+chrom_range(1,i);
end
end
%%适应度计算
function fitness=CalFitness(chrom,N,N_chrom)
fitness = zeros(N,1);
for i=1:N
    x=chrom(i,1);
    y=chrom(i,2);
    fitness(i)=sin(x)+cos(y)+0.1*x+0.1*y;
end
end
%%选择淘汰
function chrom_best =FindBest(chrom,fitness,N_chrom)
chrom_best =zeros(1,N_chrom+1);
[maxNum,maxCorr]=max(fitness);
chrom_best(1:N_chrom)=chrom(maxCorr,:);
chrom_best(end)=maxNum;
end
%%计算平均适应度
function fitness_ave=CalAveFitness(fitness)
[N,~]=size(fitness);
fitness_ave=sum(fitness)/N;
end
%%变异函数
function chrom_new=MutChrom(chrom,mut,N,N_chrom,chrom_range,t,iter)
for i=1:N 
    for j=1:N_chrom
        mut_rand=rand;%随机生成一个数,代表自然里的基因突变,然后用这个值去判断是否发生突变
        if mut_rand<=mut
            mut_pm=rand;%%增加还是减少
            mut_num =rand*(1-t/iter)^2;
            if mut_pm<=0.5
                chrom(i,j)=chrom(i,j)*(1-mut_num);
            else 
                chrom(i,j)=chrom(i,j)*(1+mut_num);
            end
           chrom(i,j)=IfOut(chrom(i,j),chrom_range(:,j));%检验是否越界
        end
    end
end
chrom_new=chrom;%将变异完的结果存在新的矩阵中
end
%%变异是否超出自变量范围判断
function c_new=IfOut(c,range)
if c<range(1)||c>range(2)
    if abs(c-range(1))<abs(c-range(2))
        c_new=range(1);
    else 
        c_new=range(2);
    end
else
    c_new=c;
end
end
%%交叉处理
function chrom_new=AcrChrom(chrom,acr,N,N_chrom)
for i=1:N
    acr_rand=rand;
    if acr_rand<acr
        acr_chrom=floor((N-1)*rand+1);
        acr_node=floor((N_chrom-1)*rand+1);
        temp=chrom(i,acr_node);
        chrom(i,acr_node)=chrom(acr_chrom,acr_node);
        chrom(acr_chrom,acr_node)=temp;
    end
end
chrom_new=chrom;
end
function [chrom_new,fitness_new]=ReplaceWorse(chrom,chrom_best,fitness)
max_num=max(fitness);
min_num=min(fitness);
limit =(max_num-min_num)*0.2+min_num;

replace_corr=fitness<limit;

replace_num=sum(replace_corr);
chrom(replace_corr,:)=ones(replace_num,1)*chrom_best(1:end-1);
fitness(replace_corr)=ones(replace_num,1)*chrom_best(end);
chrom_new=chrom;
fitness_new=fitness;
end
%%绘制结果
    function y=PlotModel(chrom)
        x=chrom(1);
        y=chrom(2);
        z=chrom(3);
        figure(2)
        scatter3(x,y,z,'ko')
        hold on
        [X,Y]=meshgrid(-10:0.1:10);
        Z=sin(X)+cos(Y)+0.1*X+0.1*Y;
        mesh(X,Y,Z)
    end





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值