matlab粒子群算法求二元函数极值_【粒子群算法系列】粒子群算法求解函数极值(C/C++)...

本文介绍了粒子群算法(PSO)的基本思想,并提供了利用该算法求解非线性函数极值的实例。通过算法流程图和代码展示,阐述了算法在寻找最优解过程中的应用。尽管每次运行结果可能不同,但在第54代时达到最大值。此外,还分享了相关学习资源和速度更新公式的重点。
摘要由CSDN通过智能技术生成

3d595ee44b6a9bca6f1761d7fb0de34f.png

粒子群算法

粒子群算法(PSO,Particle Swarm Optimization),也称粒子群优化算法或鸟群觅食算法。1995年由J. Kennedy和R. C. Eberhart等开发的一种新的进化算法(Evolutionary Algorithm - EA)。

粒子群优化算法的基本思想是利用群体中个体之间的信息共享,从而使得整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得问题的最优解。

粒子群算法的详细介绍,网上已经有很多资料,这里就不再赘述。画个标准算法的流程图吧。

a02607dbf861598e28bd31560cbd0829.png

然后推荐几个学习链接:

https://mp.weixin.qq.com/s/Vz6BFqzFmQLwgQz6agjG0A

https://mp.weixin.qq.com/s/axln8SohDXpHDAeJ2EhKQg

https://mp.weixin.qq.com/s/3Os2ZxLkFM6wKzY6wLQ9zA

……

本文要求解极值的非线性函数为

c23e048a44e927da2a488ee2e72ec276.png

下面直接上代码:

