粒子群优化算法
资料来源
粒子群优化算法_百度百科 (baidu.com)
简介
定义
粒子群优化算法(Particle Swarm optimization,PSO)又翻译为粒子群算法、微粒群算法、或微粒群优化算法。是通过模拟鸟群觅食行为而发展起来的一种基于群体协作的随机搜索算法。通常认为它是群集智能 (Swarm intelligence, SI) 的一种。它可以被纳入多主体优化系统(Multiagent Optimization System, MAOS)。
粒子群优化算法(PSO:Particle swarm optimization) 是一种进化计算技术(evolutionary computation)。源于对鸟群捕食的行为研究。粒子群优化算法的基本思想:是通过群体中个体之间的协作和信息共享来寻找最优解.
PSO的优势:在于简单容易实现并且没有许多参数的调节。目前已被广泛应用于函数优化、神经网络训练、模糊系统控制以及其他遗传算法的应用领域。
模拟捕食
PSO模拟鸟群的捕食行为。一群鸟在随机搜索食物,在这个区域里只有一块食物。所有的鸟都不知道食物在那里。但是他们知道当前的位置离食物还有多远。那么找到食物的最优策略是什么呢。最简单有效的就是搜寻离食物最近的鸟的周围区域。
启示
PSO从这种模型中得到启示并用于解决优化问题。PSO中,每个优化问题的解都是搜索空间中的一只鸟。我们称之为“粒子”。所有的粒子都有一个由被优化的函数决定的适应值(fitnessvalue),每个粒子还有一个速度决定他们飞翔的方向和距离。然后粒子们就追随当前的最优粒子在解空间中搜索。
PSO初始化
PSO初始化为一群随机粒子(随机解),然后通过迭代找到最优解,在每一次迭代中,粒子通过跟踪两个“极值”来更新自己。第一个就是粒子本身所找到的最优解,这个解叫做个体极值pBest,另一个极值是整个种群找到的最优解,这个极值是全局极值gBest。另外也可以不用整个种群而只是用其中一部分最优粒子的邻居,那么在所有邻居中的极值就是局部极值。
基本思想
粒子群算法通过设计一种无质量的粒子来模拟鸟群中的鸟,粒子仅具有两个属性:速度和位置,速度代表移动的快慢,位置代表移动的方向。每个粒子在搜索空间中单独的搜寻最优解,并将其记为当前个体极值,并将个体极值与整个粒子群里的其他粒子共享,找到最优的那个个体极值作为整个粒子群的当前全局最优解,粒子群中的所有粒子根据自己找到的当前个体极值和整个粒子群共享的当前全局最优解来调整自己的速度和位置。下面的动图很形象地展示了PSO算法的过程:
算法介绍
在找到这两个最优值时,粒子根据如下的公式来更新自己的速度和新的位置
(a)
(b)
v[] 是粒子的速度,present[] 是当前粒子的位置。pbest[] 和 gbest[] 如前定义。rand() 是介于(0,1)之间的随机数。c1,c2是学习因子。通常c1=c2=2。
PSO初始化为一群随机粒子(随机解)。然后通过迭代找到最优解。在每一次的迭代中,粒子通过跟踪两个“极值”(pbest,gbest)来更新自己。在找到这两个最优值后,粒子通过下面的公式来更新自己的速度和位置。
另一种解释:
公式(1)的第一部分称为【记忆项】,表示上次速度大小和方向的影响;公式(1)的第二部分称为【自身认知项】,是从当前点指向粒子自身最好点的一个矢量,表示粒子的动作来源于自己经验的部分;公式(1)的第三部分称为【群体认知项】,是一个从当前点指向种群最好点的矢量,反映了粒子间的协同合作和知识共享。粒子就是通过自己的经验和同伴中最好的经验来决定下一步的运动。以上面两个公式为基础,形成了PSO的标准形式。
伪代码实现
1 2 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
| For each particle
____Initialize particle
END
Do
____For each particle
________Calculate fitness value
________If the fitness value is better than the best fitness value (pBest) in history
____________set current value as the new pBest
____End
____Choose the particle with the best fitness value of all the particles as the gBest
____For each particle
________Calculate particle velocity according equation (a)
________Update particle position according equation (b)
____End While maximum iterations or minimum error criteria is not attained 在每一维粒子的速度都会被限制在一个最大速度Vmax,如果某一维更新后的速度超过用户设定的Vmax,那么这一维的速度就被限定为Vmax。
|
PSO算法案例
代码demo
1 2 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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| #include <iostream> #include <vector> #include <cmath> #include <map> #include <algorithm> #include <random> #include <ctime> #include <Eigen/Dense> using namespace Eigen; using namespace std;
const int dim = 1; const int p_num = 10; const int iters = 100; const int inf = 999999; const double pi = 3.1415;
const double v_max = 4; const double v_min = -2; const double pos_max = 2; const double pos_min = -1;
vector<double> pos; vector<double> spd;
vector<double> p_best; double g_best;
Matrix<double, iters, p_num> f_test; Matrix<double, iters, p_num> pos_mat;
double fun_test(double x) { double res = x * x + 1; return res; }
void init() { f_test.fill(inf); pos_mat.fill(inf); static std::mt19937 rng; static std::uniform_real_distribution<double> distribution1(-1, 2); static std::uniform_real_distribution<double> distribution2(-2, 4); for (int i = 0; i < p_num; ++i) { pos.push_back(distribution1(rng)); spd.push_back(distribution2(rng)); } vector<double> vec; for (int i = 0; i < p_num; ++i) { auto temp = fun_test(pos[i]); f_test(0, i) = temp; pos_mat(0, i) = pos[i]; p_best.push_back(pos[i]); } std::ptrdiff_t minRow, minCol; f_test.row(0).minCoeff(&minRow, &minCol); g_best = pos_mat(minRow, minCol); }
void PSO() { static std::mt19937 rng; static std::uniform_real_distribution<double> distribution(0, 1); for (int step = 1; step < iters; ++step) { for (int i = 0; i < p_num; ++i) { spd[i] = 0.5 * spd[i] + 2 * distribution(rng) * (p_best[i] - pos[i]) + 2 * distribution(rng) * (g_best - pos[i]); pos[i] = pos[i] + spd[i]; if (spd[i] < -2 || spd[i] > 4) spd[i] = 4; if (pos[i] < -1 || pos[i] > 2) pos[i] = -1; pos_mat(step, i) = pos[i]; } for (int i = 0; i < p_num; ++i) { auto temp = fun_test(pos[i]); f_test(step, i) = temp; } for (int i = 0; i < p_num; ++i) { MatrixXd temp_test; temp_test = f_test.col(i); std::ptrdiff_t minRow, minCol; temp_test.minCoeff(&minRow, &minCol); p_best[i] = pos_mat(minRow, i); } g_best = *min_element(p_best.begin(), p_best.end()); } cout << fun_test(g_best); }
int main() { init(); PSO(); system("pause"); return 0; }
|