粒子群(PSO)C++代码实现及其算法可视化

前言

最近想学一些玄学算法,比如说退火和粒子群。退火网上教程有很多,我学得比较舒服。但是粒子群...我在网上真的没有找到几篇适合我的,要么使用的语言不是c++,要么长得像工程文件,要么就是过于简练...但我在经过一番自己的努力摸索后,还是写出来了。所以在此我写一篇博客,希望对后来有兴趣学习的人有所帮助。

本次的代码是带可视化的,使用了hdc画图和一些控制台的操作。看不懂没关系,删了一样能跑。

算法针对的问题

粒子群算法可以解决在一个很大的范围内短时间内找到全局最优解的问题,但要求该问题是没有约束的(但其实可以将有约束的问题转为无约束问题)。就比如说我这里代码解决的样例问题:给定一个点,要求求出离这个点最近的点。我知道你想说什么:这不就是这个点本身吗!但是要知道,正式的问题可能还有不同的权值计算方式。对于某些问题,粒子群算法将十分有优势。

算法原理

算法的原型是鸟群觅食活动:有一群鸟在广阔的林场中觅食,它们都想要去到食物最多的地方。这些鸟有某种奇特的方式,可以共享当前找到的食物最多的地方(假设每只鸟都不想恰独食)。对于每只鸟,它下一步都会考虑两个东西:当前所有鸟的记忆中最好的地方和它的记忆中最好的地方。又因为它自己飞行有一个“惯性”,它下一步的飞行也会受到前一步飞行的影响。

该原理经过数学家们的研究、提炼,变成了一个数学模型,并得到了如下的公式:

(图来自百度百科)

该公式中,Vx是一个向量,表示了微粒x的速度(实际上我认为Vx前面还应该加上一个惯性系数ω);‘2’是参数,实际运用中可以根据情况改动;rand与Rand都是一个随机数,范围是0~1;pbest是这个微粒之前所搜索到的最优解,pbest-x是一个由x指向pbest的向量;gbest是全局最优解

来解释一下上面那个公式。该公式大体可以分为三个部分:ω*Vx  、p*rand()*(pbest-x) 、q*Rand()*(gbest-x)。第一个部分就是该粒子前一次运动的惯性的影响;第二部分是该粒子记忆最优解对该粒子的“吸引力”;第三部分是全局最优解对该粒子的“吸引力”。

公式中的可调参数有三个:ω、p、q。ω减小会使得粒子更快地改变方向,但可能会因此失去寻找更优解的能力,陷入局部最优;p>q会使粒子更趋向于去到全局最优,但可能导致陷入局部最优;p<q会使粒子更趋向于去到个体最优,但可能导致解的最优性下降或最优解精度丢失;p、q的大小都会影响粒子收敛的速度,p、q值越大速度越快,但是精度低;值越小速度越慢,但精度高。

有了这些原理,我们就可以写出代码啦

代码

下面两个代码都加上了可视化

 二维

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
//选择窗口,新建画笔
HWND hWnd=GetConsoleWindow();
HDC hdc=GetDC(GetConsoleWindow());
HPEN hpenwhite = CreatePen( PS_SOLID, 1, RGB(255,255,255) );
HPEN hpenblack = CreatePen( PS_SOLID, 1, RGB(0,0,0) );

//
//下面是PSO算法主要内容
struct Vector{
	double x,y;
	double px,py;//px,py是原点为零的方向向量坐标 
};
struct Point{
	double x,y,val;
}glb;
double Bx,By;
double val(double x,double y){//val函数是对一个点权值的计算,是实际运用中最重要的地方
	in
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于粒子群优化算法实现方式较为复杂,且需要涉及到较多的数学知识,因此在此不能提供完整的代码实现。但是,可以提供一个简单的可视化实现粒子群优化算法的示例,供参考: ```python import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # 定义目标函数 def func(x): return np.sin(x) + np.sin(10 * x / 3) # 粒子群优化算法 def PSO(func, x_min, x_max, n_particles=50, max_iter=100, w=0.8, c1=2.0, c2=2.0): # 初始化粒子群 x = np.random.uniform(x_min, x_max, n_particles) v = np.zeros_like(x) p = x.copy() p_best = p.copy() f_best = np.min(func(p_best)) # 迭代 for i in range(max_iter): # 更新速度和位置 v = w * v + c1 * np.random.rand() * (p_best - p) + c2 * np.random.rand() * (np.min(p_best) - p) x = x + v # 防止粒子越界 x[x < x_min] = x_min x[x > x_max] = x_max # 更新个体最优位置和全局最优位置 f = func(x) mask = f < func(p_best) p_best[mask] = x[mask] f_best = np.min(func(p_best)) yield x, p_best, f_best # 可视化 fig, ax = plt.subplots() ax.set_xlim(-10, 10) ax.set_ylim(-3, 3) line, = ax.plot([], [], 'bo') p_best_line, = ax.plot([], [], 'ro') f_best_text = ax.text(-9, 2.5, '', fontsize=12) def init(): line.set_data([], []) p_best_line.set_data([], []) f_best_text.set_text('') return line, p_best_line, f_best_text def update(data): x, p_best, f_best = data line.set_data(x, func(x)) p_best_line.set_data(p_best, func(p_best)) f_best_text.set_text('Global Best: {:.6f}'.format(f_best)) return line, p_best_line, f_best_text ani = FuncAnimation(fig, update, frames=PSO(func, -10, 10), init_func=init, blit=True) plt.show() ``` 在上面的代码中,定义了一个目标函数 `func`,并通过粒子群优化算法来最小化该函数。具体实现过程如下: 1. 定义粒子群的个数、最大迭代次数、惯性权重、加速常数等参数,以及粒子的初始位置、速度和个体最优位置。 2. 每次迭代,根据当前速度和位置更新粒子的位置,同时更新个体最优位置和全局最优位置。 3. 将每一次迭代得到的粒子位置、个体最优位置和全局最优位置进行可视化。 4. 最终输出全局最优位置和最优解。 需要注意的是,上述代码中的粒子群优化算法实现方式较为简单,仅供参考,实际应用中可能需要根据具体问题进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值