matlab-day6

粒子群算法求解2020建模A题问题三的代码:

问题三代码(粒子种群算法)

main


%***************************************************************
%基于改进全局最优的粒子群算法求解第三问模型
%***************************************************************
%粒子群算法中的预设参数(参数的设置不是固定的,可以适当修改)
clc,clear;
n = 1000; % 粒子数量
narvs = 5; % 变量个数
%经过论文查找,专家给出建议为2左右最好
c1 = 2.05; % 每个粒子的个体学习因子,也称为个体加速常数
c2 = 2.05; % 每个粒子的社会学习因子,也称为社会加速常数
C = c1+c2; 
fai = 2/abs((2-C-sqrt(C^2-4*C))); % 收缩因子
w_max = 0.9; % 最大惯性权重,通常取0.9
w_min = 0.4; % 最小惯性权重,通常取0.4
K = 1000; % 迭代的次数
%查阅资料发现,最大速度为变量区间大小的10%或者20%是最优的
vmax = [10 6 6 6 6]; % 粒子的最大速度
%数度温度上下限约束
x_lb = [65 165 185 225 245]; % 变量的下界
x_ub = [100 185 205 245 265]; % 变量的上界
 
%初始化粒子的位置和速度
x = zeros(n,narvs);
for i = 1: narvs
x(:,i) = x_lb(i) + (x_ub(i)-x_lb(i))*rand(n,1); % 随机初始化粒子所在的位置在定义域内
end
v = -vmax + 2*vmax .* rand(n,narvs); % 随机初始化粒子的速度(这里我们设置为[-vmax,vmax])
%计算适应度
fit = zeros(n,1); % 初始化这n个粒子的适应度全为0
for i = 1:n % 循环整个粒子群,计算每一个粒子的适应度
array=x(i,:);
[l,current_x] = Process_Z(array);
if  l==1  %判断初始化的变量是否满足制程界限
[previous_tspan,previous_u]=PCB_T(current_x(1)/60, current_x(2),current_x(3),current_x(4),current_x(5),25);
dt=previous_tspan(2)-previous_tspan(1);
fit(i) = Area(previous_u,dt); % 调用目标函数来计算适应度
end
end
pbest = x; % 初始化这n个粒子迄今为止找到的最佳位置(是一个n*narvs的向量)
ind = find(fit == min(fit), 1); % 找到适应度最小的那个粒子的下标
gbest = x(ind,:); % 定义所有粒子迄今为止找到的最佳位置(是一个1*narvs的向量)
fitnessbest = ones(K,1); % 初始化每次迭代得到的最佳的适应度
for d = 1:K % 开始迭代,一共迭代K次
for i = 1:n % 依次更新第i个粒子的速度与位置
f_i = fit(i); % 取出第i个粒子的适应度
f_avg = sum(fit)/n; % 计算此时适应度的平均值
f_min= min(fit); % 计算此时适应度的最小值
if f_i >= f_avg 
if f_avg ~= f_min % 如果分母为0,我们就干脆令w=w_min
w = w_min + (w_max - w_min)*(f_i - f_min)/(f_avg - f_min);
else
w = w_min;
end
else
w = w_max;
end
v(i,:) = fai * (w*v(i,:) + c1*rand(1)*(pbest(i,:) - x(i,:)) + c2*rand(1)*(gbest - x(i,:))); % 更新第i个粒子的速度
x(i,:) = x(i,:) + v(i,:); % 更新第i个粒子的位置
% 如果粒子的位置超出了定义域,就对其进行调整
for j = 1: narvs
if x(i,j) < x_lb(j)
x(i,j) = x_lb(j);
elseif x(i,j) > x_ub(j)
x(i,j) = x_ub(j);
end
end
array=x(i,:);
[p,current_x] = Process_Z(array);
if p==1%判断更新后的变量是否满足制程界限
[previous_tspan,previous_u]=PCB_T(current_x(1)/60, current_x(2),current_x(3),current_x(4),current_x(5),25);
dt=previous_tspan(2)-previous_tspan(1);
fit(i) = Area(previous_u,dt); % 调用目标函数来计算适应度
end
array=pbest(i,:);
[p,current_x] = Process_Z(array);
if p==1
[previous_tspan,previous_u]=PCB_T(current_x(1)/60,current_x(2),current_x(3),current_x(4),current_x(5),25);
dt=previous_tspan(2)-previous_tspan(1);
end
if fit(i) < Area(previous_u,dt) % 如果第i个粒子的适应度小于这个粒子迄今为止找到的最佳位置对应的适应度
pbest(i,:) = x(i,:); % 那就更新第i个粒子迄今为止找到的最佳位置
end
array=gbest;
[p,current_x] = Process_Z(array);
if p==1%判断gbest中的变量是否满足制程界限
[previous_tspan,previous_u]=PCB_T(current_x(1)/60,current_x(2),current_x(3),current_x(4),current_x(5),25);
dt=previous_tspan(2)-previous_tspan(1);
end
if fit(i) < Area(previous_u,dt) % 如果第i个粒子的适应度小于所有的粒子迄今为止找到的最佳位置对应的适应度
gbest = pbest(i,:); % 那就更新所有粒子迄今为止找到的最佳位置
end
end
[p,current_x] = Process_Z(gbest);
 if p==1%判断gbest变量是否满足制程界限
