标准粒子群优化算法 PSO
1、基本思想
粒子群算法通過(guò)設(shè)計(jì)一種無(wú)質(zhì)量的粒子來(lái)模擬鳥(niǎo)群中的鳥(niǎo),粒子僅具有兩個(gè)屬性:速度和位置,速度代表移動(dòng)的快慢,位置代表移動(dòng)的方向。每個(gè)粒子在搜索空間中單獨(dú)的搜尋最優(yōu)解,并將其記為當(dāng)前個(gè)體極值,并將個(gè)體極值與整個(gè)粒子群里的其他粒子共享,找到最優(yōu)的那個(gè)個(gè)體極值作為整個(gè)粒子群的當(dāng)前全局最優(yōu)解,粒子群中的所有粒子根據(jù)自己找到的當(dāng)前個(gè)體極值和整個(gè)粒子群共享的當(dāng)前全局最優(yōu)解來(lái)調(diào)整自己的速度和位置。下面的動(dòng)圖很形象地展示了PSO算法的過(guò)程:
2、更新規(guī)則
PSO初始化為一群隨機(jī)粒子(隨機(jī)解)。然后通過(guò)迭代找到最優(yōu)解。在每一次的迭代中,粒子通過(guò)跟蹤兩個(gè)“極值”(pbest,gbest)來(lái)更新自己。在找到這兩個(gè)最優(yōu)值后,粒子通過(guò)下面的公式來(lái)更新自己的速度和位置。?
基本粒子群優(yōu)化算法中的的更新是基于等式(1)和等式(2),等式(1)根據(jù)每個(gè)粒子
公式(1)的第一部分稱為【記憶項(xiàng)】,表示上次速度大小和方向的影響;公式(1)的第二部分稱為【自身認(rèn)知項(xiàng)】,是從當(dāng)前點(diǎn)指向粒子自身最好點(diǎn)的一個(gè)矢量,表示粒子的動(dòng)作來(lái)源于自己經(jīng)驗(yàn)的部分;公式(1)的第三部分稱為【群體認(rèn)知項(xiàng)】,是一個(gè)從當(dāng)前點(diǎn)指向種群最好點(diǎn)的矢量,反映了粒子間的協(xié)同合作和知識(shí)共享。粒子就是通過(guò)自己的經(jīng)驗(yàn)和同伴中最好的經(jīng)驗(yàn)來(lái)決定下一步的運(yùn)動(dòng)。以上面兩個(gè)公式為基礎(chǔ),形成了PSO的標(biāo)準(zhǔn)形式。
3、PSO算法的流程和偽代碼
4、PSO算法舉例
5、PSO算法的demo
#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;//維數(shù) const int p_num = 10;//粒子數(shù)量 const int iters = 100;//迭代次數(shù) 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; //定義粒子的歷史最優(yōu)位置和全局最優(yōu)位置 vector<double> p_best; double g_best; //使用eigen庫(kù)定義函數(shù)值矩陣和位置矩陣 Matrix<double, iters, p_num> f_test; Matrix<double, iters, p_num> pos_mat;//定義適應(yīng)度函數(shù) double fun_test(double x) {double res = x * x + 1;return res; }//初始化粒子群的位置和速度 void init() {//矩陣中所有元素初始化為極大值f_test.fill(inf);pos_mat.fill(inf);//生成范圍隨機(jī)數(shù)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]);//計(jì)算函數(shù)值//初始化函數(shù)值矩陣和位置矩陣f_test(0, i) = temp;pos_mat(0, i) = pos[i];p_best.push_back(pos[i]);//初始化粒子的歷史最優(yōu)位置}std::ptrdiff_t minRow, minCol;f_test.row(0).minCoeff(&minRow, &minCol);//返回函數(shù)值矩陣第一行中極小值對(duì)應(yīng)的位置g_best = pos_mat(minRow, minCol);//初始化全局最優(yōu)位置 }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];}//更新函數(shù)值矩陣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);//取函數(shù)值矩陣的每一列std::ptrdiff_t minRow, minCol;temp_test.minCoeff(&minRow, &minCol);//獲取每一列的極小值對(duì)應(yīng)的位置p_best[i] = pos_mat(minRow, i);//獲取每一列的極小值,即每個(gè)粒子的歷史最優(yōu)位置}g_best = *min_element(p_best.begin(), p_best.end());//獲取全局最優(yōu)位置}cout << fun_test(g_best); }int main() {init();PSO();system("pause");return 0; }?
總結(jié)
以上是生活随笔為你收集整理的标准粒子群优化算法 PSO的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux下生成源程序控制流图,Linu
- 下一篇: 初识SolrJ开发, schema.xm