%% 多元函数优化
clc, clear
close all
%% 画出函数图
figure(1);
lbx = -2; ubx = 2;
lby = -2; uby = 2;
ezmesh('x*cos(2*pi*y) + y*sin(2*pi*x)', [lbx, ubx, lby, uby], 50);
hold on;
%% 定义遗传算法参数
nind = 40; %种群大小
maxgen = 50; %最大遗传迭代次数
preci = 20; %个体长度
ggap = 0.95; %代沟
px = 0.7; %交叉概率
pm = 0.01; %变异概率
trace = zeros(3, maxgen); %寻优结果初始化
fieldd = [preci preci;lbx lby;ubx uby;1 1;0 0;1 1;1 1]; %区域描述器
chrom = crtbp(nind, preci * 2); %种群初始化(任意离散随机种群)
%% 优化
gen = 0; %代计数器
XY = bs2rv(chrom, fieldd); %初始种群二进制转十进制
X = XY(:, 1); Y = XY(:, 2);
objv = X .* cos(2*pi*Y) + Y .* sin(2*pi*X); %计算目标函数值
while gen < maxgen
fitnv = ranking(-objv); %分配适应度值
selch = select('sus', chrom, fitnv, ggap); %选择
selch = recombin('xovsp', selch, px); %交叉
selch = mut(selch, pm); %变异
XY = bs2rv(selch, fieldd); %子代个体十进制转换
X = XY(:, 1); Y = XY(:, 2);
objvsel = X .* cos(2*pi*Y) + Y .* sin(2*pi*X);
[chrom, objv] = reins(chrom, selch, 1, 1, objv, objvsel); %重插入子代到父代,得到新种群
XY = bs2rv(chrom, fieldd);
gen = gen + 1;
%获取每代的最优解及其序号,Y为最优解,i为个体的序号
[Y, i] = max(objv);
trace(1:2, gen) = XY(i, :);
trace(3, gen) = Y;
end
plot3(trace(1, :), trace(2, :), trace(3, :), 'bo'); %绘制每一代的最优点
grid on;
plot3(XY(:, 1), XY(:, 2), objv, 'b*');
hold off
%% 画进化图
figure(2);
plot(1 : maxgen, trace(3, :));
grid on;
xlabel('遗传代数')
ylabel('解的变化')
title('进化过程')
best_z = trace(3, end);
best_y = trace(2, end);
best_x = trace(1, end);
fprintf(['最优解:\nX=', num2str(best_x), '\nY=', num2str(best_y), '\nZ=', num2str(best_z), '\n'])
最优解:
X=1.7627
Y=-2
Z=3.7563
图一为目标函数图,圈为每代的最优价。图中可以看出,圈大都集中在一个点,这个点即为最优解。图中标出的最优点和程序计算的有偏差,这是因为图一画出的是函数的离散点,并不是全部。
图二所示是种群优化50代的进化图。(这边可以改最大迭代次数)
PS:图一还可以拉来拉去,好好玩(像吃的薄饼)