基于改进遗传算法的自抗扰控制器在四旋翼飞行器高度姿态上的应用改进与补充 2022.10.18(补充)
注:本文档由 MD 完成。仅为本人在现代测控技术课程中的一些记录和分享如需完整遗传算法、四旋翼飞行器、自抗扰控制器代码,本人提供无偿完整代码. by SJJ
先放结果
变 Pm 和 定 Pm 的结果:左上图为 遗传算法改进前后 的 最优个体 评价指标 (ITAE) 随迭代的下降曲线;左下图为 最优个体 适应度值 随迭代的上升曲线;右上图为不同基因变异策略下 每代变异次数 直方图;右下图为每代变异次数曲线以及 变异次数均值。
|
|
策略 | 变 Pm | 定 Pm |
---|---|---|
ITAE | 0.140808930973540 | 8.881842619988129 |
适应度值 | 7.101822252153414 | 0.112589250088522 |
beta01 | 801.6013760977735 | 809.8834479420645 |
beta02 | 5175.157037053104 | 5284.614615017952 |
beta03 | 8550.337824623948 | 5936.364635037471 |
beta1 | 4.265653715268949 | 207.3338962670779 |
beta2 | 20.221209401563210 | 32.092701530318490 |
策略 | 100代变异次数均值 | 变异次数方差(有效估计) | 变异次数方差(无偏差估计) |
---|---|---|---|
变 Pm | 14.060000000000000 | 3.363985731242034 | 3.380932869890657 |
定 Pm | 14.450000000000001 | 3.683408747342603 | 3.701965080135881 |
遗传算法改进前后 100 代变异次数的均值、方差(有效估计、无偏估计)如上表,可以看到在采用改进后的遗传算法对自抗扰控制器 5 个参数(染色体)进行寻优,评价指标优于采用传统的遗传算法,大大减小了 ITAE 并提高了种群个体的适应度值,通过较少的变异次数,形成更优个体。我认为是因为赋予个体不同基因变异阈值 在一定程度上 改进了传统遗传算法局部收敛,但是这样的结果并不具有普遍性,我运行了10次左右(图像我之后还得画),每次运行时间 1 min 30.51 s,变 Pm 策略不一定一直优于 定 Pm 策略,并且改进后的遗传算法也可能会发生早熟收敛和陷入局部最优。我想之后的实验中可以对遗传算法中的基因变异概率和交叉变异概率进行 自适应 改进。
针对一代中的每个个体,共有五条染色体,将五条染色体发生的变异总次数作为该个体的变异次数,绘制 100 代中每个个体的变异次数三维图像,纵坐标为个体变异次数。
|
|
流程分析与其他结果
由于需要验证不同策略(种群内个体 Pm 相等 与 不相等)下的个体的 基因变异次数 和对 自抗扰控制器寻优的影响,因此我把原来的 ADRC_GA 主程序作为 子程序 ADRCGAFunc,通过设计 主程序 main 输入不同 Pm值,得到每一代种群内个体的基因变异次数以及控制系统性能指标值。
首先定义一些变量用来存放数据:
变量名 | 描述 |
---|---|
mutationFlagMatrix | 存放 G 代 Size 个体的 CodeL 条染色体是否发生变异(三维) |
mutationRealMatrix | 存放 G 代 Size 个体的 CodeL 条染色体实际变异概率(三维) |
mutationModelMatrix | 每一代 Size 个体基因变异概率超参数(二维行向量) |
mutationTimes | 每一代的基因变异总次数(二维行向量) |
需要指出,我采用的 ITAE 计算公式为适应度函数 (Fitness Function) ,而对个体的适应度值的计算,需要对适应度函数的值取倒数作为个体的适应度值
f i t n e s s = ∫ 0 ∞ t ∣ e ( t ) ∣ d t fitness = \int_0^{\infty}t\mid e(t)\mid dt fitness=∫0∞t∣e(t)∣dt
多次运行变Pm和定Pm的程序,减少了结果的偶然性。得到100次基于遗传算法和改进遗传算法的自抗扰控制器参数寻优结果,共用时:147 min。但是头一天绷不住了:
- 失败记录:2022.10.17晚上 10:30 开始跑,凌晨00:57跑完了 100 次优化程序,数据保存 run3.mat,2022.10.18早上 8:30 还没跑完 200 次优化程序,但是导入 run3.mat ,发现有错(把矩阵初始化放在了 100 次循环的内部,俺是弱智_),白跑了一晚上,真的绷不住了。。。今早重新跑,用时 150min。
代码更新后,将 变Pm 和 定Pm 100 次优化适应度函数值 下降曲线 以及 适应度上升曲线 绘制如下:
|
|
|
|
左下和右下图可以看出,有些优化会陷入局部最优,表现为适应度值很低。
然后绘制 变Pm 和 定Pm 100 次(即不同 minibatch 下)优化的最优个体适应函数值和适应度值 柱状图 与 曲线图:789 101112
|
|
|
|
|
|
在 batch = 100 优化中,最优个体的适应度函数值和适应度值分别如下:
改进情况 | 适应度函数值 | 适应度值 |
---|---|---|
变 Pm | 0.002877718177498 | 347.4975 |
定 Pm | 0.001752984358488 | 570.4557 |
但是上表的结果只是找到最优的个体,不一定是在同一次优化中。因此需要对其进行数据分析,探究遗传算法改进前后的发生 早熟收敛 和 陷入局部最优 的情况,每次优化结果样本相对于 100次优化的偏离程度,采用方差与四分位差箱线图以及均值分析:
改进情况 | 方差(有效估计) | 方差(无偏估计) | 适应度函数值AVG | 适应度值AVG |
---|---|---|---|---|
变 Pm | 4.019306881439093 | 4.039555406977863 | 4.772027649549330 | 25.478872335327747 |
定 Pm | 3.753329485888940 | 3.772238066445802 | 4.725081091436540 | 31.486788663766117 |
|
|
其实上图表的结果,也并不能说我的改进型遗传算法是最优的,也就优化了一点点,也并不能防止 GA 陷入局部最优和抑制早熟收敛。还需要继续优化 GA
部分 main 代码:
%% main
clear
clc
close all
%% minibatch
batch = 100;
% BestfiMat 为所有 G 代中最优个体适应度值(n*1)
% BestJMat 为每一代最优个体的适应度函数值(n*100)
% Best_JMat 为所有 G 代中最优个体的适应度函数值(n*1)
% BestSMat 为迭代 G 代后的最优个体染色体值,即所要寻优的参数值(n*5)
% mutationFlagMatrixMat 存放 n 次循环的 100 代的 30 个体的 5 条染色体是否发生变异(30*5*100*n)
% mutationRealMatrixMat 存放 n 次循环的 100 代的 30 个体的 5 条染色体实际变异概率(30*5*100*n)
% mutationModelMatrixMat 存放 n 次循环的 100 代的 30 个体基因变异概率超参数(1*30*n)
% mutationTimesMatrixMat 存放 n 次循环的 100 代的变异次数(1*100*n)
% 设置循环存放矩阵
tuMat = zeros(2,1,batch);
BestfiMat = zeros(2,1,batch);
BestJMat = zeros(2,100,batch);
Best_JMat = zeros(2,1,batch);
BestSMat = zeros(2,5,batch);
mutationFlagMatrixMat = zeros(30,5,100,2,batch);
mutationRealMatrixMat = zeros(30,5,100,2,batch);
mutationModelMatrixMat = zeros(1,30,2,batch);
mutationTimesMatrixMat = zeros(1,100,2,batch);
%% n 为循环次数
for minibatch = 1:batch
minibatch
% 个体 Pm 不同
% 确定 Pm
for i = 1:2
if i == 1
Pm = 0.10-(1:1:30)*(0.01)/30;% 变 Pm,类似于自适应
mutationModelMatrixMat(:,:,i,minibatch) = Pm;
elseif i == 2
Pm = 0.095 * ones(1,30);% 固定 Pm
mutationModelMatrixMat(:,:,i,minibatch) = Pm;
else
disp('wrong')
break
end
[tu,Bestfi,BestJ,Best_J,BestS,mutationFlagMatrix,mutationRealMatrix,mutationTimesMatrix] = ADRCGAFunc(Pm);
tuMat(i,:,minibatch) = tu;
BestfiMat(i,:,minibatch) = Bestfi;
BestJMat(i,:,minibatch) = BestJ;
Best_JMat(i,:,minibatch) = Best_J;
BestSMat(i,:,minibatch) = BestS;
mutationFlagMatrixMat(:,:,:,i,minibatch) = mutationFlagMatrix;
mutationRealMatrixMat(:,:,:,i,minibatch) = mutationRealMatrix;
mutationTimesMatrixMat(:,:,i,minibatch) = mutationTimesMatrix;
% 输出结果
fprintf('\n最佳个体的适应度为: %f\n',BestfiMat(i,:,minibatch))
fprintf('\t\t其 ITAE 值为: %f\n',Best_JMat(i,:,minibatch))
fprintf('\t\t控制器参数寻优结果:%f,%f,%f,%f,%f\n',BestSMat(i,1,minibatch),BestSMat(i,2,minibatch),BestSMat(i,3,minibatch),BestSMat(i,4,minibatch),BestSMat(i,5,minibatch))
clear tu Bestfi BestJ Best_J BestS
end
end
clear i minibatch
以及 ADRCGAFunc 完整代码:
function [tu,Bestfi,BestJ,Best_J,BestS,mutationFlagMatrix,mutationRealMatrix,mutationTimesMatrix] = ADRCGAFunc(Pm)
%% INPUT
% Pm 个体基因变异概率值(1*30)
%% OUTPUT
% Bestfi 为所有 G 代中最优个体适应度值(1*1)
% BestJ 为每一代最优个体的适应度函数值(1*100)
% Best_J 为所有 G 代中最优个体的适应度函数值(1*1)
% BestS 为迭代 G 代后的最优个体染色体值,即所要寻优的参数值(1*5)
% mutationFlagMatrix 存放 100 代的 30 个体的 5 条染色体是否发生变异(30*5*100)
% mutationRealMatrix 存放 100 代的 30 个体的 5 条染色体实际变异概率(30*5*100)
% mutationModelMatrix 存放 100 代的 30 个体基因变异概率超参数(1*30)
% mutationTimesMatrix 存放每代的变异次数(1*100)
% 矩阵初始化
mutationFlagMatrix = zeros(30,5,100);
mutationRealMatrix = zeros(30,5,100);
mutationTimesMatrix = zeros(1,100);
%% ADRC-GA
global rin yout timef tu v1
tic
Size=30;
CodeL=5;
G=100; %代数
BsJ=0; %指标值
Bestfi_matrix_state = zeros(1,G);
BestJMatrix = zeros(1,G);
MinX(1)=100*ones(1);
MaxX(1)=1000*ones(1);
MinX(2)=zeros(1);
MaxX(2)=10000*ones(1);
MinX(3)=zeros(1);
MaxX(3)=10000*ones(1);
MinX(4)=zeros(1);
MaxX(4)=1000*ones(1);
MinX(5)=zeros(1);
% MaxX(5)=2*ones(1);
MaxX(5)=100*ones(1);
Beta(:,1)=MinX(1)+(MaxX(1)-MinX(1))*rand(Size,1);
Beta(:,2)=MinX(2)+(MaxX(2)-MinX(2))*rand(Size,1);
Beta(:,3)=MinX(3)+(MaxX(3)-MinX(3))*rand(Size,1);
Beta(:,4)=MinX(4)+(MaxX(4)-MinX(4))*rand(Size,1);
Beta(:,5)=MinX(5)+(MaxX(5)-MinX(5))*rand(Size,1);
%*************** Start Running ***************
for kg=1:1:G
time(kg)=kg;
%显示
fprintf('%d',kg)
%****** Step 1 : Evaluate BestJ ******
for i=1:1:Size
Betai=Beta(i,:);
[Betai,BsJ]=adrc_model(Betai,BsJ);
BsJi(i)=BsJ;
end
[OderJi,IndexJi]=sort(BsJi);% 这里是把30个体进行排序,sort 是从小到大排序
BestJ(kg)=OderJi(1);
BJ=BestJ(kg);
Ji=BsJi+1e-10; %Avoiding deviding zero 防止30个体逼近0 % 为啥?俺也不知道
fi=1./Ji;
[Oderfi,Indexfi]=sort(fi); %Arranging fi small to bigge
Bestfi=Oderfi(Size); %Let Bestfi=max(fi)
BestS=Beta(Indexfi(Size),:); %Let BestS=E(m), m is the Indexfi belong to max(fi)
%****** Step 2 : Select and Reproduct Operation******选择
fi_sum=sum(fi);
fi_Size=(Oderfi/fi_sum)*Size;
fi_S=floor(fi_Size); % Selecting Bigger fi value
r=Size-sum(fi_S);
Rest=fi_Size-fi_S;
[RestValue,Index]=sort(Rest);
for i=Size:-1:Size-r+1
fi_S(Index(i))=fi_S(Index(i))+1; % Adding rest to equal Size
end
k=1;
for i=Size:-1:1 % Select the Sizeth and Reproduce firstly
for j=1:1:fi_S(i)
TempE(k,:)=Beta(Indexfi(i),:); % Select and Reproduce
k=k+1; % k is used to reproduce
end
end
%************ Step 3 : Crossover Operation ************交叉
Pc=0.90;
for i=1:2:(Size-1)
temp=rand;
if Pc>temp %Crossover Condition
alfa=rand;
TempE(i,:)=alfa*Beta(i+1,:)+(1-alfa)*Beta(i,:);
TempE(i+1,:)=alfa*Beta(i,:)+(1-alfa)*Beta(i+1,:);
end
end
TempE(Size,:)=BestS;
Beta=TempE;
%************ Step 4: Mutation Operation **************变异
% 变异概率超参数设置
Pm_rand=rand(Size,CodeL);% 个体变异概率
mutationRealMatrix(:,:,kg) = Pm_rand;
Mean=(MaxX + MinX)/2;
Dif=(MaxX-MinX);
number = 0;
for i=1:Size
for j=1:CodeL
if Pm(i)>Pm_rand(i,j) %Mutation Condition
TempE(i,j)=Mean(j)+Dif(j)*(rand-0.5);
mutationFlagMatrix(i,j,kg) = 1;% 说明发生变异了
number = number + 1;
end
end
end
%Guarantee TempE(Size,:) belong to the best individual
TempE(Size,:)=BestS;
Beta=TempE;
mutationTimesMatrix(kg) = number;
end
tu;
Bestfi;%适应度值;
BestS;
Best_J=BestJ(G);
save GA_ADRC