粒子群算法(PSO) C

本文探讨了粒子群优化算法(PSO)中惯性权重(w)对算法性能的影响,包括线性递减惯性权重(LDIW)以及其他四种不同的w更新策略。通过比较不同w值下的平均最优解、次优解出现频率和接近最优解的次数,以评估各种策略在全局和局部搜索能力上的表现。
摘要由CSDN通过智能技术生成

粒子群算法的核心的两个公式为:
速度更新公式:
Vid(k+1)=wVid(k)+c1r1*(Pid(k)-Xid(k))+c2r2(Pgd(k)-Xid(k))
位置更新公式:
Xid(k+1) = Xid(k) + Vid(k+1)

w称之为惯性权重,体现的是粒子继承先前速度的能力。 经验表明:一个较大的惯性权重有利于全局搜索,而一个较小的惯性权重则更有利于局部搜索。

为了更好地平衡算法的全局搜索能力与局部搜索能力,Shi.Y提出了线性递减惯性权重(LDIW)
即:w(k) = w_end + (w_start- w_end)*(Tmax-k)/Tmax。*其中w_start 为初始惯性权重,w_end 为迭代至最大次数时的惯性权重;k为当前迭代次数, Tmax为最大迭代次数。

一般来说,w_start=0.9,w_end=0.4时,算法的性能最好。这样随着迭代的进行,惯性权重从0.9递减到0.4,迭代初期较大的惯性权重使算法保持了较强的全局搜索能力。而迭代后期较小的惯性权重有利于算法进行更精确的局部搜索。线性惯性权重,只是一种经验做法,常用的惯性权重还包括 以下几种。*

(3) w(k) = w_start - (w_start-w_end)(k/Tmax)^2
(4) w(k) = w_start + (w_start-w_end)
(2k/Tmax - (k/Tmax)^2)
(5) w(k) = w_end
(w_start/w_end)^(1/(1+c*k/Tmax)) ,c为常数,比如取10等。

本例的目的就是比较这5种不同的w取值,对于PSO寻优的影响。比较的方法为每种w取值,重复实验若干次(比如100次),比较平均最优解的大小,陷入次优解的次数,以及接近最优解的次数。 这样对于5种方法的优劣可以有一个直观的比较。

代码:

/*
* 本例的寻优非线性函数为
* f(x, y) = sin(sqrt(x ^ 2 + y ^ 2)) / (sqrt(x ^ 2 + y ^ 2)) + exp((cos(2 * PI*x) + cos(2 * PI*y)) / 2) - 2.71289
* 该函数有很多局部极大值点,而极限位置为(0, 0), 在(0, 0)附近取得极大值
*/

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define c1 1.49445 //加速度因子一般是根据大量实验所得
#define c2 1.49445
#define maxgen 300  // 迭代次数
#define repeat 100 // 重复实验次数
#define sizepop 20 // 种群规模
#define popmax 2 // 个体位置最大取值
#define popmin -2 // 个体位置最小取值
#define Vmax 0.5 // 速度最大值
#define Vmin -0.5 //速度最小值
#define dim 2 // 粒子的维数
#define w_start 0.9
#define w_end 0.4
#define PI 3.1415926 //圆周率

double pop[sizepop][dim]; // 定义种群数组
double V[sizepop][dim]; // 定义种群速度数组
double fitness[sizepop]; // 定义种群的适应度数组
double result[maxgen];  //定义存放每次迭代种群最优值的数组
double pbest[sizepop][dim];  // 个体极值的位置
double gbest[dim]; //群体极值的位置
double fitnesspbest[sizepop]; //个体极值适应度的值
double fitnessgbest; // 群体极值适应度值
double genbest[maxgen][dim]; //每一代最优值取值粒子

double func(double * arr);	//适应度函数
void pop_init(void);	 // 种群初始化
double * max(double * fit, int size);	// max()函数定义
void PSO_func(int n);	// 迭代寻优,传入的参数为一个整数,取值为1到5,分别代表5种不同的计算w的方法


int main(void)
{
   
	clock_t start, finish; //程序开始和结束时间
	start = clock(); //开始计时
	srand((unsigned)time(NULL)); // 初始化随机数种子
	for (int i = 1; i <= 5; i++)
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值