一、问题简述
给定一个函数表达式(二维或三维),求该函数的最值。
用粒子群算法解决此类问题。
二、代码
clear
clc
f = @(x1, x2) 20 + x1.^2 + x2.^2 - 10*cos(2*pi.* x1) - 10*cos(2*pi.* x2);
%初始种群个数
N = 20;
%可行解维数
d = 2;
%迭代次数
G = 100;
%位置参数限制
limit = [-5.12, 5.12];
%每次移动距离参数限制
vlimit = [-0.5, 0.5];
%给二维的参数x1,x2按一定精度划分下标,用于绘制函数图像
x_plot1 = limit(1) : 0.05 : limit(2);
x_plot2 = limit(1) : 0.05 : limit(2);
%用meshgrid函数使得x_plot1, x_plot2不再是原本的一一对应组合,而是一个数组中的每个都与另一个数组中的所有项组合
[X1, X2] = meshgrid(x_plot1, x_plot2);
Y = f(X1, X2);
%惯性权重
w = 0.8;
%自我学习粒子
c1 = 0.5;
%群体学习粒子
c2 = 0.5;
%初始化第一代种群的位置和速度
per = limit(1) + rand(N, d) * (limit(2) - limit(1));
v = vlimit(1) + rand(N, 1) * (vlimit(2) - vlimit(1));
%历代个体函数值最小的位置
perMinX = zeros(N, d);
%历代种群函数值最小的位置
popMinX = zeros(1, d);
%当前种群的函数值最小的位置
popNowMinX = zeros(1, d);
%历代个体的最小函数值
perMinY = ones(N, 1) * inf;
%历代种群的最小函数值
popMinY = inf;
%记录每代种群的最小函数值
popMinY_list = zeros(1, G);
for i = 1 : G
%找到并记录历代个体函数值最小的位置
index = find(f(per(:, 1), per(:, 2)) < perMinY);
perMinX(index, :) = per(index, :);
perMinY = f(perMinX(:, 1), perMinX(:, 2));
%计算当前代种群的最小函数值及其对应位置
[popNowMinY, index] = min(f(per(:, 1), per(:, 2)));
popNowMinX = per(index, :);
%将历代种群的最小函数值与当前代种群的最小函数值比较,得到新的历代种群最小函数值
if popNowMinY < popMinY
popMinX = popNowMinX;
popMinY = popNowMinY;
end
%计算下一代在上一代的基础上移动的方向和距离
v = v * w + c1 * rand * (perMinX - per) + c2 * rand * (repmat(popMinX, N, 1) - per);
%给移动距离划定界限
v(v < vlimit(1)) = vlimit(1);
v(v > vlimit(2)) = vlimit(2);
%移动得到下一代
per = per + v;
%给位置划定界限
per(per < limit(1)) = limit(1);
per(per > limit(2)) = limit(2);
%绘制函数图像与粒子的位置
subplot(1, 2, 1);
%绘制函数图像,mesh函数绘制曲面,view函数确定初始视角
mesh(X1, X2, Y),view(0,90);
hold on
%scatter3函数绘制三维图像中的点
scatter3(per(:, 1), per(:, 2), f(per(:, 1), per(:, 2)), 'r*');
hold off
%绘制每代种群的函数最小值图像
subplot(1, 2, 2);
popMinY_list(1, i) = popMinY;
plot(popMinY_list(1, 1 : i));
pause(0.5);
end
三、运行结果