数学建模智能优化算法之遗传算法(GA)案例附Matlab代码

读书使人充实,讨论使人机智,笔记使人准确…。凡有所学,皆成性格。
———— (英国)培根

文章目录

遗传学与遗传算法术语表

遗传学术语遗传算法术语
群体可行解集
个体可行解
染色体可行解的编码
基因可行解编码的分量
基因形式遗传编码
适应度评价函数值
选择选择操作
交叉交叉操作
变异变异操作
Created with Raphaël 2.3.0 开始框 创建初始种群 适应度计算 满足终止准则? 输出最优个体 结束 选择操作 交叉操作 变异操作 yes no

关键参数说明

参数取值
群体规模 N p N_{p} Np一般 N p N_{p} Np取10~200
交叉概率 P c P_{c} Pc一般 P c P_{c} Pc取0.25~1.00
变异概率 P m P_{m} Pm通常 P m P_{m} Pm取0.001~0.1
遗传运算的终止进化代数 G G G G G G的取值可在100~1000之间

MATLAB仿真实例

[求最大值]用标准遗传算法求函数 f ( x ) = x + 10 s i n ( 5 x ) + 7 c o s ( 4 x ) f(x)=x+10sin(5x)+7cos(4x) f(x)=x+10sin(5x)+7cos(4x)的最大值,其中x的取值范围为[0,10]。这是一个有多个局部极值的函数,其函数值图形如图2.2所示,其MATLAB实现程序如下:

%%%%%%%%%%%%f(x)=x+10sin(5x)+7cos(4x)%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
x=0:0.01:10;
y=x+10*sin(5*x)+7*cos(4*x);
max_y=max(y);
max_x=x(find(y==max_y));
plot(x,y,max_x,max_y,'ro')
xlabel('x')
ylabel('f(x)')
title('f(×)=×+10sin(5×)+7cos(4x)')

仿真过程如下:

(1)初始化种群数目为 N p N_{p} Np=50,染色体二进制编码长度为L=20,最大进化代数为G=100,交叉概率为 P c P_{c} Pc=0.8,变异概率为 P m P_{m} Pm=0.1。(2)产生初始种群,将二进制编码转换成十进制,计算个体适应度值,并进行归一化;采用基于轮盘赌的选择操作、基于概率的交叉和变异操作,产生新的种群,并把历代的最优个体保留在新种群中,进行下一步遗传操作

在这里插入图片描述

(3)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。优化结束后,其适应度进化曲线如图所示,优化结果为x=7.8567,函数f(x)的最大值为24.86。

MATLAB源程序如下:

%%%%%%%%%%%%标准遗传算法求函数极值%%%%%%%%%%%%
%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%
clear all;      %清除所有变量
close all;      %种群数量
clc;            %清屏
NP=50;          %种群数量
L=20;           %二进制位串长度
Pc=0.8;          %交叉率
Pm=0.1;         %变异率
G=100;          %最大遗传代数
Xs=10;          %上限
Xx=0;           %下限
f=randi([0, 1], NP, L);  %随机获得初始种群
%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%
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)= funcl(x(i));
    end
    maxFit=max(Fit);         %最大值
    minFit=min(Fit);         %最小值
    rr= find (Fit==maxFit);
    fBest=f(rr(1,1),:);      %历代最优个体
    xBest=x(rr(1,1));
    Fit=(Fit- minFit)/( maxFit- minFit);    %归一化适应度值
    %%%%%%%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%%%%
    sum_Fit=sum(Fit);
    fitvalue=Fit./sum_Fit;
    fitvalue=cumsum(fitvalue);
    ms=sort(rand(NP,1));
    fiti=1;
    newi=1;
    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
