PSO-PID算法迭代的PID值为什么变化范围那么小?

我用权重线性递减PSO-PID算法寻找最优的PID值,其参数设置如下:

Wmax=0.9;       % 最大权重
Wmin=0.4;       % 惯性因子 线性惯性权重 最小权重
c1 = 2;         % 个体学习因子1
c2 = 2;         % 社会学习因子2
Dim = 3;                      % 维数
SwarmSize = 100;              % 粒子群规模
ObjFun = @PSO_PIDdiscrete1;   % 待优化函数句柄
MaxIter = 300;                % 最大迭代次数  
MinFitness = 0.00001;         % 最小适应值 
Vmax = 1;               %速度更新限制范围
Vmin = -1;
Xmax = [10 100 10];     %位置更新限制范围
Xmin = [0 0 0];

仿真出来的结果如下面三张图所示:

 Kp值随迭代次数变化曲线

 

  Ki值随迭代次数变化曲线

  Kd值随迭代次数变化曲线

 明明我设置的X可变化范围那么大(代码最后两行),为什么每一次迭代它们三个的随机取值变化范围那么小?可以看下面三张图:

 Kp粒子取值

 Ki粒子取值 

  Kd粒子取值

 后面一两百代已经收敛了,不变化了我能理解,为了不让算法陷入局部最优,我用了权重线性递减的方法。

我的问题是怎么让它的PID随机取值变化范围变大?
需要改V速度的取值范围吗?但是它每一次的Vstep也没有超过[-1,1]这个范围。

请看到的大佬不吝赐教,这对我会有很大的帮助!
谢谢大家!


2024.01.20 19:20第一次更新

我怀疑是不是速度的上下限设置的太小了,所以导致所有的粒子不能飞太远,也就导致其随机取值范围变小了,于是我进行了以下尝试,改变速度的范围大小:

Vmax = 10;       %速度更新限制范围
Vmin = -10;

然后为了尽快验证我的猜想,减短仿真时间,用100个粒子只跑了100代,100代曲线后面也变化不大,这是-10~10跑出来的结果:

我简直震惊啊!全部都是0,还运行了我8459.246000s≈2.3h 。我觉得应该是这个范围(-10~10)太大了

于是我再改:

Vmax = 2;       %速度更新限制范围
Vmin = -2;

这是速度范围-2~2的迭代结果:

比之前要好,但是也是很快就固定到一个值然后再也没有变动过,应该是陷入了局部最优。或者这个速度范围还是取大了? 尤其是PSO整定的最优PID值分别取[0.123057559866944 ;0 ;0]肯定是不对的。因为知道肯定不对,我也就没有把这些值带回到simulink模型进行验证了。

我还要再试一下,把速度范围改回去效果会不会好一点?(尽管每一次都是随机初始化的,每一次仿真寻优都会有不同的结果)请期待我下一次更新!!!

现在已经不是每一次随机初始化的PID的变化不大的问题了,而是为什么很短的迭代次数内就像已经找到最佳的组合一样,每一次都生成相同的PID值了,慢慢来吧!


2024.01.21 9:50第二次更新

不好的消息,最佳PID参数全部都是0,和第一次的仿真条件一模一样(除了迭代次数),但是达不到第一次的效果了。

Vmax = 1;       %速度更新限制范围
Vmin = -1;

这是速度-1~1跑出来的结果:

 不应该啊,难道是速度初始化有问题吗?都是利用rand函数随机生成的,应该不会出什么岔子。

%% 粒子群初始化
Range = ones(SwarmSize,1)*(Ub-Lb);                              % 初始化范围
Swarm = rand(SwarmSize,Dim).*Range + ones(SwarmSize,1)*Lb       % 初始化粒子群
VStep = rand(SwarmSize,Dim)*(Vmax-Vmin) + Vmin                  % 初始化速度
fSwarm = zeros(SwarmSize,1);                                    % 初始化粒子群适应值

但我想不出还有什么地方会出错,我下一步要用均匀分布的方式随机生成初始化粒子,请期待我下一次更新!

%% 粒子群均匀随机生成初始化
Range = ones(SwarmSize,1)*(Ub-Lb);                        % 初始化范围
 for i = 1:SwarmSize
    for j = 1:Dim
        Swarm(i, j) = unifrnd(Lb(j), Ub(j));              % 使用均匀分布随机生成位置
        VStep(i, j) = unifrnd(Vmin, Vmax);                % 使用均匀分布随机生成速度
    end
end 
    fSwarm = zeros(SwarmSize,1);                          % 初始化粒子群适应值

2024.01.21 10:39第三次更新

好像找到原因了,应该是Simulink模型的反馈速度我多加了一个负号,之前那个模型是没有的。

为了验证我的猜想,是不是这里出错,我将这个-1的Gain模块去除,20个粒子迭代20代试一试,这是跑出来的结果:

