一、问题简述

给定一个函数表达式求其最值。

用遗传算法解决该问题。

 

二、代码

1.主函数

clear
clc

f = @(x) abs(x .* sin(x) .* cos(2*x) - 2*x .* sin(3*x) + 3*x .* sin(4*x));
%迭代次数
G = 100;
%种群数量
popsize = 10;
%二进制串长度
chromlength = 20;
%交叉概率
pc = 0.8;
%变异概率
pm = 0.3;
%实际范围
xlim = [0, 50];

%第一代种群取随机数
pop = randi([0 1], popsize, chromlength);

%定义newpop用于保存半成品下一代
newpop = pop;

%初始化最大适应度矩阵
maxList = zeros(G, 2);

%计算第一代的适应度
dec = bintodec(newpop, popsize, chromlength, xlim);
fx = f(dec);
fitvalue = CalculateObject(fx);
%定义newfitvalue用于保存半成品下一代的适应度大小
newfitvalue = fitvalue;

%计算第一代适应度的最大值
[maxY, maxIndex] = max(fitvalue);
maxX = dec(maxIndex);
maxList(1, :) = [maxX, maxY];
plotfig(f, xlim, dec, fx, 1, maxList);

for i = 2 : G
    %选择、交叉、变异,得到半成品下一代
    newpop = select(newpop, pop, popsize, fitvalue);
    newpop = crossover(newpop,pc,popsize,chromlength);
    newpop = mutation(newpop,pm,popsize,chromlength);

    %计算半成品下一代的适应度,目的是筛选出真正的下一代
    dec = bintodec(newpop, popsize, chromlength, xlim);
    fx = f(dec);
    newfitvalue = CalculateObject(fx);

    %筛选出下一代
    index = find(newfitvalue > fitvalue);
    pop(index, :) = newpop(index, :);

    %计算真正下一代的适应度
    dec = bintodec(pop, popsize, chromlength, xlim);
    fx = f(dec);
    fitvalue = CalculateObject(fx);   %记录当前代的适应度
    
    %计算每一代的最大适应度数值和对应的自变量数值并保存在矩阵中
    [maxY, maxIndex] = max(fitvalue);
    maxX = dec(maxIndex);
    maxList(i, :) = [maxX, maxY];

    %绘制函数图像以及最大适应度图像
    plotfig(f, xlim, dec, fx, i, maxList);

end

2.选择函数

 

%选择操作
%pop与newpop都传入函数,根据上一代最终的pop对下一代刚开始进行筛选
function newpop = select(newpop, pop, popsize, fitvable)

i = 1; j = 1;

%根据适应度大小计算种群的分布,确保越高适应度的个体的数目越多
p = fitvable/sum(fitvable);

%cumsum函数表示对前缀进行累加
Cs = cumsum(p);
R = sort(rand(popsize, 1));

%循环新种群确定其分布
while j <= popsize
    if R(j) < Cs(i)
        newpop(j, :) = pop(i, :);
        j = j + 1;
    else
        i = i + 1;
    end
end

end

3.交叉函数

%交叉操作
function newpop = crossover(newpop,pc,popsize,chromlength)

for i = 2 : 2 : popsize
    rand1 = rand(1);
    if rand1 < pc
        %取两个随机数表示两个个体之间交换位置的区间
        randomInt1 = randi([1, chromlength]);
        randomInt2 = randi([1, chromlength]);
        
        %找到两个随机数的最大值与最小值
        randmin = min(randomInt1, randomInt2);
        randmax = max(randomInt1, randomInt2);

        %执行交换操作
        temp = newpop(i, randmin : randmax);
        newpop(i, randmin : randmax) = newpop(i - 1, randmin : randmax);
        newpop(i - 1, randmin : randmax) = temp;
        clear temp;
    end    
end
end

4.变异函数

%变异操作
function newpop = mutation(newpop,pm,popsize,chromlength)

for i = 1 : 1 : popsize
    %取0~1之间的随机数与变异概率比较,判断该个体是否要变异
    rand1 = rand(1);
    if rand1 < pm
        %随机选取一个变异位置
        rand2 = randi([1, chromlength]);
        newpop(i, rand2) = ~newpop(i, rand2);
    end
end 
end

5.二进制转换十进制函数

%二进制转化为十进制
function dec = bintodec(newpop, popsize, chromlength, xlim)

%初始化dec矩阵用于保存转化后的十进制数
dec = zeros(1, popsize);
index = chromlength - 1 : -1 : 0;
for i = 1 : popsize
    %计算二进制转化为十进制的数值,表示权重
    dec(1, i) = sum(newpop(i, :).* (2.^ index));
end 
%将权重除以总份数表示占总范围的比例
dec = xlim(1) + dec / (2 ^ chromlength - 1) * (xlim(2) - xlim(1));
end

6.表示适应度与函数值关系的函数

%表示适应度与函数值的关系
function fitvalue = CalculateObject(fx)

fitvalue = fx;
end

7.绘图函数

 %绘制函数图像以及最大适应度图像
function plotfig(f, xlim, dec, fx, i, maxList)

x = xlim(1) : 0.05 : xlim(2);
y = f(x);
subplot(1, 2, 1);
plot(x, y, dec, fx, 'o');
title(['第', num2str(i), '次迭代的函数图像']);



subplot(1, 2, 2);
iList = 1 : 1 : i;
plot(iList, maxList(1:i, 2));
title(['第', num2str(i), '次迭代的最大适应度图像']);
pause(0.5);
end

三、运行结果

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