主要内容

优化粒子群优化过程

方法进行优化particleswarm解算器。粒子群算法将称为群的粒子群移动到目标函数的最小值。群中每个粒子的速度根据三个因素变化:

  • 惯性的影响(InertiaRange选项)

  • 粒子所经过的最佳位置的吸引力(SelfAdjustmentWeight选项)

  • 对邻近粒子中最佳位置的吸引(SocialAdjustmentWeight选项)

这个例子展示了改变粒子群选项的一些效果。

何时修改选项

通常,particleswarm在使用默认选项时找到一个很好的解决方案。例如,它优化rastriginsfcn使用默认选项。这个函数有许多局部最小值,和一个全局最小值0在这一点上(0,0)

rng默认的再现率%[x,fval,exitflag,output] = particleswarm(@rastriginsfcn,2);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
formatstring ='particleswarm使用%d函数计算达到值%f。\n';流(formatstring fval output.funccount)
使用2560个函数评估,Particleswarm达到了0.000000的值。

对于这个函数,你知道最优目标值,所以你知道解算器找到了它。但是如果你不知道答案怎么办呢?评估解决方案质量的一种方法是重新运行求解器。

[x,fval,exitflag,output] = particleswarm(@rastriginsfcn,2);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fval output.funccount)
使用1480个函数评估,Particleswarm达到了0.000000的值。

解决方案和函数计算的数量都与前面的运行类似。这表明解算器在得到解时没有困难。

困难的目标函数使用默认参数

Rosenbrock函数是一个众所周知的难以优化的函数。这个例子使用了Rosenbrock函数的多维版本。函数的最小值为0在这一点上(1, 1, 1,……)

rng默认的再现率%Nvars = 6;%为nvars选择任意偶数有趣= @multirosenbrock;[x,fval,exitflag,output] = particleswarm(fun,nvars);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fval output.funccount)
使用12960个函数计算,Particleswarm的值达到3106.436648。

求解者没有找到一个很好的解。

绑定搜索空间

尝试限制空间,以帮助求解器找到一个好的点。

Lb = -10*ones(1,nvars);Ub = -lb;[xbounded,fvalbounded,exitflagbounded,outputbounded] = particleswarm(fun,nvars,lb,ub);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fvalbounded outputbounded.funccount)
使用71160个函数评估,Particleswarm的值达到0.000006。

求解者找到了一个更好的解。但这需要大量的函数求值。

改变选项

如果求解器更多地关注整个空间中的最佳邻域,而不是某个较小的邻域,它可能会更快地收敛。

选项= optimoptions(“particleswarm”“MinNeighborsFraction”1);[xn,fvaln,exitflagn,outputn] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fvaln outputn.funccount)
使用30180个函数计算,Particleswarm达到了0.000462的值。

虽然求解器使用了更少的函数求值,但尚不清楚这是由于随机性还是由于更好的选项设置。

也许你应该提高SelfAdjustmentWeight选择。

选项。SelfAdjustmentWeight = 1.9;[xn2,fvaln2,exitflagn2,outputn2] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fvaln2 outputn2.funccount)
使用18780个函数评估,Particleswarm的值达到0.000074。

这一次particleswarm需要更少的函数计算。这种改进是由于随机性,还是选项设置真的值得?重新运行求解器并查看函数求值的数量。

[xn3,fvaln3,exitflagn3,outputn3] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fvaln3 outputn3.funccount)
使用53040个函数计算,Particleswarm达到了0.157026的值。

这一次,函数计算的数量增加了。很显然,这SelfAdjustmentWeight设置不一定能提高性能。

提供一个起始点

也许particleswarm如果从一个已知点出发离解不太远,效果会更好。试试原点。让几个人在相同的起始点。它们的随机速度确保了它们不会保持在一起。

X0 = 0 (20,6);%设置20个个体作为行向量选项。InitialSwarmMatrix = x0;其余的蜂群是随机的。[xn3,fvaln3,exitflagn3,outputn3] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
流(formatstring fvaln3 outputn3.funccount)
使用32100个函数求值,得到的值为0.039015。

函数计算的数量再次减少。

矢量化速度

multirosenbrock函数允许向量化函数求值。这意味着它可以同时评估群中所有粒子的目标函数。这通常会大大加快求解器的速度。

rng默认的做一个公平的比较选项。UseVectorized = true;Tic [xv,fvalv,exitflagv,outputv] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
toc
运行时间为0.151691秒。
选项。UseVectorized = false;rng默认的Tic [xnv,fvalnv,exitflagnv,outputnv] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。
toc
运行时间为0.345724秒。

向量化计算的时间约为串行计算的一半。

绘制函数

您可以使用绘图函数查看求解器的进度。

选项= optimoptions(选项,“PlotFcn”, @pswplotbestf);rng默认的[x,fval,exitflag,output] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。

{

流(formatstring fval output.funccount)
使用24960个函数计算,得到的值为0.079755。

使用更多的颗粒

通常,使用更多的粒子可以得到更精确的解。

rng默认的选项。SwarmSize = 200;[x,fval,exitflag,output] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。

{

流(formatstring fval output.funccount)
使用169400函数评估,Particleswarm达到了0.000424。

混合函数

particleswarm可以通过几个吸引人的盆地来找到一个好的本地解决方案。然而,有时它并不能得到一个足够精确的局部最小值。尝试通过指定在粒子群算法停止后运行的混合函数来改进最终答案。将粒子数重置为原始值60,以查看混合函数产生的差异。

rng默认的选项。HybridFcn = @fmincon;选项。SwarmSize = 60;[x,fval,exitflag,output] = particleswarm(fun,nvars,lb,ub,options);
优化结束:目标值相对于上一个OPTIONS发生了变化。MaxStallIterations的迭代小于OPTIONS.FunctionTolerance。

{

流(formatstring fval output.funccount)
使用25191个函数评估,Particleswarm达到了0.000000的值。
disp (output.hybridflag)
1

虽然混合函数改善了结果,但plot函数显示的最终值与以前相同。这是因为图函数只显示了粒子群算法的迭代,而不是混合函数的计算。混合函数使得最终的函数值非常接近真实的最小值0。的output.hybridflagField显示fmincon以退出标志1停止,表示x是真正的局部极小值。

相关的话题