精华内容
下载资源
问答
  • 提供了三个经典遗传算法的案例,内有源代码。欢迎大家交流,共同进步。
  • MATLAB的三个遗传算法小段程序,看懂这三个程序遗传算法不是问题
  • 三个遗传算法matlab程序实例
  • 三个遗传算法matlab程序实例

    万次阅读 多人点赞 2018-09-14 22:26:48
    遗传算法程序(一):  说明: fga.m 为遗传算法的主程序; 采用二进制Gray编码,采用基于轮盘赌法的非线性排名选择, 均匀交叉,变异操作,而且还引入了倒位操作! function [BestPop,Trace]=fga(FUN,LB,UB,eranum,...

    遗传算法程序(一):

       说明: fga.m 为遗传算法的主程序; 采用二进制Gray编码,采用基于轮盘赌法的非线性排名选择, 均匀交叉,变异操作,而且还引入了倒位操作!

    function [BestPop,Trace]=fga(FUN,LB,UB,eranum,popsize,pCross,pMutation,pInversion,options)
    
    % [BestPop,Trace]=fmaxga(FUN,LB,UB,eranum,popsize,pcross,pmutation)
    
    % Finds a maximum of a function of several variables.
    
    % fmaxga solves problems of the form:
    
    %      max F(X) subject to: LB <= X <= UB                           
    
    % BestPop       - 最优的群体即为最优的染色体群
    
    % Trace         - 最佳染色体所对应的目标函数值
    
    % FUN           - 目标函数
    
    % LB            - 自变量下限
    
    % UB            - 自变量上限
    
    % eranum        - 种群的代数,取100--1000(默认200)
    
    % popsize       - 每一代种群的规模;此可取50--200(默认100)
    
    % pcross        - 交叉概率,一般取0.5--0.85之间较好(默认0.8)
    
    % pmutation     - 初始变异概率,一般取0.05-0.2之间较好(默认0.1)
    
    % pInversion    - 倒位概率,一般取0.05-0.3之间较好(默认0.2)
    
    % options       - 1*2矩阵,options(1)=0二进制编码(默认0),option(1)~=0十进制编
    
    %码,option(2)设定求解精度(默认1e-4)
    
    %
    
    % ------------------------------------------------------------------------
    
    
    
    T1=clock;
    
    if nargin<3, error('FMAXGA requires at least three input arguments'); end
    
    if nargin==3, eranum=200;popsize=100;pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];end
    
    if nargin==4, popsize=100;pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];end
    
    if nargin==5, pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];end
    
    if nargin==6, pMutation=0.1;pInversion=0.15;options=[0 1e-4];end
    
    if nargin==7, pInversion=0.15;options=[0 1e-4];end
    
    if find((LB-UB)>0)
    
       error('数据输入错误,请重新输入(LB<UB):');
    
    end
    
    s=sprintf('程序运行需要约%.4f 秒钟时间,请稍等......',(eranum*popsize/1000));
    
    disp(s);
    
    
    
    global m n NewPop children1 children2 VarNum
    
    
    
    bounds=[LB;UB]';bits=[];VarNum=size(bounds,1);
    
    precision=options(2);%由求解精度确定二进制编码长度
    
    bits=ceil(log2((bounds(:,2)-bounds(:,1))' ./ precision));%由设定精度划分区间
    
    [Pop]=InitPopGray(popsize,bits);%初始化种群
    
    [m,n]=size(Pop);
    
    NewPop=zeros(m,n);
    
    children1=zeros(1,n);
    
    children2=zeros(1,n);
    
    pm0=pMutation;
    
    BestPop=zeros(eranum,n);%分配初始解空间BestPop,Trace
    
    Trace=zeros(eranum,length(bits)+1);
    
    i=1;
    
    while i<=eranum
    
        for j=1:m
    
            value(j)=feval(FUN(1,:),(b2f(Pop(j,:),bounds,bits)));%计算适应度
    
        end
    
        [MaxValue,Index]=max(value);
    
        BestPop(i,:)=Pop(Index,:);
    
        Trace(i,1)=MaxValue;
    
        Trace(i,(2:length(bits)+1))=b2f(BestPop(i,:),bounds,bits);
    
        [selectpop]=NonlinearRankSelect(FUN,Pop,bounds,bits);%非线性排名选择
    
    [CrossOverPop]=CrossOver(selectpop,pCross,round(unidrnd(eranum-i)/eranum));
    
    %采用多点交叉和均匀交叉,且逐步增大均匀交叉的概率
    
        %round(unidrnd(eranum-i)/eranum)
    
        [MutationPop]=Mutation(CrossOverPop,pMutation,VarNum);%变异
    
        [InversionPop]=Inversion(MutationPop,pInversion);%倒位
    
        Pop=InversionPop;%更新
    
    pMutation=pm0+(i^4)*(pCross/3-pm0)/(eranum^4);
    
    %随着种群向前进化,逐步增大变异率至1/2交叉率
    
        p(i)=pMutation;
    
        i=i+1;
    
    end
    
    t=1:eranum;
    
    plot(t,Trace(:,1)');
    
    title('函数优化的遗传算法');xlabel('进化世代数(eranum)');ylabel('每一代最优适应度(maxfitness)');
    
    [MaxFval,I]=max(Trace(:,1));
    
    X=Trace(I,(2:length(bits)+1));
    
    hold on; plot(I,MaxFval,'*');
    
    text(I+5,MaxFval,['FMAX=' num2str(MaxFval)]);
    
    str1=sprintf  ('进化到 %d 代 ,自变量为 %s 时,得本次求解的最优值 %f\n对应染色体是:%s',I,num2str(X),MaxFval,num2str(BestPop(I,:)));
    
    disp(str1);
    
    %figure(2);plot(t,p);%绘制变异值增大过程
    
    T2=clock;
    
    elapsed_time=T2-T1;
    
    if elapsed_time(6)<0
    
        elapsed_time(6)=elapsed_time(6)+60; elapsed_time(5)=elapsed_time(5)-1;
    
    end
    
    if elapsed_time(5)<0
    
        elapsed_time(5)=elapsed_time(5)+60;elapsed_time(4)=elapsed_time(4)-1;
    
    end %像这种程序当然不考虑运行上小时啦
    
    str2=sprintf('程序运行耗时 %d 小时 %d 分钟 %.4f 秒',elapsed_time(4),elapsed_time(5),elapsed_time(6));
    
    disp(str2);
    
    %初始化种群
    
    %采用二进制Gray编码,其目的是为了克服二进制编码的Hamming悬崖缺点
    
    function [initpop]=InitPopGray(popsize,bits)
    
    len=sum(bits);
    
    initpop=zeros(popsize,len);%The whole zero encoding individual
    
    for i=2:popsize-1
    
        pop=round(rand(1,len));
    
        pop=mod(([0 pop]+[pop 0]),2);
    
        %i=1时,b(1)=a(1);i>1时,b(i)=mod(a(i-1)+a(i),2)
    
        %其中原二进制串:a(1)a(2)...a(n),Gray串:b(1)b(2)...b(n)
    
        initpop(i,:)=pop(1:end-1);
    
    end
    
    initpop(popsize,:)=ones(1,len);%The whole one encoding individual
    
    
    
    
    
    
    
    
    
    %解码
    
    
    
    function [fval] = b2f(bval,bounds,bits)
    
    % fval   - 表征各变量的十进制数
    
    % bval   - 表征各变量的二进制编码串
    
    % bounds - 各变量的取值范围
    
    % bits   - 各变量的二进制编码长度
    
    scale=(bounds(:,2)-bounds(:,1))'./(2.^bits-1); %The range of the variables
    
    numV=size(bounds,1);
    
    cs=[0 cumsum(bits)];
    
    for i=1:numV
    
    a=bval((cs(i)+1):cs(i+1));
    
    fval(i)=sum(2.^(size(a,2)-1:-1:0).*a)*scale(i)+bounds(i,1);
    
    end
    
    
    
    
    
    
    
    
    
    %选择操作
    
    %采用基于轮盘赌法的非线性排名选择
    
    %各个体成员按适应值从大到小分配选择概率:
    
    %P(i)=(q/1-(1-q)^n)*(1-q)^i, 其中 P(0)>P(1)>...>P(n), sum(P(i))=1
    
    
    
    function [selectpop]=NonlinearRankSelect(FUN,pop,bounds,bits)
    
    global m n
    
    selectpop=zeros(m,n);
    
    fit=zeros(m,1);
    
    for i=1:m
    
        fit(i)=feval(FUN(1,:),(b2f(pop(i,:),bounds,bits)));%以函数值为适应值做排名依据
    
    end
    
    selectprob=fit/sum(fit);%计算各个体相对适应度(0,1)
    
    q=max(selectprob);%选择最优的概率
    
    x=zeros(m,2);
    
    x(:,1)=[m:-1:1]';
    
    [y x(:,2)]=sort(selectprob);
    
    r=q/(1-(1-q)^m);%标准分布基值
    
    newfit(x(:,2))=r*(1-q).^(x(:,1)-1);%生成选择概率
    
    newfit=cumsum(newfit);%计算各选择概率之和
    
    rNums=sort(rand(m,1));
    
    fitIn=1;newIn=1;
    
    while newIn<=m
    
        if rNums(newIn)<newfit(fitIn)
    
            selectpop(newIn,:)=pop(fitIn,:);
    
            newIn=newIn+1;
    
        else
    
            fitIn=fitIn+1;
    
        end
    
    end
    
    
    
    
    
    
    
    
    
    %交叉操作
    
    function [NewPop]=CrossOver(OldPop,pCross,opts)
    
    %OldPop为父代种群,pcross为交叉概率
    
    global m n NewPop
    
    r=rand(1,m);
    
    y1=find(r<pCross);
    
    y2=find(r>=pCross);
    
    len=length(y1);
    
    if len>2&mod(len,2)==1%如果用来进行交叉的染色体的条数为奇数,将其调整为偶数
    
        y2(length(y2)+1)=y1(len);
    
        y1(len)=[];
    
    end
    
    if length(y1)>=2
    
       for i=0:2:length(y1)-2
    
           if opts==0
    
               [NewPop(y1(i+1),:),NewPop(y1(i+2),:)]=EqualCrossOver(OldPop(y1(i+1),:),OldPop(y1(i+2),:));
    
           else
    
               [NewPop(y1(i+1),:),NewPop(y1(i+2),:)]=MultiPointCross(OldPop(y1(i+1),:),OldPop(y1(i+2),:));
    
           end
    
       end    
    
    end
    
    NewPop(y2,:)=OldPop(y2,:);
    
    
    
    %采用均匀交叉
    
    function [children1,children2]=EqualCrossOver(parent1,parent2)
    
    
    
    global n children1 children2
    
    hidecode=round(rand(1,n));%随机生成掩码
    
    crossposition=find(hidecode==1);
    
    holdposition=find(hidecode==0);
    
    children1(crossposition)=parent1(crossposition);%掩码为1,父1为子1提供基因
    
    children1(holdposition)=parent2(holdposition);%掩码为0,父2为子1提供基因
    
    children2(crossposition)=parent2(crossposition);%掩码为1,父2为子2提供基因
    
    children2(holdposition)=parent1(holdposition);%掩码为0,父1为子2提供基因
    
    
    
    %采用多点交叉,交叉点数由变量数决定
    
    
    
    function [Children1,Children2]=MultiPointCross(Parent1,Parent2)
    
    
    
    global n Children1 Children2 VarNum
    
    Children1=Parent1;
    
    Children2=Parent2;
    
    Points=sort(unidrnd(n,1,2*VarNum));
    
    for i=1:VarNum
    
        Children1(Points(2*i-1):Points(2*i))=Parent2(Points(2*i-1):Points(2*i));
    
        Children2(Points(2*i-1):Points(2*i))=Parent1(Points(2*i-1):Points(2*i));
    
    end
    
    
    
    
    
    
    
    
    
    %变异操作
    
    function [NewPop]=Mutation(OldPop,pMutation,VarNum)
    
    
    
    global m n NewPop
    
    r=rand(1,m);
    
    position=find(r<=pMutation);
    
    len=length(position);
    
    if len>=1
    
       for i=1:len
    
           k=unidrnd(n,1,VarNum); %设置变异点数,一般设置1点
    
           for j=1:length(k)
    
               if OldPop(position(i),k(j))==1
    
                  OldPop(position(i),k(j))=0;
    
               else
    
                  OldPop(position(i),k(j))=1;
    
               end
    
           end
    
       end
    
    end
    
    NewPop=OldPop;
    
    
    
    
    
    
    
    
    
    %倒位操作
    
    
    
    function [NewPop]=Inversion(OldPop,pInversion)
    
    
    
    global m n NewPop
    
    NewPop=OldPop;
    
    r=rand(1,m);
    
    PopIn=find(r<=pInversion);
    
    len=length(PopIn);
    
    if len>=1
    
        for i=1:len
    
            d=sort(unidrnd(n,1,2));
    
            if d(1)~=1&d(2)~=n
    
               NewPop(PopIn(i),1:d(1)-1)=OldPop(PopIn(i),1:d(1)-1);
    
               NewPop(PopIn(i),d(1):d(2))=OldPop(PopIn(i),d(2):-1:d(1));
    
               NewPop(PopIn(i),d(2)+1:n)=OldPop(PopIn(i),d(2)+1:n);
    
           end
    
       end
    
    end

     

     

     

    遗传算法程序(二):


     

    function youhuafun
    
    
    
    D=code;
    
    N=50;         % Tunable
    
    maxgen=50;     % Tunable
    
    crossrate=0.5; %Tunable
    
    muterate=0.08; %Tunable
    
    generation=1;  
    
    num = length(D);
    
    fatherrand=randint(num,N,3);
    
    score = zeros(maxgen,N);
    
    while generation<=maxgen
    
       ind=randperm(N-2)+2; % 随机配对交叉
    
       A=fatherrand(:,ind(1:(N-2)/2));
    
       B=fatherrand(:,ind((N-2)/2+1:end));
    
    %     多点交叉
    
       rnd=rand(num,(N-2)/2);
    
       ind=rnd   tmp=A(ind);
    
       A(ind)=B(ind);
    
       B(ind)=tmp;
    
    
    
    % % 两点交叉
    
    %     for kk=1:(N-2)/2
    
    %         rndtmp=randint(1,1,num)+1;
    
    %         tmp=A(1:rndtmp,kk);
    
    %         A(1:rndtmp,kk)=B(1:rndtmp,kk);
    
    %         B(1:rndtmp,kk)=tmp;
    
    %     end
    
       fatherrand=[fatherrand(:,1:2),A,B];
    
       
    
       % 变异
    
       rnd=rand(num,N);
    
       ind=rnd   [m,n]=size(ind);
    
       tmp=randint(m,n,2)+1;
    
       tmp(:,1:2)=0;
    
       fatherrand=tmp+fatherrand;
    
       fatherrand=mod(fatherrand,3);
    
    %     fatherrand(ind)=tmp;
    
       
    
       %评价、选择
    
       scoreN=scorefun(fatherrand,D);% 求得N个个体的评价函数
    
       score(generation,:)=scoreN;
    
       [scoreSort,scoreind]=sort(scoreN);
    
       sumscore=cumsum(scoreSort);
    
       sumscore=sumscore./sumscore(end);
    
       childind(1:2)=scoreind(end-1:end);
    
       for k=3:N
    
           tmprnd=rand;
    
           tmpind=tmprnd       difind=[0,diff(tmpind)];
    
           if ~any(difind)
    
               difind(1)=1;
    
           end
    
           childind(k)=scoreind(logical(difind));
    
       end
    
       fatherrand=fatherrand(:,childind);    
    
       generation=generation+1;
    
    end
    
    % score
    
    maxV=max(score,[],2);
    
    minV=11*300-maxV;
    
    plot(minV,'*');title('各代的目标函数值');
    
    F4=D(:,4);
    
    FF4=F4-fatherrand(:,1);
    
    FF4=max(FF4,1);
    
    D(:,5)=FF4;
    
    save DData D
    
    
    
    
    
    function D=code
    
    load youhua.mat
    
    % properties F2 and F3
    
    F1=A(:,1);
    
    F2=A(:,2);
    
    F3=A(:,3);
    
    if (max(F2)>1450)||(min(F2)<=900)
    
       error('DATA property F2 exceed it''s range (900,1450]')
    
    end
    
    % get group property F1 of data, according to F2 value
    
    F4=zeros(size(F1));
    
    for ite=11:-1:1
    
       index=find(F2<=900+ite*50);
    
       F4(index)=ite;
    
    end
    
    D=[F1,F2,F3,F4];
    
    
    
    function ScoreN=scorefun(fatherrand,D)
    
    F3=D(:,3);
    
    F4=D(:,4);
    
    N=size(fatherrand,2);
    
    FF4=F4*ones(1,N);
    
    FF4rnd=FF4-fatherrand;
    
    FF4rnd=max(FF4rnd,1);
    
    ScoreN=ones(1,N)*300*11;
    
    % 这里有待优化
    
    for k=1:N
    
       FF4k=FF4rnd(:,k);
    
       for ite=1:11
    
           F0index=find(FF4k==ite);
    
           if ~isempty(F0index)
    
               tmpMat=F3(F0index);
    
               tmpSco=sum(tmpMat);
    
               ScoreBin(ite)=mod(tmpSco,300);
    
           end
    
       end
    
       Scorek(k)=sum(ScoreBin);
    
    end
    
    ScoreN=ScoreN-Scorek;
    
    

     

     

     

    遗传算法程序(三):

    %IAGA
    
    function best=ga
    
    clear
    
    MAX_gen=200;            %最大迭代步数
    
    best.max_f=0;           %当前最大的适应度
    
    STOP_f=14.5;            %停止循环的适应度
    
    RANGE=[0 255];          %初始取值范围[0 255]
    
    SPEEDUP_INTER=5;       %进入加速迭代的间隔
    
    advance_k=0;            %优化的次数
    
    
    
    popus=init;             %初始化
    
    for gen=1:MAX_gen
    
        fitness=fit(popus,RANGE);       %求适应度
    
        f=fitness.f;
    
        picked=choose(popus,fitness);   %选择
    
        popus=intercross(popus,picked); %杂交
    
        popus=aberrance(popus,picked); %变异
    
        if max(f)>best.max_f
    
            advance_k=advance_k+1;
    
            x_better(advance_k)=fitness.x;
    
            best.max_f=max(f);
    
            best.popus=popus;
    
            best.x=fitness.x;
    
        end
    
        if mod(advance_k,SPEEDUP_INTER)==0
    
            RANGE=minmax(x_better);
    
           
    
            RANGE
    
           
    
            advance=0;
    
        end
    
    end
    
    return;
    
    function popus=init%初始化
    
    M=50;%种群个体数目
    
    N=30;%编码长度
    
    popus=round(rand(M,N));
    
    return;
    
    
    
    function fitness=fit(popus,RANGE)%求适应度
    
    [M,N]=size(popus);
    
    fitness=zeros(M,1);%适应度
    
    f=zeros(M,1);%函数值
    
    A=RANGE(1);B=RANGE(2);%初始取值范围[0 255]
    
    
    
    for m=1:M
    
        x=0;
    
        for n=1:N
    
            x=x+popus(m,n)*(2^(n-1));
    
        end
    
        x=x*((B-A)/(2^N))+A;
    
        for k=1:5
    
            f(m,1)=f(m,1)-(k*sin((k+1)*x+k));
    
        end
    
    end
    
    f_std=(f-min(f))./(max(f)-min(f));%函数值标准化
    
    fitness.f=f;fitness.f_std=f_std;fitness.x=x;
    
    return;
    
    
    
    function picked=choose(popus,fitness)%选择
    
    f=fitness.f;f_std=fitness.f_std;
    
    [M,N]=size(popus);
    
    choose_N=3;                 %选择choose_N对双亲
    
    picked=zeros(choose_N,2);   %记录选择好的双亲
    
    p=zeros(M,1);               %选择概率
    
    d_order=zeros(M,1);
    
    
    
    %把父代个体按适应度从大到小排序
    
    f_t=sort(f,'descend');%将适应度按降序排列
    
    for k=1:M
    
        x=find(f==f_t(k));%降序排列的个体序号
    
        d_order(k)=x(1);
    
    end
    
    for m=1:M
    
        popus_t(m,:)=popus(d_order(m),:);
    
    end
    
    popus=popus_t;
    
    f=f_t;
    
    
    
    p=f_std./sum(f_std);                    %选择概率
    
    c_p=cumsum(p)';                          %累积概率
    
    
    
    for cn=1:choose_N
    
        picked(cn,1)=roulette(c_p); %轮盘赌
    
        picked(cn,2)=roulette(c_p); %轮盘赌
    
        popus=intercross(popus,picked(cn,:));%杂交
    
    end
    
    popus=aberrance(popus,picked);%变异
    
    return;
    
    
    
    function popus=intercross(popus,picked) %杂交
    
    [M_p,N_p]=size(picked);
    
    [M,N]=size(popus);
    
    for cn=1:M_p
    
        p(1)=ceil(rand*N);%生成杂交位置
    
        p(2)=ceil(rand*N);
    
        p=sort(p);
    
        t=popus(picked(cn,1),p(1):p(2));
    
        popus(picked(cn,1),p(1):p(2))=popus(picked(cn,2),p(1):p(2));
    
        popus(picked(cn,2),p(1):p(2))=t;
    
    end
    
    return;
    
    function popus=aberrance(popus,picked) %变异
    
    P_a=0.05;%变异概率
    
    [M,N]=size(popus);
    
    [M_p,N_p]=size(picked);
    
    U=rand(1,2);
    
    
    
    for kp=1:M_p
    
        if U(2)>=P_a        %如果大于变异概率,就不变异
    
            continue;
    
        end
    
        if U(1)>=0.5
    
            a=picked(kp,1);
    
        else
    
            a=picked(kp,2);
    
        end
    
        p(1)=ceil(rand*N);%生成变异位置
    
        p(2)=ceil(rand*N);
    
        if popus(a,p(1))==1%0 1变换
    
            popus(a,p(1))=0;
    
        else
    
            popus(a,p(1))=1;
    
        end
    
        if popus(a,p(2))==1
    
            popus(a,p(2))=0;
    
        else
    
            popus(a,p(2))=1;
    
        end
    
    end
    
    return;
    
    
    
    function picked=roulette(c_p) %轮盘赌
    
    [M,N]=size(c_p);
    
    M=max([M N]);
    
    U=rand;
    
    if U<c_p(1)
    
        picked=1;
    
        return;
    
    end
    
    for m=1:(M-1)
    
        if U>c_p(m) & U<c_p(m+1)
    
            picked=m+1;
    
            break;
    
        end
    
    end

     

    全方位的两点杂交、两点变异的改进的加速遗传算法(IAGA)

    展开全文
  • 三个遗传算法matlab程序实例_matlab遗传算法_遗传算法案例_遗传算法_源码.rar
  • 三个遗传算法matlab程序实例源码.rar
  • 三个遗传算法matlab程序实例.docx
  • 全方位的两点杂交、两点变异的改进的加速遗传算法
  • 几个已调试好的matlab程序 % 求下列函数的最大值 % 1 f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] 2 f(x)=x 10*sin(5x) 7*cos(4x)的最大值,其中0 3 在-5,i=1,2区间内,求解 f(x1,x2)=-20*exp(-0.2*sqrt(0.5*(x1.^2+...
  • 遗传算法的基本思想是: 从一组解的初值开始进行搜索,这组解称为一个种群, 种群由一定数量、通过基因编码的个体组成, 其中每 个个体称为染色体。不同个体通过染色体的复制、交叉 和变异又生成新的个体,依照适者...
  • GA遗传算法matlab程序

    2018-12-11 14:03:13
    基于ATO的列车速度曲线优化,用matlab遗传算法实现。适合初学者。
  • matlab遗传算法实例

    2018-06-28 13:18:33
    matlab遗传算法实例 matlab遗传算法实例 matlab遗传算法实例
  • 详解遗传算法(含MATLAB代码)

    万次阅读 多人点赞 2019-05-29 11:30:47
    目录 一、遗传算法概述 二、遗传算法的特点和应用 三、遗传算法的基本流程及实现技术 3.1 遗传算法的基本流程 3.2 遗传算法的实现技术 ...五、遗传算法编程实例MATLAB) 一、遗传算法概述 遗传算法(...

    目录

    一、遗传算法概述

    二、遗传算法的特点和应用

    三、遗传算法的基本流程及实现技术

    3.1 遗传算法的基本流程

    3.2 遗传算法的实现技术

    1.编码

    2.适应度函数

    3.选择算子

    4.交叉算子

    5.变异算子

    6.运行参数

    四、遗传算法的基本原理

    4.1 模式定理

    4.2 积木块假设

    五、遗传算法编程实例(MATLAB)


    一、遗传算法概述

            遗传算法(Genetic Algorithm,GA)是进化计算的一部分,是模拟达尔文的遗传选择和自然淘汰的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。该算法简单、通用,鲁棒性强,适于并行处理。

    二、遗传算法的特点和应用

       遗传算法是一类可用于复杂系统优化的具有鲁棒性的搜索算法,与传统的优化算法相比,具有以下特点:

    1. 以决策变量的编码作为运算对象。

        传统的优化算法往往直接利用决策变量的实际值本身来进行优化计算,但遗传算法是使用决策变量的某种形式的编码作为运算对象。这种对决策变量的编码处理方式,使得我们在优化计算中可借鉴生物学中染色体和基因等概念,可以模仿自然界中生物的遗传和进化激励,也可以很方便地应用遗传操作算子。

    2. 直接以适应度作为搜索信息。

        传统的优化算法不仅需要利用目标函数值,而且搜索过程往往受目标函数的连续性约束,有可能还需要满足“目标函数的导数必须存在”的要求以确定搜索方向。

        遗传算法仅使用由目标函数值变换来的适应度函数值就可确定进一步的搜索范围,无需目标函数的导数值等其他辅助信息。直接利用目标函数值或个体适应度值也可以将搜索范围集中到适应度较高部分的搜索空间中,从而提高搜索效率。

    3. 使用多个点的搜索信息,具有隐含并行性

        传统的优化算法往往是从解空间的一个初始点开始最优解的迭代搜索过程。单个点所提供的搜索信息不多,所以搜索效率不高,还有可能陷入局部最优解而停滞;

        遗传算法从由很多个体组成的初始种群开始最优解的搜索过程,而不是从单个个体开始搜索。对初始群体进行的、选择、交叉、变异等运算,产生出新一代群体,其中包括了许多群体信息。这些信息可以避免搜索一些不必要的点,从而避免陷入局部最优,逐步逼近全局最优解。

    4. 使用概率搜索而非确定性规则。

       传统的优化算法往往使用确定性的搜索方法,一个搜索点到另一个搜索点的转移有确定的转移方向和转移关系,这种确定性可能使得搜索达不到最优店,限制了算法的应用范围。

       遗传算法是一种自适应搜索技术,其选择、交叉、变异等运算都是以一种概率方式进行的,增加了搜索过程的灵活性,而且能以较大概率收敛于最优解,具有较好的全局优化求解能力。但,交叉概率、变异概率等参数也会影响算法的搜索结果和搜索效率,所以如何选择遗传算法的参数在其应用中是一个比较重要的问题

    综上,由于遗传算法的整体搜索策略和优化搜索方式在计算时不依赖于梯度信息或其他辅助知识,只需要求解影响搜索方向的目标函数和相应的适应度函数,所以遗传算法提供了一种求解复杂系统问题的通用框架。它不依赖于问题的具体领域,对问题的种类有很强的鲁棒性,所以广泛应用于各种领域,包括:

    • 函数优化
    • 组合优化生产调度问题
    • 自动控制
    • 机器人学
    • 图像处理(图像恢复、图像边缘特征提取......)
    • 人工生命
    • 遗传编程
    • 机器学习

    三、遗传算法的基本流程及实现技术

       基本遗传算法(Simple Genetic Algorithms,SGA)只使用选择算子、交叉算子和变异算子这三种遗传算子,进化过程简单,是其他遗传算法的基础。

    3.1 遗传算法的基本流程

    1.  通过随机方式产生若干由确定长度(长度与待求解问题的精度有关)编码的初始群体;
    2. 通过适应度函数对每个个体进行评价,选择适应度值高的个体参与遗传操作,适应度低的个体被淘汰;
    3. 经遗传操作(复制、交叉、变异)的个体集合形成新一代种群,直到满足停止准则(进化代数GEN>=?);
    4. 将后代中变现最好的个体作为遗传算法的执行结果。

                                                       

    其中,GEN是当前代数;M是种群规模,i代表种群数量。

    3.2 遗传算法的实现技术

    基本遗传算法(SGA)由编码、适应度函数、遗传算子(选择、交叉、变异)及运行参数组成。

    1.编码

    (1)二进制编码

    二进制编码的字符串长度与问题所求解的精度有关。需要保证所求解空间内的每一个个体都可以被编码。

    优点:编、解码操作简单,遗传、交叉便于实现

    缺点:长度大

    (2)其他编码方法

    格雷码、浮点数编码、符号编码、多参数编码等

    2.适应度函数

    适应度函数要有效反映每一个染色体与问题的最优解染色体之间的差距。

    3.选择算子

    通过选择算子模拟“优胜劣汰”,适应度高的个体被遗传到下一代的概率较大,适应度低的算子被遗传到下一代的概率较小。

    常用的选择算法:轮盘赌选择法,即令\sum f_i表示群体的适应度函数值的总和,f_i表示群体中第i个染色体的适应度值,则它产生后代的能力刚好为其适应度值所占的份额\frac{f_i}{\sum f_i}

    4.交叉算子

    • 交叉运算是指对两个相互配对的染色体按某种方式相互交换其部分基因,从而形成两个新的个体;
    • 交叉运算是遗传算法区别于其他进化算法的重要特征,是产生新个体的主要方法。

    在交叉之前需要将群体中的个体进行配对,一般采取随机配对原则。

    常用的交叉方式:

    • 单点交叉
    • 双点交叉(多点交叉,交叉点数越多,个体的结构被破坏的可能性越大,一般不采用多点交叉的方式)
    • 均匀交叉
    • 算术交叉

    5.变异算子

    遗传算法中的变异运算是指将个体染色体编码串中的某些基因座上的基因值用该基因座的其他等位基因来替换,从而形成一个新的个体。

    就遗传算法运算过程中产生新个体的能力方面来说,交叉运算是产生新个体的主要方法,它决定了遗传算法的全局搜索能力;而变异运算只是产生新个体的辅助方法,但也是必不可少的一个运算步骤,它决定了遗传算法的局部搜索能力。交叉算子与变异算子的共同配合完成了其对搜索空间的全局搜索和局部搜索,从而使遗传算法能以良好的搜索性能完成最优化问题的寻优过程。

    6.运行参数

    • 编码长度。编码长度取决于问题解的精度,精度越高,编码越长;
    • 种群规模。规模小,收敛快但降低了种群的多样性,N=20-200
    • 交叉概率。较大的交叉概率容易破坏种群中已形成的优良结构,使搜索具有太大随机性;较小的交叉概率发现新个体的速度太慢,一般取值为P_c=0.4-0.99
    • 变异概率。变异概率太小,则变异操作产生新个体的能力和抑制早熟现象的能力会较差;变异概率过高随机性过大,一般建议取值范围为0.005~0.01
    • 终止进化代数。算法运行结束的条件之一,一般取100~1000

    四、遗传算法的基本原理

    4.1 模式定理

    定义1:模式H是由{0,1,*}中的元素组成的一个编码串,其中“*”表示通配符,既能被当作0,也能被当作1。e.g. H=10**1

    定义2:模式的阶,是指模式中所含有0,1的数量,记作O(H)  e.g. O(11*00**)=4

    定义3:模式的矩,即模式的长度,是指模式中从左到右第一个非*位和最后一个非*位之间的距离,记作\delta (H)

              e.g. \delta (01**1)=3;\delta (**0*1)=2;\delta (***1**)=1

    定义4:模式的适应度值,是群体中所包含的全部个体的适应度值的平均值。

    定义5:在选择、交叉、变异遗传算子的作用下,低阶、长度短、超过群体平均适应值的模式的生存数量,将随迭代次数以指数规律增长。

    模式定理不仅说明基因块的样本呈指数增长,也说明用遗传算法寻求最优样本的可能性,但它并未指出遗传算法一定能够寻求到最优解,积木块假设说明了遗传算法的寻找最优解的能力。

    4.2 积木块假设

    具有低阶、定义长度短,且适应度值高于群体平均适应度值的模式称为基因块或积木块。

    积木块假设:个体的基因块通过选择、交叉、变异等遗传算子的作用,能够相互拼接在一起,形成适应度更高的个体编码串。

    积木块假设说明了用遗传算法求解各类问题的基本思想,即通过积木块直接相互拼接在一起能够产生更好的解。

    五、遗传算法编程实例(MATLAB)

    https://github.com/strawberry-magic-pocket/Genetic-Algorithm.git

     

    展开全文
  • 遗传算法MATLAB程序实例doc-遗传算法MATLAB程序实例.doc 求函数的最值的遗传算法 MATLAB程序实例 
  • 代码中有特别详细的注释,包括7个模块,供大家学习使用。
  • 非线性整数规划是一个具有指数复杂度的NP问题,如果约束较为复杂,Matlab优化工具箱和一些优化软件比如lingo等,常常无法应用,即使能应用也不能给...下面举一个遗传算法应用于非线性整数规划的编程实例,供大家参考!
  • 一个一个简单的遗传算法例子,代码注释详尽,很适合初学者进行学习。代码已经经过测试,请放心下载
  • 非线性整数规划是一个具有指数复杂度的NP问题,如果约束较为复杂,Matlab优化工具箱和一些优化软件比如lingo等,常常无法应用,即使能应用也不能给...下面举一个遗传算法应用于非线性整数规划的编程实例,供大家参考!
  • matlab遗传算法

    2018-05-31 17:31:06
    matlab遗传算法源代码底层实现,以及具体的示例运用代码。
  • 经典遗传算法MATLAB实例

    千次阅读 多人点赞 2020-10-28 12:20:23
    经典遗传算法及简单实例MATLAB)1. 遗传算法简单介绍1.1 理论基础1.2 算法要点1.1 编码1.2 适应度函数1.3 基本流程2. 雪兔实例 1. 遗传算法简单介绍 1.1 理论基础 整个算法的基础就是达尔文的生物进化论,...

    1. 遗传算法简单介绍

    1.1 理论基础

    整个算法的基础就是达尔文的生物进化论,“物竞天择,适者生存” 这句话已经是常识了。

    用雪兔做一个引子吧:

    东北那旮瘩,有群原始雪兔,刚从未知物种进化而来,五颜六色(表现型)漂亮极了,称之为 I(0)。
    (注意:种群初始化)

    入夏了,雪兔们出来觅食,浅色兔在草地中无所遁形,被雪狐收割了一波(大批浅色+小批深色)。
    入冬了,雪兔们出来觅食,深色兔在雪地中光彩夺目,被雪狐收割了一波(大批深色+小批浅色)。
    (注意:自然选择过程)

    春天到了,又到了兔兔们生孩的季节,雪兔们染色体内的基因进行 重组/不重组 ,产生一批受精卵。
    (注意:交叉遗传过程)

    受精卵内的生命活动非常强烈,造成了基因的 突变/不突变,产生了各种各样奇怪的小雪兔。
    (注意:基因变异过程)

    老雪兔们完成了自己繁衍的使命,全部不知所踪。留下新生代,继续在各种威胁下苟活,这一代叫 I(1)。

    再次入冬入夏,雪兔们又出来觅食。。。。。。再次入冬,觅食。。。。。。入冬,觅食。。。。。。

    就这样,50年后,基因突变和重组造就了种神奇的兔子:夏天褐色,冬天白色,可以轻易躲避雪狐的追捕

    再次入冬入夏,雪兔们又出来觅食。。。。。。再次入冬,觅食。。。。。。入冬,觅食。。。。。。

    这样,50年后,雪地里基本上见不到五颜六色的雪兔了,这时候雪兔们达到了兔生巅峰!

    这就是遗传算法的理论基础,自然选择、交叉、变异、迭代,最终获得最优解。

    注意:算法是根据表现型来进行选择,最终选出最优的表现型及其对应的基因。

    1.2 算法要点

    1.1 编码

    编码是为了把我们的输入参数变成染色体(每个个体只有一条染色体),以便于进行交叉和遗传运算。

    例如我们把雪兔的颜色进行划分, 0-255 (表现型)代表 黑->白 的不同程度,0就是纯黑的,255就是纯白的。

    我们这里只谈一下简单的二进制编码,二进制编码中的每一个二进制位是一个基因,整个数字为染色体。

    那么0-255共有256阶(表现型),我们可以用8位2进制数来表示(基因型)。

    兔色为0的编码为 00000000,兔色为2的编码为 00000010,兔色为255的编码为 11111111。

    1.2 适应度函数

    适应度函数就是个体对环境的适应度,适应度越强的越能产生后代,保留自己的基因及表现型。

    这里,我们假设灰色兔子的适应能力最强,即兔色为128的兔子不会被吃掉,设定函数为:

    在这里插入图片描述

    是一个最大值为128的分段函数,图像如下:
    在这里插入图片描述
    适应度函数的极值点一般是未知的,这里我们为了演示方便,就先展示出来。

    1.3 基本流程

    流程就和雪兔故事一样简单,如下所示:

    在这里插入图片描述

    注意:迭代的终止条件可以不是最大迭代次数,比如规定为种群适应度值的方差小于某个值(即种群表现型趋于一致)。

    2. 代码实例(MATLAB)

    2.1 代码汇总

    遗传算法代码(通用代码):

    function [bestChromosome,fitnessBest]=GA(numOfChromosome,numOfGene,iterationNum)
    %% 函数功能:执行基于自适应遗传算法的卸载决策
    %   输入:
    %       numOfChromosome:染色体数量,即迭代的种群大小
    %       numOfGene:基因的数量,即所用二进制编码的位数
    %       iterationNum:迭代的总次数,达到迭代次数即终止迭代
    %   输出:
    %       bestChromosome:最优的染色体(即最优的输入)
    %       fitnessBest:最优的适应度值(即最优的结果)
    
    %% 随机生成初始种群,种群大小为numOfChromosome,染色体中基因数为numOfGene
    % lastPopulation:上一代的种群(染色体)
    % newPopulation:新一代的种群(染色体)
    % randi([0,1])会产生0或1的整数
    lastPopulation=randi([0,1],numOfChromosome,numOfGene);
    newPopulation=zeros(numOfChromosome,numOfGene);
    
    %% 进行遗传迭代,直至达到最大迭代次数iterationNum
    for iteration=1:iterationNum
        %% 计算所有个体(染色体)的适应度,一共有numOfChromosome个适应度值
        fitnessAll=zeros(1,numOfChromosome);
        for i=1:numOfChromosome
            individual=lastPopulation(i,:);
            fitnessAll(i)=fitnessFunc(individual);
        end
        
        %% 如果达到最大迭代次数,跳出(不能再进行选择遗传和变异了)
        if iteration==iterationNum
            break;
        end
        
        %% 使用轮盘赌法选择numOfChromosome条染色体,种群中个体总数不变
        fitnessSum=sum(fitnessAll);
        fitnessProportion=fitnessAll/fitnessSum;
        % 使用随机数进行numOfChromosome次选择,保持种群中个体数量不变
        for i=1:numOfChromosome
            probability=rand(1);
            proportionSum=0;
            chromosomeIndex=1;
            for j=1:numOfChromosome
                proportionSum=proportionSum+fitnessProportion(j);
                if proportionSum>=probability
                    chromosomeIndex=j;
                    break;
                end
            end
            newPopulation(i,:)=lastPopulation(chromosomeIndex,:);
        end
    
        %% 将染色体进行配对,执行单点交叉
        lastPopulation=newPopulation;
        % 生成从1到numOfChromosome的无序排列,每两个相邻数字进行配对
        coupleAllIndex=randperm(numOfChromosome);
        for i=1:floor(numOfChromosome/2)
            coupleOneIndex=coupleAllIndex(2*i-1:2*i);
            % 定义两条染色体交叉的概率,自己选择
            probability=0.6;
            % 如果生成的随机数在交叉概率内,执行交叉操作
            if rand(i)<probability
                % 随机生成交叉的基因点,将两条基因进行交叉
                crossPosition=randi([1,numOfGene],1);
                newPopulation(coupleOneIndex(1),crossPosition:end)=lastPopulation(coupleOneIndex(2),crossPosition:end);
                newPopulation(coupleOneIndex(2),crossPosition:end)=lastPopulation(coupleOneIndex(1),crossPosition:end);
            end
        end
    
        %% 对每条染色体执行基本位变异操作
        lastPopulation=newPopulation;
        for i=1:numOfChromosome
            % 定义染色体变异的概率,自己选择
            probability=0.2;
            % 如果生成的随机数在变异概率内,执行变异操作
            if rand(1)<probability
                % 选择变异的位置
                mutatePosition=randi([1,numOfGene],1);
                % 将对应基因位置的二进制数反转
                if(lastPopulation(i,mutatePosition)==0)
                    newPopulation(i,mutatePosition)=1;
                else
                    newPopulation(i,mutatePosition)=0;
                end
            end
        end 
        
        %% 完成了一次迭代,更新种群
        lastPopulation=newPopulation;
    end
    
    %% 遗传迭代结束后,获得最优适应度值和对应的基因
    fitnessBest=max(fitnessAll);
    bestChromosome=newPopulation(find(fitnessAll==fitnessBest,1),:);
    

    雪兔例子的适应度计算代码:

    function fitness=fitnessFunc(chromosome)
    %% 函数功能:计算染色体的表现型及其适应度
    % 输入:
    %       chromosome:染色体的基因序列
    % 输出:
    %       fitness:染色体(个体)的适应度值
    
    %% 计算雪兔染色体对应表现型
    len=length(chromosome);
    numList=2.^(len-1:-1:0);
    x=sum(chromosome.*numList);
    
    %% 计算表现型对应的适应度
    if x<128
        fitness=x;
    else
        if x>128
            fitness=256-x;
        else
            fitness=128;
        end
    end
    
    
    

    2.1 初始化种群

    %% 随机生成初始种群,种群大小为numOfChromosome,染色体中基因数为numOfGene
    % lastPopulation:上一代的种群(染色体)
    % newPopulation:新一代的种群(染色体)
    % randi([0,1])会产生0或1的整数
    lastPopulation=randi([0,1],numOfChromosome,numOfGene);
    newPopulation=zeros(numOfChromosome,numOfGene);
    

    这里使用随机数生成函数生成了numOfChromosome条染色体,每条染色体有numOfGene个基因。

    将生成的种群放入lastPopulation中,每一行是一条染色体。

    newPopulation相当于一个辅助数组,存储生成种群的中间结果。

    2.2 计算适应度

        %% 计算所有个体(染色体)的适应度,一共有numOfChromosome个适应度值
        fitnessAll=zeros(1,numOfChromosome);
        for i=1:numOfChromosome
            individual=lastPopulation(i,:);
            fitnessAll(i)=fitnessFunc(individual);
        end
    

    计算种群中所有个体的适应度,即把每一条染色体(个体)都放入适应度函数中,得到适应度结果。

    2.3 迭代终止判断

        %% 如果达到最大迭代次数,跳出(不能再进行选择遗传和变异了)
        if iteration==iterationNum
            break;
        end
    

    计算完适应度,如果达到终止条件,就不再进行选择、遗传和变异了。

    否则你跳出循环时,种群适应度与计算的的适应度不匹配。

    另一种方案:执行选择、遗传、变异,跳出循环后再次计算适应度即可。

    2.4 自然选择(轮盘赌法)

        %% 使用轮盘赌法选择numOfChromosome条染色体,种群中个体总数不变
        fitnessSum=sum(fitnessAll);
        fitnessProportion=fitnessAll/fitnessSum;
        % 使用随机数进行numOfChromosome次选择,保持种群中个体数量不变
        for i=1:numOfChromosome
            probability=rand(1);
            proportionSum=0;
            chromosomeIndex=1;
            for j=1:numOfChromosome
                proportionSum=proportionSum+fitnessProportion(j);
                if proportionSum>=probability
                    chromosomeIndex=j;
                    break;
                end
            end
            newPopulation(i,:)=lastPopulation(chromosomeIndex,:);
        end
    

    计算每个个体适应度占总适应度的比例,总适应度是一个饼图,每个个体占据一定的扇形区域。

    在这里插入图片描述

    然后生成numOfChromosome个0-1的随机数,随机数落在哪个区域,哪个个体便被生存,可重复选择。

    显然,适应度高的个体容易被选择,将自己的基因和表现型遗传下去。

    2.5 配对交叉(单点)

        %% 将染色体进行配对,执行单点交叉
        lastPopulation=newPopulation;
        % 生成从1到numOfChromosome的无序排列,每两个相邻数字进行配对
        coupleAllIndex=randperm(numOfChromosome);
        for i=1:floor(numOfChromosome/2)
            coupleOneIndex=coupleAllIndex(2*i-1:2*i);
            % 定义两条染色体交叉的概率,自己选择
            probability=0.6;
            % 如果生成的随机数在交叉概率内,执行交叉操作
            if rand(i)<probability
                % 随机生成交叉的基因点,将两条基因进行交叉
                crossPosition=randi([1,numOfGene],1);
                newPopulation(coupleOneIndex(1),crossPosition:end)=lastPopulation(coupleOneIndex(2),crossPosition:end);
                newPopulation(coupleOneIndex(2),crossPosition:end)=lastPopulation(coupleOneIndex(1),crossPosition:end);
            end
        end
    

    进行遗传的前提是配对,每两条染色体组合成一对,将两者的部分染色体进行交换。

    单点交叉,顾名思义,选择染色体上的一个基因点,从这个基因点开始的两条染色体片段互换:

    在这里插入图片描述

    2.6 变异(基本位变异)

        %% 对每条染色体执行基本位变异操作
        lastPopulation=newPopulation;
        for i=1:numOfChromosome
            % 定义染色体变异的概率,自己选择
            probability=0.2;
            % 如果生成的随机数在变异概率内,执行变异操作
            if rand(1)<probability
                % 选择变异的位置
                mutatePosition=randi([1,numOfGene],1);
                % 将对应基因位置的二进制数反转
                if(lastPopulation(i,mutatePosition)==0)
                    newPopulation(i,mutatePosition)=1;
                else
                    newPopulation(i,mutatePosition)=0;
                end
            end
        end 
    

    基本位变异就是选择一条染色体上的一个基因点,将其取反。

    如染色体 11111111,选择其第四个基因进行基本位变异, 新染色体变为 11101111

    2.7 获得最优解

    %% 遗传迭代结束后,获得最优适应度值和对应的基因
    fitnessBest=max(fitnessAll);
    bestChromosome=newPopulation(find(fitnessAll==fitnessBest,1),:);
    

    迭代结束之后,我们求出最大的适应度及其对应的染色体(个体),这就是我们需要的最优个体。

    2.8 雪兔遗传结果

    我们运行2.1给出的GA函数,在命令行输入以下代码运行:

    [bestChromosome,fitnessBest]=GA(40,8,60)
    

    40个染色体进行60次迭代。多次这行代码,发现结果可以不同,如下:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    虽然结果不尽相同,但都接近最优解128,这是遗传算法本身的局限,不一定能获得最优解。

    2.9 改善遗传算法的方法

    通过2.8我们知道,遗传算法有时候只能逼近最优解,那么有什么方法能让他达到更好的逼近效果呢?

    这里有几个方案:

    1. 使用自适应遗传和变异概率
    2. 增加种群中个体数量
    3. 增大迭代次数
    4. 使用双点交叉法
    5. 采用多样的变异方法
    6. 更改编码方式(某些情况)
    7. 更换适应度函数,将个体适应度的差距拉大
    8. 更换选择方法,轮盘赌法是最基本的方法,不科学

    大家可以自行了解,以后可能会继续就这几个方面探讨。

    3. 多多交流!

    展开全文
  • 利用遗传算法对建模自变量进行降维计算的matlab程序,欢迎下载参考
  • 基于MATLAB编写的遗传算法实例 可运算 (转)
  • 遗传算法的一个应用实例,采用matlab编写程序实现遗传算法
  • matlab vrp ga 遗传算法
  • matlab遗传算法路径优化代码实例,可供大家学习。同时带有注释,大家可根据自己需要进行学习
  • 遗传算法详解及matlab代码
  • 遗传算法(GA)是最著名的进化...在本文中,我们将与您分享遗传算法的两个版本的MATLAB实现:二进制遗传算法和实数编码遗传算法。这些版本中的优化机制是相同的,并且仅在解决方案表示形式和遗传算子的意义上有所不同。
  • 该代码包括遗传算法应用于函数优化和解决旅行商问题详细注释解析,以及本人做成的PPT。详细解析参考博客(https://blog.csdn.net/weixin_43935696/article/details/107045716)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 900
精华内容 360
关键字:

遗传算法matlab程序实例

matlab 订阅