程序中种群规模为50,迭代次数为500,位置范围为[-2, 2],速度范围为[-0.5, 0.5],两个加速因子均为1.49445。
/* 参考资料:https://blog.csdn.net/hcc199521/article/details/53445656?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242求解以下二元函数的最大值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.71289s.t. x∈[-2, 2]     y∈[-2, 2]*/#include #include #include #include #include #include #include #define g_dC1 1.49445   /* 加速因子 */#define g_dC2 1.49445   /* 加速因子 */#define g_nG 500                 /* 迭代次数 */#define g_nPopulationNum 50     /* 种群大小 */#define g_nXMin -2#define g_nXMax 2#define g_nYMin -2#define g_nYMax 2#define g_dVMin -0.5#define g_dVMax 0.5#define PI 3.1415926typedef struct stParticle_s{    double dX;    double dY;    double dVX;    double dVY;    double dFitness;}stParticle_t;stParticle_t g_astParticles[g_nPopulationNum];   /* 每一代种群数据 */stParticle_t g_astPBestParticle[g_nPopulationNum];   /* 各粒子极值数据 */stParticle_t g_stGBestParticle;   /* 群体全局极值数据 *//* 计算粒子的适应度值 */void CalFitnessPerParticle(stParticle_t *stParticle){    stParticle->dFitness         = sin(sqrt(stParticle->dX * stParticle->dX + stParticle->dY * stParticle->dY))/(sqrt(stParticle->dX * stParticle->dX + stParticle->dY * stParticle->dY))         + exp((cos(2 * PI * stParticle->dX) + cos(2 * PI * stParticle->dY))/2) - 2.71289;}void CalFitness(){    for (int i = 0; i < g_nPopulationNum; i++)    {        CalFitnessPerParticle(&(g_astParticles[i]));    }}/* 初始化 */void Initialization(){    /* 初始化种群数据 */    for (int i = 0; i < g_nPopulationNum; i++)    {        g_astParticles[i].dX = (((double)rand()) / RAND_MAX - 0.5) * 4; /* -2到2之间的随机数 */        g_astParticles[i].dY = (((double)rand()) / RAND_MAX - 0.5) * 4; /* -2到2之间的随机数 */        g_astParticles[i].dVX = ((double)rand()) / RAND_MAX - 0.5; /* -0.5到0.5之间的随机数 */        g_astParticles[i].dVY = ((double)rand()) / RAND_MAX - 0.5; /* -0.5到0.5之间的随机数 */    }    /* 初始化全局数据 */    g_stGBestParticle.dX = 0.0;    g_stGBestParticle.dY = 0.0;    g_stGBestParticle.dVX = 0.0;    g_stGBestParticle.dVY = 0.0;    g_stGBestParticle.dFitness = DBL_MIN;    for (int i = 0; i     {                g_astPBestParticle[i].dX = 0.0;        g_astPBestParticle[i].dY = 0.0;        g_astPBestParticle[i].dVX = 0.0;        g_astPBestParticle[i].dVY = 0.0;        g_astPBestParticle[i].dFitness = DBL_MIN;    }}/* 找到每个粒子各自的极值,以及整体的极值 */void SearchPGBestParticle(){    for (int i = 0; i < g_nPopulationNum; i++)    {        /* 找到每个粒子各自的极值(该粒子每代的极值进行比较) */        if (g_astPBestParticle[i].dFitness < g_astParticles[i].dFitness)        {            g_astPBestParticle[i].dX = g_astParticles[i].dX;            g_astPBestParticle[i].dY = g_astParticles[i].dY;            g_astPBestParticle[i].dVX = g_astParticles[i].dVX;            g_astPBestParticle[i].dVY = g_astParticles[i].dVY;            g_astPBestParticle[i].dFitness = g_astParticles[i].dFitness;        }                /* 找到全局最优粒子 */        if (g_stGBestParticle.dFitness < g_astParticles[i].dFitness)        {            g_stGBestParticle.dX = g_astParticles[i].dX;            g_stGBestParticle.dY = g_astParticles[i].dY;            g_stGBestParticle.dVX = g_astParticles[i].dVX;            g_stGBestParticle.dVY = g_astParticles[i].dVY;            g_stGBestParticle.dFitness = g_astParticles[i].dFitness;        }    }}/* 更新粒子的位置和速度 */void RefreshParticlePAndV(){    for (int i = 0; i < g_nPopulationNum; i++)    {        /* X方向速度(如果是多维的话,这里指第一维的速度) */        double dRand1 = (double)rand() / RAND_MAX;   /* 取0到1之间的随机数 */        double dRand2 = (double)rand() / RAND_MAX;        g_astParticles[i].dVX = g_astParticles[i].dVX             + g_dC1 * dRand1 * (g_astPBestParticle[i].dX - g_astParticles[i].dX)             + g_dC2 * dRand2 * (g_stGBestParticle.dX - g_astParticles[i].dX);        /* Y方向速度(如果是多维的话,这里指第一维的速度) */        dRand1 = (double)rand() / RAND_MAX;        dRand2 = (double)rand() / RAND_MAX;        g_astParticles[i].dVY = g_astParticles[i].dVY             + g_dC1 * dRand1 * (g_astPBestParticle[i].dY - g_astParticles[i].dY)             + g_dC2 * dRand2 * (g_stGBestParticle.dY - g_astParticles[i].dY);        /* 如果速度超过边界,则设为边界 */        if (g_astParticles[i].dVX < g_dVMin)        {            g_astParticles[i].dVX = g_dVMin;        }        if (g_astParticles[i].dVX > g_dVMax)        {            g_astParticles[i].dVX = g_dVMax;        }        if (g_astParticles[i].dVY < g_dVMin)        {            g_astParticles[i].dVY = g_dVMin;        }        if (g_astParticles[i].dVY > g_dVMax)        {            g_astParticles[i].dVY = g_dVMax;        }        /* 粒子位置更新 */        g_astParticles[i].dX = g_astParticles[i].dX + g_astParticles[i].dVX;        g_astParticles[i].dY = g_astParticles[i].dY + g_astParticles[i].dVY;        if (g_astParticles[i].dX > g_nXMax)        {            g_astParticles[i].dX = g_nXMax;        }        if (g_astParticles[i].dX < g_nXMin)        {            g_astParticles[i].dX = g_nXMin;        }        if (g_astParticles[i].dY > g_nYMax)        {            g_astParticles[i].dY = g_nYMax;        }        if (g_astParticles[i].dY < g_nYMin)        {            g_astParticles[i].dY = g_nYMin;        }    }}void main(){    clock_t start, finish;    start = clock();    srand((unsigned)time(NULL));    Initialization();    for (int i = 0; i < g_nG; i++)    {        /* 计算每个粒子的适应度值 */        CalFitness();        /* 找到每个粒子各自的极值,以及整体的极值 */        SearchPGBestParticle();        /* 更新粒子的位置和速度 */        RefreshParticlePAndV();        printf("第%d代,最优值位置为(%f, %f),最优值为:%f\n", i + 1, g_stGBestParticle.dX, g_stGBestParticle.dY, g_stGBestParticle.dFitness);    }    finish = clock();    double dTimeSpan = (double)(finish - start) / CLOCKS_PER_SEC;    printf("程序运行时间:%f\n", dTimeSpan);    system("pause");    return;}

运行结果

b8307966abf9114d078808c81762d9e0.png

从运行结果可以看出,当迭代到54代时就达到了最大值。每次运行的结果可能不一样。

粒子群算法和遗传算法的流程比较像,粒子群算法需要重点关注速度更新公式:

b43c2fc8c4b99f02ddb60dc4935313f6.png

参考资料

https://blog.csdn.net/hcc199521/article/details/53445656?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242

(注:本文内容仅供学习交流,如有资料涉及侵权,请通知我删除。谢谢!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值