可以清晰地看到每一张图片都有明显变化趋势,不像之前两次迭代出来的值都是0,那么这就验证了我的猜想,确实是Simulink模型出了一点小错误。也不是速度初始化的问题,之后对比rand初始化速度和均匀随机分布初始化速度我会另外出一篇文章,敬请期待!

那么回到本篇文章问题本身,是不是改变速度边界可以使得迭代PID值变化范围变大,下一次我将更新正确的模型,速度范围边界为-5~5的迭代结果。 


2024.01.21 15:05第四次更新

这是速度-5~5跑出来的结果:

 

 我觉得和第一次得出来的结果(最开始贴出来的三张图)没有什么大的区别,我计算了它们的取值范围区间(Max-Min),其计算结果如下:

KpKiKd
第一次0.46161.24481.6516
这一次01.17810.5379

如果单看变化范围,这一次的变化范围甚至还没有第一次变化得大呢,这还是在加大了速度的边界范围的前提下,所以不是单纯改变速度的边界范围就能改变最优PID粒子的取值范围的

让我们来梳理一下,最终的PID粒子取值是靠Swarm这个变量决定的,而Swarm初始化的公式如下:

%% 粒子群初始化
Range = ones(SwarmSize,1)*(Ub-Lb);                          % 初始化范围,因为它有多维参数
Swarm = rand(SwarmSize,Dim).*Range + ones(SwarmSize,1)*Lb   % 初始化粒子群,初始位置满足(-Ub,Ub)内均匀分布
VStep = rand(SwarmSize,Dim)*(Vmax-Vmin) + Vmin              % 初始化速度,初始速度满足(-Vmax,Vmax)内均匀分布

粒子群更新位置公式如下(就不考虑其位置会超出边界了,仿真那么多次还没有一次超出的):

%% 位置更新
Swarm(j,:)=Swarm(j,:)+VStep(j,:);

 这样我们就能稍微发现点问题了:

1)Swarm初始化大小和Range有关,而Range和PID取值位置边界有关,但是我们最初设置的PID参数取值范围,Kp和Kd是0~10,而Ki是0~100,为了更好地观察这个PID粒子取值与位置边界、速度边界的关系,接下来我把位置边界都设置成0~50(Ki也没有超过20);

2)如果想让Swarm的PID取值变化更加明显,可以从Vmin速度最小值设置入手,如果Vmin设置为0,那么Vstep只会取正值,PID值只会在初始化值的基础上增加,但这样是一种非常极端的做法,接下来不妨把Vmin的取值取得比较小一点

又或者是,确实人家那么多粒子也取到了其他变化范围比较大的点,但是一代那么多粒子表现得比较好的值,一代代这么迭代下就就是变化范围这么小,所以不是它变化范围小,而是最终它的效果不好,所以没有表现出来,我也就只能这么解释了。再做最后一次仿真验证吧。


 2024.01.22  9:15第五次更新

这一次仿真主要就是改变了以下参数,向前的速度比较大,而向后的速度设置得较小一点,以及位置的边界都设置得一样

Vmax = 5;       %速度更新限制范围
Vmin = -1;
Ub = [50 50 50]; %位置更新限制范围
Lb = [0 0 0];

以下是仿真出来的结果:

说实话得出来的结果是大差不差的,唯一一个改变的点是这次仿真进行了 32745.980857s≈9.1h时间远超前面几次仿真(我还在电脑面前傻傻地等以为只要仿真3小时差不多了,时间沉没成本啊!)

得到的较优PID值带回到Simulink模型后发现反馈曲线是这样子的:

也就是说得到的较优PID值是不能用的。 

所以结论是这个改变速度边界大小还是不能明显改变每次PID迭代的变化范围!暂且就这样吧!


总结

1)改变速度范围边界对迭代的PID值变化范围影响不大,如果你将向前的速度(Vmax)和向后的速度(Vmin)变化边界设置得差距比较大(比如一个5,一个-1),那么会大大增加matlab仿真的时间

2)如果想要得到一个比较精确的适合自己模型的PID值,需要提前知道PID值大概在哪个区间,再在这个区间进行迭代寻优的效果比较好,不然得出来的值带进去效果也不好。

All in all,

所以只解决了一个问题,排除了改变速度边界可以明显影响PID随机取值变化范围;

最本质的问题还是没有解决:怎么让它的PID随机取值变化范围变大?

欢迎各位在评论区积极讨论!!!


2024.7.28 20:52第六次更新

仔细想来,为什么在后期PID迭代曲线几乎没有什么变化,可能有两种说法:

1)迭代次数不够多,没有找到最优解就要迭代次数结束了;

2)陷入了局部最优解,这就是这个范围内最好的迭代结果了。

我也不去纠结“怎么让其迭代曲线变化大”的结果了。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hipipi39

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值