[previous_tspan,previous_u]=PCB_T(gbest(1)/60,gbest(2),gbest(3),gbest(4),gbest(5),25);
dt=previous_tspan(2)-previous_tspan(1);
fitnessbest(d) = Area(previous_u,dt); % 更新第d次迭代得到的最佳的适应度
end
end
% 绘制最优炉温曲线
[tspan,uuu] = PCB_T(gbest(1)/60,gbest(2),gbest(3),gbest(4), gbest(5),25);
figure(1)
plot(tspan,uuu,'-k')
xlabel('时间/s')
ylabel('温度/℃')
title('粒子群算法-焊接中心温度曲线','position',[150,255])
%绘制纵坐标为(0,217℃)虚线用作比较。
hold on
plot(tspan,217*ones(length(tspan), 1),'--r','linewidth' ,2,'markeredgecolor' ,'k','markeredgecolor','b','markersize' ,8);
figure(2)
plot(fitnessbest)  % 绘制出每次迭代最佳适应度的变化图
xlabel('迭代次数');
%输出结果
disp('最优参数:'); disp(gbest)
[previous_tspan,previous_u]=problem2(gbest(1)/60, gbest(2),gbest(3),gbest(4),gbest(5),25);
dt=previous_tspan(2)-previous_tspan(1);
disp('最优面积是:'); disp(S(previous_u,dt))
Process_Z(粒子群算法制程约束)
%********************************************************
          %判断所生成的变量参数是否满足制程约束的函数
%*********************************************************
function [m,y]=Process_Z(x)
m=0;
y=0;
[tspan,u]=PCB_T(x(1)/60,x(2),x(3),x(4),x(5),25);
dt=tspan(2)-tspan(1);
 
%计算u(t)大于150,小于190的时间
a=find (u<190&u>150);
t1=max ((length(a)-2),1)*dt;
%计算u(t)大于217的时间
 
b=find (u>217);
t2=max ((length(b)-1), 1)*dt;
Tmax=max(u);
 
%计算各阶导数最大最小值
uu=(u(2:end)-u(1:end-1))/dt;
uumin=min(uu);
uumax=max(uu);
%判断新的参数是否满足题目的约束条件
if(uumin>-3)&&(uumax<3)&&(t1>60)&&(t1<120)&&(t2>40)&&(t2<90)&&(Tmax>240)&&(Tmax<250)
 y=x;
 m=1;
end
end

 PCB_T (焊接中心温度函数子程序)

%**********************************************
        %求解u(t)函数:代入参数求解u(t)
%*************************************************
function [tspan,T]=PCB_T(v,T15,T6,T7,T89,T1011)
dt=0.2;
tspan=0:dt:435.5/v;
Tair=Furance_T(tspan,v,T15,T6,T7,T89,T1011);
T=zeros (length(Tair),1);
T(1)=25;%电路板初始温度
for i=2: length(Tair)
k=kk(v*(i-1)*dt);
T(i)=-dt*(T(i-1)-Tair(i))*k+T(i-1) ;%2R#end
end
end

 Furance_T(炉内温度函数子程序)

 

%*************************************************
% 求解炉内环境温度T_AIR(T);
%ceil()函数的使用
%floor()函数的使用
%*****************************************************
function y=T_air(t,v,T15,T6,T7,T89,T1011)
y=ceil(heaviside(v*t)-heaviside(v*t-25)).*((T15-25)*exp(0.251*(v*t-25))+25)+...
floor(heaviside(v*t-25)-heaviside(v*t-197.5)).*T15+...
ceil(heaviside(v*t-197.5)-heaviside(v*t-202.5)).*(((T6-T15)/5)*(v*t-197.5)+T15)+...
floor(heaviside(v*t-202.5)-heaviside(v*t-233)).*T6+...
ceil(heaviside(v*t-233)-heaviside(v*t-238)).*(((T7-T6)/5)*(v*t-233)+T6)+...
floor(heaviside(v*t-238)-heaviside(v*t-268.5)).*T7+...
ceil(heaviside(v*t-268.5)-heaviside(v*t-273.5)).*(((T89-T7)/5)*(v*t-268.5)+T7)+...
floor(heaviside(v*t-273.5)-heaviside(v*t-339.5)).*T89+...
ceil(heaviside(v*t-339.5)-heaviside(v*t-380)).*(((T1011-T89)/96)*(v*t-339.5)+T89)+...
floor(heaviside(v*t-380)).*((((((25-T89)/96)*(380-339.5)+T89)-25)*exp(-0.00991*(v*t-380)))+25);

end

kk不同温度区下的冷却系数的设置)

 

%**********************************************************************
%不同温度区下的冷却系数不同,故而需要用位移判断所处温度区,选择合适的k值。
%**********************************************************************
function k=kk(x)

if x>=0&&x<=25

k=0.0185;

elseif 25<x&&x<=202.5
    k=0.0177;

elseif 202.5<x&&x<=238
    k=0.017;

elseif 238<x&&x<=273.5
    k=0.0247;

elseif 273.5<x&&x<=339.5
    k=0.0202;

else

    k=0.029;

end

おすすめ

転載: blog.csdn.net/qq_47541315/article/details/119641512