【复习档】群智能算法-粒子群算法

粒子群优化算法-Particle Swarm Optimization

背景

Kennedy和Eberhart于1995年提出。
特点:简单易行;收敛速度快;设置参数少。

核心

信息的社会共享。生物学对鸟/鱼群捕食的行为研究:社会行为(Social-Onlyl Model)+个体认知(Cognition-Only Model)

问题

问题的解被想象为一只鸟,称为“粒子”。
所有粒子都在一个D维空间进行搜索。

粒子

每个粒子赋予记忆功能,记住所搜寻到的最佳位置。
速度:决定飞行的距离方向
速度调整:动态,本身的飞行经验同伴的飞行经验

判定

fitness function确定适应值,判断目前位置好坏。

公式

粒子速度更新公式

粒子速度更新公式
1.粒子先前的速度。
2.“认知”部分:粒子i当前位置与自己最好位置之间的距离。
3.“社会”部分:粒子i当前位置与群体最好位置之间的距离。

粒子位置更新公式

粒子位置更新公式

基本思想

粒子群算法流程图

PSO实现-C++

以解决4维Rosenbrock函数为例。

// PSO.cpp : This file contains the 'main' function. Program execution begins and ends there.
// 

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <cstdlib>

using namespace std;

double rnd(double dbLow, double dbUpper)
{
	double dbTemp = rand() / ((double)RAND_MAX + 1.0);
	return dbLow + dbTemp * (dbUpper - dbLow);
}
//4维的解 
#define D 4
//5个粒子
#define M 5
//迭代次数
#define TIME 10000

//速度上限
double Vmax = 60;
//速度下限
double Vmin = -60;
//位置上限
double Xmax = 30;
//位置下限
double Xmin = -30;


//粒子群速度更新公式常数
double c0 = 0.7;
double c1 = 2;
double c2 = 2;
//用随机函数生成值 
double r1;
double r2;

//要记录的变量
//粒子自己的fitness最强记录表,记录的是位置,M个,D维
double pbest[M][D];
//群体的fitness最强记录表,记录的是位置,D维
double gbest[D];
//群体的fitness最强记录表,记录的是fitness值
double gbestfitness;
//粒子自己的fitness最强记录表,记录的是fitness值
double pbestfitness[M];

//位置坐标 
double x[M][D] = {
	{21.721,	-9.13677,	6.62244,	3.84079},
	{-13.5001,	-23.6131,	17.4462,	-29.0515},
	{-29.6563,	-0.871811,	-27.8912,	17.7425},
	{23.6218,	-16.4885,	-22.7019,	25.4033},
	{-28.0992,	22.6482,	0.675616,	-8.43752}
};
//速度
double v[M][D] = {
	{-19.9048,	29.562,		-22.104,	-5.45346},
	{-20.5922,	-28.6944,	-26.3216,	19.0615},
	{-7.83576,	-55.7173,	-40.9177,	28.255},
	{-11.6373,	-41.0138,	17.7311,	-14.87},
	{17.561,	-13.5365,	51.2722,	-56.098}
};
//fitness function
double fitnessFunction(double t[D])
{
	double value = 0;
	//方程计算 
	for (int i = 0; i < D; i++)
	{
		value += 100 * pow((t[i + 1] - pow(t[i], 2)), 2) + pow((t[i] - 1), 2);
	}
	//求最小值 
	//所以取了倒数
	return 1.0 / value;
}

int main()
{
	double fitnessFunction(double t[D]);
	//初始化每个粒子的适应度记录表
	double pfitness[M];
	//记录初值
	for (int i = 0; i < M; i++)
	{
		pfitness[i] = fitnessFunction(x[i]);
	}
	//假定目前的最大fitness为第一个
	double fitnessbest=pfitness[0];

	//迭代
	for (int t = 0; t < TIME; t++)
	{
		
		//更新粒子位置
		for (int i = 0; i < M; i++)
		{
			for (int j = 0; j < D; j++)
			{
				//先加
				x[i][j] += v[i][j];
				//如果小于位置规定的最小值
				if (x[i][j] < Xmin)
				{
					//赋为边界值
					x[i][j] = Xmin;
				}
				//如果大于位置规定的最大值
				else if (x[i][j] > Xmax)
				{
					//赋为边界值
					x[i][j] = Xmax;
				}
			}
		}
		//更新粒子速度
		for (int i = 0; i < M; i++)
		{
			for (int j = 0; j < D; j++)
			{
				//随机数
				r1 = rnd(0.0, 1.0);
				r2 = rnd(0.0, 1.0);
				//速度更新
				v[i][j] = c0 * v[i][j] + c1 * r1 * (pbest[i][j] - x[i][j]) + c2 * r2 * (gbest[j] - x[i][j]);
				//如果小于速度规定的最小值
				if (v[i][j] < Vmin)
				{
					//赋为边界值
					v[i][j] = Vmin;
				}
				//如果大于速度规定的最大值
				else if (v[i][j] > Vmax)
				{
					//赋为边界值
					v[i][j] = Vmax;
				}
			}
		}
		for (int i = 0; i < M; i++)
		{
			//更新粒子们的fitness表
			pfitness[i] = fitnessFunction(x[i]);
			
			//更新粒子们的最强fitness表
			//找出fitness最大的粒子
			//如果本轮出现了fitness比之前记录的个体best最高的记录
			if (pfitness[i] > pbestfitness[i])
			{
				pbestfitness[i] = pfitness[i];
				//更新粒子们最好成绩的位置坐标
				for (int j = 0; j < D; j++)
				{
					pbest[i][j] = x[i][j];
				}
			}
		}
		//更新群体fitness最优解
		for (int i = 0; i < M; i++)
		{
			if (pbestfitness[i] > gbestfitness)
			{
				gbestfitness = pbestfitness[i];
				for (int j = 0; j < D; j++)
				{
					gbest[j] = x[i][j];
				}
			}
		}
		cout << t << "times, FUNCTION smallest value is:" << 1/gbestfitness << endl;
	}
	for (int i = 0; i < D; i++)
	{
		cout << gbest[i] << endl;
	}
	return 0;
}

// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
// Debug program: F5 or Debug > Start Debugging menu

// Tips for Getting Started: 
//   1. Use the Solution Explorer window to add/manage files
//   2. Use the Team Explorer window to connect to source control
//   3. Use the Output window to see build output and other messages
//   4. Use the Error List window to view errors
//   5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
//   6. In the future, to open this project again, go to File > Open > Project and select the .sln file

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值