一个C++的粒子群(PSO)算法实现

收集和修改的PSO算法,可用于参考实现:

#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <ctime>

#define rand_01 ((float)rand() / (float)RAND_MAX)

const int numofdims = 30;
const int numofparticles = 50;

using namespace std;

//typedef void (*FitnessFunc)(float X[numofparticles][numofdims], float fitnesses[numofparticles]);

void fitnessfunc(float X[numofparticles][numofdims], float fitnesses[numofparticles])
{
    memset(fitnesses, 0, sizeof (float) * numofparticles);
    for(int i = 0; i < numofparticles; i++)
    {
        for(int j = 0; j < numofdims; j++)
        {
            fitnesses[i] += X[i][j] * X[i][j]; //(pow(X[i][j], 2));
        }
    }
}

void rosenBroekFunc(float X[numofparticles][numofdims], float fitnesses[numofparticles])
{
	float x1, x2, t1, t2;
	memset(fitnesses, 0, sizeof (float) * numofparticles);
    for(int i = 0; i < numofparticles; i++)
        for(int j = 0; j < numofdims - 1; j++)
        {
            x1 = X[i][j];
            x2 = X[i][j+1];
            t1 = (x2 - x1 * x1);
            t1 *= t1;
            t1 *= 100;
            t2 = x1 - 1;
            t2 *= t2;
            fitnesses[i] = t1 + t2;
        }
}

float mean(float inputval[], int vallength)
{
    float addvalue = 0;
    for(int i = 0; i < vallength; i++)
    {
        addvalue += inputval[i];
    }
    return addvalue / vallength;
}

void PSO(int numofiterations, float c1, float c2,
              float Xmin[numofdims], float Xmax[numofdims], float initialpop[numofparticles][numofdims],
              float worsts[], float meanfits[], float bests[], float *gbestfit, float gbest[numofdims])
{
    float V[numofparticles][numofdims] = {0};
    float X[numofparticles][numofdims];
    float Vmax[numofdims];
    float Vmin[numofdims];
    float pbests[numofparticles][numofdims];
    float pbestfits[numofparticles];
    float fitnesses[numofparticles];
    float w;
    float minfit;
    int   minfitidx;

    memcpy(X, initialpop, sizeof(float) * numofparticles * numofdims);
    fitnessfunc(X, fitnesses);
    //rosenBroekFunc(X, fitnesses);

//    fp(X, fitnesses);
    minfit = *min_element(fitnesses, fitnesses + numofparticles);
    minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses;
    *gbestfit = minfit;
    memcpy(gbest, X[minfitidx], sizeof(float) * numofdims);

    //设置速度极限
    for(int i = 0; i < numofdims; i++)
    {
        Vmax[i] = 0.2 * (Xmax[i] - Xmin[i]);
        Vmin[i] = -Vmax[i];
    }

    for(int t = 0; t < 1000; t++)
    {
        w = 0.9 - 0.7 * t / numofiterations;

		//计算个体历史极小值
        for(int i = 0; i < numofparticles; i++)
        {
            if(fitnesses[i] < pbestfits[i])
            {
                pbestfits[i] = fitnesses[i];  //pbestfits初始化尚未赋值
                memcpy(pbests[i], X[i], sizeof(float) * numofdims);
            }
        }
        for(int i = 0; i < numofparticles; i++)
        {
            for(int j = 0; j < numofdims; j++)
            {
                V[i][j] = min(max((w * V[i][j] + rand_01 * c1 * (pbests[i][j] - X[i][j])
                                   + rand_01 * c2 * (gbest[j] - X[i][j])), Vmin[j]), Vmax[j]);
                X[i][j] = min(max((X[i][j] + V[i][j]), Xmin[j]), Xmax[j]);
            }
        }

    fitnessfunc(X, fitnesses);
    //rosenBroekFunc(X, fitnesses);
        minfit = *min_element(fitnesses, fitnesses + numofparticles);
        minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses;
        if(minfit < *gbestfit)
        {
            *gbestfit = minfit;
            //cout << "It=" << t << "->" << minfit << endl;
            memcpy(gbest, X[minfitidx], sizeof(float) * numofdims);
        }

        worsts[t] = *max_element(fitnesses, fitnesses + numofparticles);
        bests[t] = *gbestfit;
        meanfits[t] = mean(fitnesses, numofparticles);
    }

}

int main()
{
    time_t t;
    srand((unsigned) time(&t));

    float xmin[30], xmax[30];
    float initpop[50][30];
    float worsts[1000], bests[1000];
    float meanfits[1000];
    float gbestfit;
    float gbest[30];
    for(int i = 0; i < 30; i++)
    {
        xmax[i] = 100;
        xmin[i] = -100;
    }
    for(int i = 0; i < 50; i++)
        for(int j = 0; j < 30; j++)
        {
            initpop[i][j] = rand() % (100 + 100 + 1) - 100;
        }

    PSO(1000, 2, 2, xmin, xmax, initpop, worsts, meanfits, bests, &gbestfit, gbest);

    cout<<"fitness: " << gbestfit << endl;
    for(int i = 0; i < 30; i++)
      cout << gbest[i] << ", ";
    cout << endl;

    return 0;
}

