[未答复] 请问有人可以帮我看一下为什么遗传算法的结果不太正确吗

[复制链接]
suzuka 发表于 2021-4-7 16:40:21
大四在写毕业论文,系统的数学模型是 G(s)H(S)=(0.01s^2+0.926)/(7.69s^3+22000s^2+2100s+1)这样的,编写了遗传算法希望可以取得使用PID时最佳的参数(实数编码方式),但是结果不但遗传算法到最后仍然存在较大的误差,而且得出的参数带入simulink建立的PID模型中得到的响应曲线也远远称不上最优,请问有人可以帮我看一下问题出在哪里吗,下面是代码
%用于优化PID参数的遗传算法
clear all;
close all;
global rin yout timef
Size=30;
CodeL=3;

MinX(1)=1*ones(1);
MaxX(1)=5000*ones(1);
MinX(2)=zeros(1);
MaxX(2)=0.5*ones(1);
MinX(3)=zeros(1);
MaxX(3)=zeros(1);

%产生初始种群
Kpid(:,1)=MinX(1)+(MaxX(1)-MinX(1))*rand(Size,1);
Kpid(:,2)=MinX(2)+(MaxX(2)-MinX(2))*rand(Size,1);
Kpid(:,3)=MinX(3)+(MaxX(3)-MinX(3))*rand(Size,1);

G=500;
BsJ=0;

%*************** 开始运行 ***************
for kg=1:1:G
    time(kg)=kg;

%****** 步骤 1 : 产生 BestJ ******
for i=1:1:Size
Kpidi=Kpid(i,:); %代入PID参数

[Kpidi,BsJ]=chap5_3f(Kpidi,BsJ);%调用PID系统模型函数

BsJi(i)=BsJ; %取出最优值
end

[OderJi,IndexJi]=sort(BsJi);
BestJ(kg)=OderJi(1); %取出第KG次时的Best J
BJ=BestJ(kg);
Ji=BsJi+1e-10;    %避免除0运算

   fi=1./Ji;
   [Oderfi,Indexfi]=sort(fi);     %从小到大排列fi
   Bestfi=Oderfi(Size);       %令 Bestfi=max(fi)
   BestS=Kpid(Indexfi(Size),:);  %令 BestS=E(m), m 是 max(fi) 的索引 筛选出在世代群体中的最优Kpid

   kg   
   BJ
   BestS      %输出本世代是第几世代,最佳指标和最佳Kpid
%****** 步骤 2 : 选择与新种群产生 ******
   fi_sum=sum(fi); %适应度求和
   fi_Size=(Oderfi/fi_sum)*Size; %计算本世代每个个体适应度

   fi_S=floor(fi_Size);                   % 向下取整运算
   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;     % 使得种群大小保持不变?
   end

   k=1;
   for i=Size:-1:1
      for j=1:1:fi_S(i)  
       TempE(k,:)=Kpid(Indexfi(i),:);       % 选择与生成新个体
         k=k+1;                           % k 用来生成新个体
      end
   end

%************ 步骤 3 : 交叉运算 ************
    Pc=0.90;
    for i=1:2:(Size-1)
          temp=rand;
      if Pc>temp                      %交叉条件
          alfa=rand;
          TempE(i,:)=alfa*Kpid(i+1,:)+(1-alfa)*Kpid(i,:);  
          TempE(i+1,:)=alfa*Kpid(i,:)+(1-alfa)*Kpid(i+1,:);
      end
    end
    TempE(Size,:)=BestS;
    Kpid=TempE;             %将新一代的数值替换上一代的数值

%************ 步骤 4: 变异运算 **************
Pm=0.1-[1:1:Size]*(0.01)/Size;       %具有更大 fi的个体具有更小的 Pm
Pm_rand=rand(Size,CodeL);
Mean=(MaxX + MinX)/2;
Dif=(MaxX-MinX);

   for i=1:1:Size
      for j=1:1:CodeL
         if Pm(i)>Pm_rand(i,j)       %变异条件
            TempE(i,j)=Mean(j)+Dif(j)*(rand-0.5);
         end
      end
   end
%保证 TempE(Size,:) 为最优个体
   TempE(Size,:)=BestS;      
   Kpid=TempE;
end
Bestfi
BestS
Best_J=BestJ(G)
figure(1);
plot(time,BestJ);
xlabel('Times');ylabel('Best J');
figure(2);
plot(timef,rin,'r',timef,yout,'b');
xlabel('Time(s)');ylabel('rin,yout')






下面是子函数(PID模拟)
function [Kpidi,BsJ]=chap5_3f(Kpidi,BsJ)
global rin yout timef

ts=1
sys=tf([0.0105,0,0.926],[7.69,22000,2100,1]);  
dsys=c2d(sys,ts,'z');
[num,den]=tfdata(dsys,'v');

rin=1.0;             %赋初值
u_1=0.0;u_2=0.0;u_3=0.0;
y_1=0.0;y_2=0.0;y_3=0.0
x=[0,0,0]';
B=0;
error_1=0;
tu=1;
s=0;
P=1000;

for k=1:1:P
   timef(k)=k*ts;
   r(k)=rin;  
   u(k)=Kpidi(1)*x(1)+Kpidi(2)*x(2)+Kpidi(3)*x(3);  %计算输出值
   if u(k)>=10         
      u(k)=10;
   end
   if u(k)<=-10
      u(k)=-10;
   end   
   yout(k)=-den(2)*y_1-den(3)*y_2-den(4)*y_3+num(1)*u(k)+num(2)*u_1+num(3)*u_2+num(4)*u_3;
   error(k)=r(k)-yout(k);        %误差
%------------计算PID参数 -------------
   u_3=u_2;u_2=u_1;u_1=u(k);
   y_3=y_2;y_2=y_1;y_1=yout(k);

   x(1)=error(k);               %计算P
   x(2)=(error(k)-error_1)/ts;     % 计算D
   x(3)=x(3)+error(k)*ts;         % 计算 I

   error_2=error_1;
   error_1=error(k);
if s==0
   if yout(k)>0.95&yout(k)<1.05
      tu=timef(k);
      s=1;
   end
end
end

for i=1:1:P
   Ji(i)=error(i)^2 +rand*u(i)^2; %算法性能指标
   B=B+Ji(i);   %计算总偏差值
end
BsJ=B;


谢谢各位dalao了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

相关帖子
热门教程
站长推荐
快速回复 返回顶部 返回列表