最优化算法与matlab应用5:遗传算法

最优化算法与matlab应用5:遗传算法
本文节选于王正林《精通MATLAB_科学计算》第2版

遗传算法GA是一种直接的随机搜索方法,它是在适者生存的自然进化过程中逐步建立的。算法原理类似于模拟退火,适用于寻找具有多个极值的目标函数的全局最小解。

算法步骤
在这里插入图片描述
在这里插入图片描述
交叉:交叉操作是遗传算法中最主要的遗传操作。通过交叉操作可以得到新一代个体,新个体组合了其父辈个体的特性。交叉体现了信息交换的思想。
变异:变异首先在群体中随机选择一个个体,对于选中的个体以一定的概率随机地改变串结构数据中某个串的值。变异发生的概率很低,通常取0.001-0.01之间。

Matlab调用函数
function [xo,fo] = genetic(f,x0,l,u,Np,Nb,Pc,Pm,eta,kmax)
%f为待求函数,x0初值,l,u上下限,Np群体大小,Nb每一个变量的基因值(二进制数)
%Pc交叉概率,Pm变异概率,eta学习率,kmax最大迭代次数

主程序文件:

function [xo,fo] = genetic(f,x0,l,u,Np,Nb,Pc,Pm,eta,kmax)
% 基因算法求f(x)最小值 s.t. l <= x <= u
%f为待求函数,x0初值,l,u上下限,Np群体大小,Nb每一个变量的基因值(二进制数)
%Pc交叉概率,Pm变异概率,eta学习率,kmax最大迭代次数
N = length(x0);
%%%%%确定各变量缺省值
if nargin < 10
    kmax = 100; %最大迭代次数缺省为100
end
if nargin < 9|eta > 1|eta <= 0
    eta = 1;  %学习率eta,(0 < eta < 1)
end
if nargin < 8
    Pm = 0.01; %变异概率缺省0.01
end
if nargin < 7
    Pc = 0.5; %交叉概率缺省0.5
end
if nargin < 6
    Nb = 8*ones(1,N);%每一变量的基因值(二进制数)
end
if nargin < 5
    Np = 10; %群体大小(染色体数)
end
%%%%%生成初始群体
NNb = sum(Nb);
xo = x0(:)'; l = l(:)'; u = u(:)';
fo = feval(f,xo);
X(1,:) = xo;
for n = 2:Np
    X(n,:) = l + rand(size(x0)).*(u - l); %初始群体随机数组
end
P = gen_encode(X,Nb,l,u);  %编码为2进制字串
for k = 1:kmax
    X = gen_decode(P,Nb,l,u);  %解码为10进制数
    for n = 1:Np
        fX(n) = feval(f,X(n,:));
    end
    [fxb,nb] = min(fX);   %选择最适合的,函数值最小的
    if fxb < fo
        fo = fxb;
        xo = X(nb,:);
    end
    fX1 = max(fxb) - fX; %将函数值转化为非负的适合度值
    fXm = fX1(nb);
    if fXm < eps  %如果所有的染色体值相同,终止程序
        return;
    end
    %%%%%复制下一代
    for n = 1:Np
        X(n,:) = X(n,:) + eta*(fXm - fX1(n))/fXm*(X(nb,:) - X(n,:));%复制准则
    end
    P = gen_encode(X,Nb,l,u); %对下一代染色体编码
    %%%%%%随机配对/交叉得新的染色体数组
    is = shuffle([1:Np]);
    for n = 1:2:Np - 1
        if rand < Pc
            P(is(n:n + 1),:) = crossover(P(is(n:n + 1),:),Nb);
        end
    end
    %%%%%%变异
    P = mutation(P,Nb,Pm);
end
function P = gen_encode(X,Nb,l,u)
%将群体X的状态编码为二进制数组P
Np=size(X,1); %群体大小
N = length(Nb); %变量(状态)维数
for n = 1:Np
    b2 = 0;
    for m = 1:N
        b1 = b2+1;
        b2 = b2 + Nb(m);
        Xnm =(2^Nb(m)- 1)*(X(n,m) - l(m))/(u(m) - l(m)); %编码方程
        P(n,b1:b2) = dec2bin(Xnm,Nb(m)); %10进制转换为2进制
    end
end
function X = gen_decode(P,Nb,l,u)
% 将二进制数组P解码为群体X的状态矩阵
Np = size(P,1); %群体大小
N = length(Nb); %变量维数
for n = 1:Np
    b2 = 0;
    for m = 1:N
        b1 = b2 + 1;
        b2 = b1 + Nb(m) - 1;
        X(n,m) = bin2dec(P(n,b1:b2))*(u(m) - l(m))/(2^Nb(m) - 1) + l(m); %解码方程
    end
end
function chrms2 = crossover(chrms2,Nb)
%两个染色体间的交叉
Nbb = length(Nb);
b2 = 0;
for m = 1:Nbb
    b1 = b2 + 1;
    bi = b1 + mod(floor(rand*Nb(m)),Nb(m));
    b2 = b2 + Nb(m);
    tmp = chrms2(1,bi:b2);
    chrms2(1,bi:b2) = chrms2(2,bi:b2);
    chrms2(2,bi:b2) = tmp;
end
function P = mutation(P,Nb,Pm)
%变异
Nbb = length(Nb);
for n = 1:size(P,1)
    b2 = 0;
    for m = 1:Nbb
        if rand < Pm
            b1 = b2 + 1;
            bi = b1 + mod(floor(rand*Nb(m)),Nb(m)); 
            b2 = b2 + Nb(m);
            P(n,bi) = ~P(n,bi);
        end
    end
end
function is = shuffle(is)
%打乱染色体次序
N = length(is);
for n = N:-1:2
    in = ceil(rand*(n - 1));
    tmp = is(in);is(in) = is(n); is(n) = tmp; %将第n个元素与第in个元素交换
end

实例:
求解无约束最优化问题。

在这里插入图片描述

f = inline('x(1)^4-16*x(1)^2-5*x(1)*x(2)+x(2)^4-16*x(2)^2-5*x(2)','x');
l = [-5 -5]; %下限
u = [5 5]; %上限
x0 = [0 0];
Np = 30; %群体大小
Nb = [12 12]; %代表每个变量的二进制位数
Pc = 0.5;  %交叉概率
Pm = 0.01; %变异概率
eta = 0.8;   %学习率
kmax = 200; %最大迭代次数
[xos,fos]=fminsearch(f,x0)
[xo_gen,fo_gen] = genetic(f,x0,l,u,Np,Nb,Pc,Pm,eta,kmax)
发布了55 篇原创文章 · 获赞 80 · 访问量 3775

猜你喜欢

转载自blog.csdn.net/wjyxld/article/details/105392045