一个C++的粒子群(PSO)算法实现

时间: 2025-01-16 20:06:16

一个C++的粒子群(PSO)算法实现的相关文章

Python实现的粒子群优化算法

01.from numpy import array 02.from random import random 03.from math import sin, sqrt 04. 05.iter_max = 10000 06.pop_size = 100 07.dimensions = 2 08.c1 = 2 09.c2 = 2 10.err_crit = 0.00001 11. 12.class Particle: 13. pass 14. 15.def f6(param): 16. '''S

MOPSO 多目标例子群优化算法

近年来,基于启发式的多目标优化技术得到了很大的发展,研究表明该技术比经典方法更实用和高效.有代表性的多目标优化算法主要有NSGA.NSGA-II.SPEA.SPEA2.PAES和PESA等.粒子群优化(PSO)算法是一种模拟社会行为的.基于群体智能的进化技术,以其独特的搜索机理.出色的收敛性能.方便的计算机实现,在工程优化领域得到了广泛的应用,多目标PSO(MOPSO)算法应用到了不同的优化领域[9~11],但存在计算复杂度高.通用性低.收敛性不好等缺点. 多目标粒子群(MOPSO)算法是由Ca

基本PSO算法实现(Java)

一.算法流程 Step1:初始化一群粒子(粒子个数为50个),包括随即位置和速度: Step2:计算每个粒子的适应度fitness: Step3:对每个粒子,将其适应度与其进过的最好位置(局部)pbest做比较,如果较好,则将其作为当前的最好位置pbest: Step4:对每个粒子,将其将其适应值与群体所经过的最好位置gbest做比较,如果较好,则将其作为当前最好位置gbest: Step5:更新所有粒子位置和速度: Step6:未达到结束条件则转Step2. 二.实验设置 (1)   粒子数p

一个关于汉字查找的算法的猜想

有没有想过当你按下ctrl+F的时候程序是怎样做到查找你要查找的内容,例如在这篇文章里查询"程序设计"我的猜想是它首先会查找到所有有"程"字的词语,将下标存在一个数组里,在查找,直到把这片文章查完,然后再在含有"序"字的地方,过程同上,然后查"设"字,然后再查"计",这用递归应该比较合适,因为操作都是相似的,有限步之内能完成的.所以可以递归,现在就是要设计出程序,加油. 就在刚才想到了另一种办法,就是当查到

一个关于字符串匹配的算法题目

有这样一个算法题目 假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些.从算法是讲, 什么方法能最快的查出所有短字符串里的字母在长字符串里都有? 比如,如果是下面两个字符串: String 1: ABCDEFGHLMNOPQRS String 2: DCGSRQPOM 答案是true,所有在string2里的字母string1也都有.如果是下面两个字符串: String 1: ABCDEFGHLMNOPQRS String 2: DCGSRQPOZ 答

一个字符串排列的小算法

给定n个A和2n个B,用这些字符拼成一个字符串,要求这个串的所有前缀和后缀B的个数始终不少于A. (一个字符串的前缀是只从开头到某个位置为止的子串,后缀是只从某个位置到结尾的子串). 输入格式 多组数据,每组数据只有一行,包含一个正整数n.(n<=10^17). 输出格式 每组数据输出一行,最终结果对99991取余数的结果. def count(n,m,ac,bc,sb):    if(ac==n or bc==m):        print sb;        return 1;    i

一个简单的伪随机数发生算法(转)

源:一个简单的伪随机数发生算法 //此代码纯属交流目的,如用作安全领域,后果自负 #include <stdint.h> #include <stdlib.h> //! \brief random seed static uint16_t s_hwRandomSeed = 0xAA55; static uint8_t s_chRandomTable[] = { 0x12,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, 0xF1,0xE2,0xD3,0xC4,

poj水题-1001 一个简单的大数乘幂算法实现

说到底就是一个大数乘幂运算,小数点后零.明白大数乘幂算法直接搞. 这里就有几个问题: 1.幂位数小可以用二进制容器表示(取模更好,但我是为了练习STL) 2.n位大数用string表示,外加一个int型表示小数点位置 3.字符串×字符串用小学竖式乘法算法就行,注意补零.位数多时两个string两个string地加. 代码长,但理解容易,大数乘法,加法函数很多都能重用. 1 #include <iostream> 2 #include <vector> 3 #include <

谷歌做了45万次不同类型的文本分类后,总结出一个通用的“模型选择算法”...

谷歌做了45万次不同类型的文本分类后,总结出一个通用的"模型选择算法"... 2018年07月25日 17:43:55 阅读数:6 新智元报道 来源:developers.google.com 编译:肖琴.大明 [导读]谷歌官方推出"文本分类"指南教程.为了最大限度地简化选择文本分类模型的过程,谷歌在进行大约450K的文本分类实验后,总结出一个通用的"模型选择算法",并附上一个完整的流程图,非常实用. 文本分类(Text classificati