用遗传算法求函数最大值一:编码和适应值

下面使用一个具体的例子来解释遗传算法。

问题如下:

求函数
f(x)=9×sin(5x)+8×cos(4x), x∈[5,10]
的最大值。

设置参数

首先需要设定几个参数:

popsize         = 30;       % 种群规模
chromlength     = 10;       % 染色体长度
pc              = 0.5;      % 交叉概率
pm              = 0.05;     % 变异概率
maxgen          = 20;       % 最大迭代数

lx = 5; ux = 10;

上面分别设定了遗传算法的参数和自变量x的取值范围。

下面是对几个参数选取的说明:

参数 太大 太小 常用值
种群规模 难以收敛且浪费资源 近亲交配,产生病态基因 0~100
变异概率 可能破坏已有的有利模式 多样性下降太快,容易丢失有效基因 0.0001~0.2
交叉概率 可能破坏已有的有利模式 不能有效更新种群 0.4~0.99
进化代数 容易早熟后浪费资源 不容易收敛 100~500

初始化

初始化的种群是随机的,这里使用二进制对自变量进行编码,初始化子程序如下:

function pop = initpop(popsize, chromlength)
% 初始化种群,二进制编码
% popsize       input  种群规模
% chromlength   input  染色体长度
% pop           output popsize x chromelength的二进制矩阵
pop = round(rand(popsize, chromlength));
end

目标函数值

由于自变量采用二进制编码,因此需要首先将种群中的染色体从二进制转化为十进制。下面的子程序将二进制编码转换成十进制:

function rpop = decodebinary(pop)
% 将二进制矩阵中的每一行转化为十进制数
% pop   input  二进制矩阵
% rpop  output 十进制列向量
[n, l] = size(pop);
temp = zeros(l, 1);
for i = 1:l
    temp(i,1) = 2^(l-i);
end
rpop = pop * temp;
end

使用该函数对染色体进行解码:

function rpop = decodechrom(pop, spoint, length)
% 将每行中列为spoint : spoint+length-1的二进制矩阵转化为十进制数
% pop       input  种群
% spoint    input  开始位置
% length    input  长度
% rpop      output 十进制列向量
tpop = pop(:, spoint: spoint+length-1);
rpop = decodebinary(tpop);
end

decodechrom()decodebinary()的区别是,decodechrom()可以使用参数spointlength指定需要解码的列,而decodebinary()不行。

最后,使用下面的子程序求出目标函数值:

function [objvalue] = calobjvalue(pop, lx, ux)
% 计算目标函数值,需根据实际情况重写
% pop       input  种群
% lx        input  自变量最小值
% ux        input  自变量最大值
% objvalue  output 目标函数值
decchrom = decodechrom(pop, 1, size(pop, 2));  % 将二进制转化为十进制
x = decchrom / (2^size(pop ,2)-1) * (ux - lx) + lx;
objvalue = 9 * sin(5 * x) + 8 * cos(4 * x);
end

calobjvalue()函数首先将二进制解码为十进制,将解码后的数值对应到自变量变化范围,最后求出函数值。

适应值

f(x)为目标函数值,F(x)为适应值,这里采用下面的策略求适应值,但是此方法并不适用于所有情况,需要需根据实际情况重写:

对于最小化问题:


对于最大化问题:

下面是代码实现:

function fitvalue = calfitvalue(objvalue, opt)
% 根据目标函数值生成适应度值,需根据实际情况重写
% objvalue      input  目标函数值
% opt           input  操作模式,指定为'min'或'max'
% fitvalue      output 适应度值
fitvalue = zeros(size(objvalue,1), 1);
for i = 1 : size(objvalue, 1)
    if strcmp(opt, 'min')
        if objvalue(i) < 0
            temp = -objvalue(i);
        else
            temp = 0;
        end
    else
        if objvalue(i) > 0
            temp = objvalue(i);
        else
            temp = 0;
        end
    end
    fitvalue(i) = temp;
end
fitvalue = fitvalue';

发表评论

电子邮件地址不会被公开。 必填项已用*标注