下面是一个五维的粒子群算法求最大值,想问一下如果要求最小值要改哪些地方啊,初学者搞不懂了,谢谢大家
clc;clear;close all;
%% 初始化种群
f= @(a,b,c,d,e)(a.*b.*c.*d.*e); % 函数表达式
N = 500; % 初始种群个数
d = 5; % 空间维数
ger = 300; % 最大迭代次数
limit = [0, 20;0,20;0,20;0,20;0,20]; % 设置位置参数限制(矩阵的形式可以多维)
vlimit = [-1.5, 1.5;-1.5, 1.5;-1.5, 1.5;-1.5, 1.5;-1.5, 1.5]; % 设置速度限制
c_1 = 0.8; % 惯性权重
c_2 = 0.5; % 自我学习因子
c_3 = 0.5; % 群体学习因子
for i = 1:d
x(:,i) = limit(i, 1) + (limit(i, 2) - limit(i, 1)) * rand(N, 1);%初始种群的位置
end
v = rand(N, d); % 初始种群的速度
xm = x; % 每个个体的历史最佳位置
ym = zeros(1, d); % 种群的历史最佳位置
fxm = zeros(N, 1); % 每个个体的历史最佳适应度
fym = -inf; % 种群历史最佳适应度
iter = 1;
times = 1;
record = zeros(ger, 1); % 记录器
while iter <= ger
fx = f(x(:,1),x(:,2),x(:,3),x(:,4),x(:,5)) ; % 个体当前适应度
for i = 1:N
if fxm(i) < fx(i)
fxm(i) = fx(i); % 更新个体历史最佳适应度
xm(i,:) = x(i,:); % 更新个体历史最佳位置
end
end
if fym < max(fxm)
[fym, nmax] = max(fxm); % 更新群体历史最佳适应度
ym = xm(nmax, :); % 更新群体历史最佳位置
end
v = v * c_1 + c_2 * rand *(xm - x) + c_3 * rand *(repmat(ym, N, 1) - x);% 速度更新
% 边界速度处理
for i=1:d
for j=1:N
if v(j,i)>vlimit(i,2)
v(j,i)=vlimit(i,2);
end
if v(j,i) < vlimit(i,1)
v(j,i)=vlimit(i,1);
end
end
end
x = x + v;% 位置更新
% 边界位置处理
for i=1:d
for j=1:N
if x(j,i)>limit(i,2)
x(j,i)=limit(i,2);
end
if x(j,i) < limit(i,1)
x(j,i)=limit(i,1);
end
end
end
record(iter) = fym;%最大值记录
iter = iter+1;
times=times+1;
end
disp(['最大值:',num2str(fym)]);
disp(['变量取值:',num2str(ym)]);
-
-
(1)问题的matlab解决代码(%%%Original code:%%%标记了修改的部分)
clc;clear;close all;
%% 初始化种群
f= @(a,b,c,d,e)(a.*b.*c.*d.*e); % 函数表达式
N = 500; % 初始种群个数
d = 5; % 空间维数
ger = 300; % 最大迭代次数
limit = [0, 20;0,20;0,20;0,20;0,20]; % 设置位置参数限制(矩阵的形式可以多维)
vlimit = [-1.5, 1.5;-1.5, 1.5;-1.5, 1.5;-1.5, 1.5;-1.5, 1.5]; % 设置速度限制
c_1 = 0.8; % 惯性权重
c_2 = 0.5; % 自我学习因子
c_3 = 0.5; % 群体学习因子
for i = 1:d
x(:,i) = limit(i, 1) + (limit(i, 2) - limit(i, 1)) * rand(N, 1);%初始种群的位置
end
v = rand(N, d); % 初始种群的速度
xm = x; % 每个个体的历史最佳位置
ym = zeros(1, d); % 种群的历史最佳位置
fxm = inf*ones(N, 1); %%%Original code: fxm = zeros(N, 1);%%% % 每个个体的历史最佳适应度
fym = inf; %%%Original code: fym = -inf;%%% % 种群历史最佳适应度
iter = 1;
times = 1;
record = zeros(ger, 1); % 记录器
while iter <= ger
fx = f(x(:,1),x(:,2),x(:,3),x(:,4),x(:,5)) ; % 个体当前适应度
for i = 1:N
if fx(i)<fxm(i) %%%Original code: fxm(i) < fx(i)%%%
fxm(i) = fx(i); % 更新个体历史最佳适应度
xm(i,:) = x(i,:); % 更新个体历史最佳位置
end
end
if min(fxm)<fym %%%Original code: fym < max(fxm)%%%
[fym, nmin] = min(fxm); %%%Original code: [fym, nmax] = max(fxm);%%% % 更新群体历史最佳适应度
ym = xm(nmin, :); %%%Original code: ym = xm(nmax, :);%%% % 更新群体历史最佳位置
end
v = v * c_1 + c_2 * rand *(xm - x) + c_3 * rand *(repmat(ym, N, 1) - x);% 速度更新
% 边界速度处理
for i=1:d
for j=1:N
if v(j,i)>vlimit(i,2)
v(j,i)=vlimit(i,2);
end
if v(j,i) < vlimit(i,1)
v(j,i)=vlimit(i,1);
end
end
end
x = x + v;% 位置更新
% 边界位置处理
for i=1:d
for j=1:N
if x(j,i)>limit(i,2)
x(j,i)=limit(i,2);
end
if x(j,i) < limit(i,1)
x(j,i)=limit(i,1);
end
end
end
record(iter) = fym;%最大值记录
iter = iter+1;
times=times+1;
end
disp(['最小值:',num2str(fym)]); %%%Original code: disp(['最大值:',num2str(fym)]); %%%
disp(['变量取值:',num2str(ym)]);
(2)代码运行结果,不改变目标函数的话,原问题有多个最小解,只要任意一个分量等于0就是最小值解,题主也可以测试其它的目标函数,结果应该也是正确的。
以下是一个可能的正确代码实现
function [ym, fym, record]=PSO(fitness, N, maxgen, limit, vlimit, c_1, c_2, c_3)
% 参数说明:
% fitness:适应度函数,输入为[N, d]的粒子位置矩阵,输出为[N, 1]的适应度值矩阵
% N:粒子数目
% maxgen:最大迭代次数
% limit:每个变量的上下限范围,为[d,2]的矩阵,第一列为下限,第二列为上限
% vlimit:每个变量的速度上下限,为[d,2]的矩阵,第一列为下限,第二列为上限
% c_1、c_2、c_3:常数,分别代表自我认知、社会认知和群体历史认知的权重
d = size(limit, 1); % 变量维度
x = repmat(limit(:, 1)', N, 1) + rand(N, d).*repmat(limit(:, 2)' - limit(:, 1)', N, 1); % 初始位置
v = rand(N, d).*(repmat(vlimit(:, 2)' - vlimit(:, 1)', N, 1)*0.5) - repmat(vlimit(:, 2)' - vlimit(:, 1)', N, 1).*0.25; % 初始速度
fxm = zeros(N, 1); % 个体历史最佳适应度
xm = x; % 个体历史最佳位置
[fym, nmax] = max(fitness(x)); % 群体历史最佳适应度和位置
ym = x(nmax, :);
iter = 1;
record = zeros(1, maxgen); % 记录群体历史最佳适应度的变化
while iter <= maxgen
fx = fitness(x);
idx = fx > fxm;
fxm(idx) = fx(idx);
xm(idx,:) = x(idx,:);
if max(fx) > fym
[fym, nmax] = max(fx);
ym = x(nmax, :);
end
v = v * c_1 + c_2 * rand(N, 1).*(xm - x) + c_3 * rand(N, 1).*(repmat(ym, N, 1) - x);
v(v > vlimit(:, 2)) = vlimit(v > vlimit(:, 2), 2);
v(v < vlimit(:, 1)) = vlimit(v < vlimit(:, 1), 1);
x = x + v;
x(x > limit(:, 2)) = limit(x > limit(:, 2), 2);
x(x < limit(:, 1)) = limit(x < limit(:, 1), 1);
record(iter) = fym;
iter = iter + 1;
end
disp(['最大值:',num2str(fym)]);
disp(['变量取值:',num2str(ym)]);
end
一般我们不改算法,改目标函数。改成原来目标函数求负。
Matlab粒子群优化算法(PSO)求函数最大值(最小值)
可以借鉴下
https://blog.csdn.net/weixin_44897776/article/details/113686831