xBest;                         %最优个体
figure
plot (trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%
function result=funcl(x)
fit =x+10*sin(5*x)+7*cos(4*x);
result=fit;
end

在这里插入图片描述

[求最小值]计算函数 f ( x ) = ∑ i = 1 n x i 2 ( − 20 ≤ x i ≤ 20 ) f(x)=\sum_{i=1}^nx_{i}^2\quad(-20 \leq x_{i} \leq 20) f(x)=i=1nxi2(20xi20)​ 的最小值,其中个体x的维数n=10。这是一个简单的平方和函数,只有一个极小点x=(0,0,…,0),理论最小值f(0,0,…,0)=0

:仿真过程如下:

(1)初始化种群数目为 N p N_{p} Np​=100,染色体基因维数为D=10,最大进化代数为G=1000,交叉概率为 P c P_{c} Pc​=0.8,变异概率为 P m P_{m} Pm​=0.1。

(2)产生初始种群,计算个体适应度值;进行实数编码的选择以及交叉和变异操作。选择和交叉操作采用“君主方案”,即在对群体根据适应度值高低进行排序的基础上,用最优个体与其他偶数位的所有个体进行交叉,每次交叉产生两个新的个体。在交叉过后,对新产生的群体进行多点变异产生子群体,再计算其适应度值,然后和父群体合并,并且根据适应度值进行排序,取前 N p N_{p} Np个个体为新群体,进行下一次遗传操作。

(3)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。

优化结束后,其适应度进化曲线如图所示,优化后的结果为x=[0.0003 -0.0037 0.0069 -0.0000 -0.0020 0.0001 -0.0009 0.0056 0.0052 0.0003],函数f(x)的最小值为1.24×10-4
在这里插入图片描述
MATLAB源程序如下:

%%%%%%%%%%%%实值遗传算法求函数极值%%%%%%%%%%%%
%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%
clear all;      %清除所有变量
close all;      %种群数量
clc;            %清屏
D=10;           %基因数目
NP=100;          %染色体数目
Pc=0.8;          %交叉率
Pm=0.1;         %变异率
G=1000;          %最大遗传代数
Xs=20;          %上限
Xx=-20;           %下限
f=zeros(D,NP);  %初始种群赋空间
nf=zeros(D,NP);   %子种群赋空间
f=rand(D,NP)*(Xs-Xx)+Xx;  %随机获得初始种群
%%%%%%%%%%%%%%%%%%按适应度升序排列%%%%%%%%%%%%%%%%%%
for np=1:NP
    FIT(np)= func2(f(:,np));
end
[SortFIT, Index]= sort(FIT);
Sortf=f(:, Index);
%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%
for gen =1:G
    %%%%%%%%%%%%%%%%%%采用君主方案进行选择交叉操作%%%%%%%%%%%%%
    Emper= Sortf(:,1); %君主染色体
    NoPoint=round (D*Pc); %每次交叉点的个数
    PoPoint=randi([1 D],NoPoint,NP/2); %交叉基因的位置
    nf=Sortf;
    for i= 1:NP/2
        nf(:,2*i-1)=Emper;
        nf(:,2*i)=Sortf(:,2*i);
        for k=1:NoPoint
            nf(PoPoint(k,i),2*i-1)=nf(PoPoint(k,i),2*i);
            nf(PoPoint(k,i),2*i)= Emper(PoPoint(k,i));
        end
    end
    %%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%
    for m=1:NP
        for n =1:D
            r=rand(1,1);
            if r<Pm
                nf(n,m)= rand(1,1)*(Xs-Xx)+Xx;
            end
        end
    end
    %%%%%%%%%%%%%%%%子种群按适应度升序排列%%%%%%%%%%%%%%%%
    for np=1: NP
        NFIT(np)= func2(nf(:,np));
    end
    [NSortFIT,Index]= sort(NFIT);
    NSortf=nf(:,Index);
    %%%%%%%%%%%%%%%%产生新种群%%%%%%%%%%%%%%%%%%%%%%%
    f1=[Sortf,NSortf];                    %子代和父代合并
    FIT1= [SortFIT, NSortFIT];   %子代和父代的适应度值合并
    [SortFIT1, Index]= sort(FIT1);    %适应度按升序排列
    Sortf1=f1(:,Index);            %按适应度排列个体
    SortFIT=SortFIT1(1:NP);        %取前NP个适应度值
    Sortf=Sortf1(:,1:NP);         %取前NP个个体
    trace(gen)= SortFIT(1);      %历代最优适应度值
end
Bestf=Sortf(:,1)            %最优个体
trace(end);                   %最优值
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%
function result=func2(x)
summ=sum(x.^2);
result=summ;
end

[旅行商问题](TSP)。假设有一个旅行商人要拜访全国31个省会城市,他需要选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。对路径选择的要求是:所选路径的路程为所有路径之中的最小值。全国31个省会城市的坐标为[1304 2312;3639 1315;4177 2244;37121399;3488 1535;3326 1556;3238 1229;4196 1004;4312 790;4386 570;3007 1970;2562 1756;2788 1491;2381 1676;1332695;3715 1678;3918 2179;4061 2370;3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2367;3394 2643;34393201;2935 3240;3140 3550;2545 2357;2778 2826;2370 2975]。

解:仿真过程如下:

(1)初始化种群数目为 N p N_{p} Np=200,染色体基因维数为N=31,最大进化代数为G=1000。

(2)产生初始种群,计算个体适应度值,即路径长度;采用基于概率的方式选择进行操作的个体;对选中的成对个体,随机交叉所选中的成对城市坐标,以确保交叉后路径每个城市只到访一次;对选中的单个个体,随机交换其一对城市坐标作为变异操作,产生新的种群,进行下一次遗传操作。

(3)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。
优化后的路径如图所示

在这里插入图片描述
其适应度进化曲线如图所示
在这里插入图片描述
MATLAB源程序如下:

%%%%%%%%%%%%%%%%%%%%%%%%%遗传算法解决TSP问题%%%%%%%%%%%%%%%%%%%%%%%
clear all;                      %清除所有变量
close all;                      %清图
clc;                            %清屏
C=[1304 2312;3639 1315;4177 2244;3712 1399;3488 1535;3326 1556;...
    3238 1229;4196 1044;4312  790;4386  570;3007 1970;2562 1756;...
    2788 1491;2381 1676;1332  695;3715 1678;3918 2179;4061 2370;...
    3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2376;...
    3394 2643;3439 3201;2935 3240;3140 3550;2545 2357;2778 2826;...
    2370 2975];                 %31个省会城市坐标
N=size(C,1);                    %TSP问题的规模,即城市数目
D=zeros(N);                     %任意两个城市距离间隔矩阵
%%%%%%%%%%%%%%%%%%%%%求任意两个城市距离间隔矩阵%%%%%%%%%%%%%%%%%%%%%
for i=1:N
    for j=1:N
        D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;
    end
end
NP=200;                          %种群规模
G=1000;                          %最大遗传代数
f=zeros(NP,N);                   %用于存储种群
F=[];                            %种群更新中间存储
for i=1:NP
    f(i,:)=randperm(N);          %随机生成初始种群
end
R=f(1,:);                        %存储最优种群
len=zeros(NP,1);                 %存储路径长度
fitness=zeros(NP,1);             %存储归一化适应值
gen=0;
%%%%%%%%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
while gen<G
    %%%%%%%%%%%%%%%%%%%%%计算路径长度%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    for i=1:NP
        len(i,1)=D(f(i,N),f(i,1));
        for j=1:(N-1)
            len(i,1)=len(i,1)+D(f(i,j),f(i,j+1));
        end
    end
    maxlen=max(len);              %最长路径
    minlen=min(len);              %最短路径
    %%%%%%%%%%%%%%%%%%%%%%%%%更新最短路径%%%%%%%%%%%%%%%%%%%%%%%%%%
    rr=find(len==minlen);
    R=f(rr(1,1),:);
    %%%%%%%%%%%%%%%%%%%%%计算归一化适应值%%%%%%%%%%%%%%%%%%%%%%%%%%
    for i=1:length(len)
        fitness(i,1)=(1-((len(i,1)-minlen)/(maxlen-minlen+0.001)));
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    nn=0;
    for i=1:NP
        if fitness(i,1)>=rand
            nn=nn+1;
            F(nn,:)=f(i,:);
        end
    end
    [aa,bb]=size(F);
    while aa<NP
        nnper=randperm(nn);
        A=F(nnper(1),:);
        B=F(nnper(2),:);
        %%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        W=ceil(N/10);              %交叉点个数
        p=unidrnd(N-W+1);          %随机选择交叉范围,从p到p+W
        for i=1:W
            x=find(A==B(p+i-1));
            y=find(B==A(p+i-1));
            temp=A(p+i-1);
            A(p+i-1)=B(p+i-1); 
            B(p+i-1)=temp;
            temp=A(x); 
            A(x)=B(y); 
            B(y)=temp;
        end
        %%%%%%%%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%%%%%%%%%
        p1=floor(1+N*rand());
        p2=floor(1+N*rand());
        while p1==p2
            p1=floor(1+N*rand());
            p2=floor(1+N*rand());
        end
        tmp=A(p1); 
        A(p1)=A(p2); 
        A(p2)=tmp;
        tmp=B(p1); 
        B(p1)=B(p2); 
        B(p2)=tmp;
        F=[F;A;B];
        [aa,bb]=size(F);
    end
    if aa>NP
        F=F(1:NP,:);             %保持种群规模为n
    end
    f=F;                         %更新种群
    f(1,:)=R;                    %保留每代最优个体
    clear F;
    gen=gen+1
    Rlength(gen)=minlen;
end
figure
for i=1:N-1
    plot([C(R(i),1),C(R(i+1),1)],[C(R(i),2),C(R(i+1),2)],'bo-');
    hold on;
end
plot([C(R(N),1),C(R(1),1)],[C(R(N),2),C(R(1),2)],'ro-');
title(['优化最短距离:',num2str(minlen)]);
figure
plot(Rlength)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')

[0-1背包问题]。有N件物品和一个容量为V的背包。第i件物品的体积是c(i),价值是w(i)。求解将哪些物品放入背包可使物品的体积总和不超过背包的容量,且价值总和最大。假设物品数量为10,背包的容量为300。每件物品的体积为[95,75,23,73,50,22,6,57,89,98],价值为[89,59,19,43,100,72,44,16,7,64]。

解:仿真过程如下:

(1)初始化种群数目为 N p N_{p} Np=50,染色体基因维数为L=10,最大进化代数为G=100。

(2)产生二进制初始种群,其中1表示选择该物品,0表示不选择该物品。取适应度值为选择物品的价值总和,计算个体适应度值,当物品体积总和大于背包容量时,对适应度值进行惩罚计算。

(3)对适应度进行归一化,采用基于轮盘赌的选择操作、基于概率的交叉和变异操作,产生新的种群,并把历代的最优个体保留在新种群中,进行下一步遗传操作。

(4)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。

优化结果为[1 0 1 0 1 1 1 0 0 1],1表示选择相应物品,0表示不选择相应物品,价值总和为388。

其适应度进化曲线如图所示

MATLAB源程序如下:

%%%%%%%%%%%%%%%遗传算法解决0-1背包问题%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%%%%%%%%
clear all;                       %清变量
close all;                       %清图
clc;                             %清屏
NP = 50;                         %种群规模
L = 10;                          %物品件数
Pc = 0.8;                        %交叉率
Pm = 0.05;                       %变异率
G = 100;                         %最大遗传代数
V = 300;                             %背包容量
C = [95,75,23,73,50,22,6,57,89,98];  %物品体积
W = [89,59,19,43,100,72,44,16,7,64]; %物品价值
afa = 2;                             %惩罚函数系数
f = randi([0,1],NP,L);               %随机获得初始种群
%%%%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%%
for k = 1:G
    %%%%%%%%%%%%%%%%%%适应度计算%%%%%%%%%%%%%%%%%
    for i = 1:NP
         Fit(i) = func4(f(i,:),C,W,V,afa);
    end
    maxFit = max(Fit);                          %最大值
    minFit = min(Fit);                          %最小值
    rr = find(Fit==maxFit);
    fBest = f(rr(1,1),:);                       %历代最优个体
    Fit = (Fit - minFit)/(maxFit - minFit);     %归一化适应度值
    %%%%%%%%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%%%%
    sum_Fit = sum(Fit);
    fitvalue = Fit./sum_Fit;
    fitvalue = cumsum(fitvalue);
    ms = sort(rand(NP,1));
    fiti = 1;
    newi = 1;
    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
    %%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%%%%%%
    for m = 1:NP
        for n = 1:L
            r = rand(1,1);
            if r < Pm
                nf(m,n) = ~nf(m,n);
            end
        end
    end
    f = nf;
    f(1,:) = fBest;                     %保留最优个体在新种群中
    trace(k) = maxFit;                  %历代最优适应度
end
fBest;                                  %最优个体
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%
function result = func4(f,C,W,V,afa)
fit = sum(f.*W);
TotalSize = sum(f.*C);
if TotalSize <= V
    fit = fit;
else
    fit = fit - afa * (TotalSize - V);
end
result = fit;
end

在这里插入图片描述

[1]包子阳 余继周 杨彬.智能优化算法及其MATLAB实例[M]电子工业出版社,2021

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值