粒子群优化(Particle Swarm Optimization,PSO),又称微粒群算法
其重要的迭代用的公式是这条:
$v_i=v_i×w+c×rand()×(pbest_i+gbest- 2×x_i)$
其中:
$v_i$是速度
$w$是惯性因子((0,1)的实数),和学习因子相反,就是该粒子原来的速度的 参考权重 。比如我的这个程序里取的是0.5,而据说从大到小衰减会更好。因为大的时候会重视每个个体的价值,可以更全面的寻找可行解,而越趋于0就越注重社会的价值就是所有粒子中的最优解。
$C$是学习因子也就是权重一般取$2$。
我们可以通过这个速度向量来更新位置。
$ b[a].x += b[a].v; $
原理
PSO算法是基于群体的,根据对环境的适应度将群体中的个体移动到好的区域。然而它不对个体使用演化算子,而是将每个个体看作是D维搜索空间中的一个没有体积的微粒(点),在搜索空间中以一定的速度飞行,这个速度根据它本身的飞行经验和同伴的飞行经验来动态调整。第i个微粒表示为Xi= (xi1, xi2, …, xiD),它经历过的最好位置(有最好的适应值)记为Pi= (pi1, pi2, …, piD),也称为pbest。在群体所有微粒经历过的最好位置的索引号用符号g表示,即Pg,也称为gbest。微粒i的速度用Vi= (vi1, vi2, …, viD)表示。
引用自百度百科
粒子群优化算法流程图:

所以
对于这道题目我们先初始化他个$ 100 $个粒子,随机地在$ \begin{bmatrix}l,r\end{bmatrix} $区间里取x值,接着计算一下这个值对应的函数值且记录一下全局最优(更新时要用到)。
然后通过公式迭代他个$ 100 $次。
那就可以得到答案了。
一些更详细的内容都写在了代码里了。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 
 | #include <cstdio>#include <iostream>
 #include <cmath>
 #include <cstdlib>
 using namespace std;
 const int cnt=100;
 int n;
 double xs[15];
 double l,r;
 double f(double x) {
 double y = 0;
 for (int i=n+1; i>=1; i--) {
 y+=xs[n-i+2]*pow(x,i-1);
 }
 return y;
 }
 double Rand() {
 return (double)rand()/RAND_MAX;
 }
 struct node {
 double xv,x,y,besty,bestx;
 } b[105];
 
 
 double by=-1e233,bx;
 
 
 void update(int a) {
 
 
 b[a].xv=b[a].xv*0.5+Rand()*2*(bx+b[a].bestx-b[a].x*2);
 
 
 b[a].x+=b[a].xv;
 
 
 if (b[a].x<l) b[a].x=l,b[a].xv=b[a].xv*-1;
 if (b[a].x>r) b[a].x=r,b[a].xv=b[a].xv*-1;
 
 b[a].y=f(b[a].x);
 if (b[a].y>b[a].besty) {
 b[a].bestx=b[a].x;
 b[a].besty=b[a].y;
 }
 }
 
 int main() {
 scanf("%d%lf%lf",&n,&l,&r);
 for (int i=1; i<=n+1; i++) {
 scanf("%lf",&xs[i]);
 }
 srand(xs[1]+xs[n]);
 
 for (int i=1; i<=cnt; i++) {
 
 b[i].x=b[i].bestx=l+Rand()*(r-l);
 b[i].xv=0;
 b[i].y=b[i].besty=f(b[i].x);
 if (by<b[i].y) {
 bx=b[i].bestx;
 by=b[i].besty;
 }
 }
 
 for (int k=1; k<=100; k++) {
 for (int i=1; i<=cnt; i++) {
 
 update(i);
 if (by<b[i].besty) {
 
 bx=b[i].bestx;
 by=b[i].besty;
 }
 }
 }
 printf("%.5lf\n",bx);
 return 0;
 }
 
 |