📄 psoprotein.cpp
字号:
#include <iostream.h> //include cout cin
#include<math.h>// include pow
#include<stdlib.h> //include rand()和srand()
#include<time.h>
#include<stdio.h>
#define INPUT 5
#define HIDE 3
#define OUTPUT 1
#define NDIM (INPUT+1)*HIDE+(HIDE+1)*OUTPUT //空间维数
#define PSO_popsize 30 //种群大小 即粒子个数
#define PSO_maxgen 10 // 迭代次数
#define VMAX 1 //速度极值
#define rnd(low,uper) ((rand()/(float)RAND_MAX)*((uper)-(low))+(low))//生成[low,uper]的随机float值
#define MAXLINE 1000
float g_fParamater_w; //惯性权重
float g_fParamater_c1=2.0; //加速系数
float g_fParamater_c2=2.0; //加速系数
float g_fLowBound[NDIM],g_fUpperBound[NDIM]; //种群中个体的范围
float g_fGbest_pos_global[NDIM]; //全局极值的坐标,注意由ParticleSwarm::getGBest()更新 粒子更新速度需要使用,用于全局通信用。
float g_fW1[100][100],g_fW2[100][100];
float g_fInput[MAXLINE][INPUT+1];
float g_fOutput[MAXLINE][OUTPUT];
int g_nMaxline;
//定义单个粒子类
class Particle {
public:
float pos[NDIM]; //粒子位置
float v[NDIM]; //粒子速度
float pbest; //个体极值点
float pbest_pos[NDIM]; //个体最优解的坐标
float fitness; //当前算出的一个适应值
public:
float calcFitness(); //计算适应值的函数,评估个体
void updatePosition(); //更新位置
void updatePBest(); //更新个体极值
void Transfer(); // 转换
void ReadFile(); //读文件
};
float Particle::calcFitness() //计算适应度值
{
float SumResult[OUTPUT],sum[HIDE],sum1[HIDE],sum2[OUTPUT],wucha[MAXLINE],SUMwucha,fitness;
Transfer();
//隐层各节点的输出值
sum[HIDE]=-1;
SUMwucha=0;
for(int m=0;m<g_nMaxline;m++)
{
for(int j=0;j<HIDE;j++)
{
sum1[j]=0;
for(int i=0;i<INPUT+1;i++)
sum1[j]=sum1[j]+g_fInput[m][i]*g_fW1[i][j];
sum[j]=1.0/(1.0+pow(2.178,-sum1[j]));
}
//输出层节点的输出值
for(int k=0;k<OUTPUT;k++)
{
sum2[k]=0;
for(int j=0;j<HIDE+1;j++)
sum2[k]=sum2[k]+sum[j]*g_fW2[j][k];
SumResult[k]=1.0/(1.0+pow(2.178,-sum2[k]));
}
wucha[m]=fabs(SumResult[k]-g_fOutput[m][INPUT+1]);
SUMwucha=SUMwucha+wucha[m];
}
fitness=1.0/SUMwucha;
//cout<<"the fitness is"<<fitness<<endl;
return (fitness);
}
void Particle:: Transfer()//把位置转换为相对应权值
{
for(int p=0;p<INPUT+1;p++)
{
for(int k=0;k<HIDE;k++)
g_fW1[p][k]=pos[HIDE*p+k];
}
for(int m=0;m<HIDE+1;m++)
{
for(int n=0;n<OUTPUT;n++)
g_fW2[m][n]=pos[(INPUT+1)*HIDE+m];// 多个输出时 g_fW2[m][n]=PSO_pop[i].pos[(INPUT+1)*HIDE+(OUTPUT*m)+n];
}
}
void Particle:: ReadFile() // 读文件
{
int i,j;
FILE *fp;
fp=fopen("gbp_train.txt","r");
fscanf(fp,"%d",&g_nMaxline);
for(i=0;i<g_nMaxline;i++)
{
for(j=0;j<OUTPUT;j++)
{
fscanf(fp,"%f",&g_fInput[i][j]);
}
g_fInput[i][j] = -1;
fscanf(fp,"%f",&g_fOutput[i][j]);
}
}
void Particle::updatePosition() //更新位置和速度
{
int i;
for(i=0;i<NDIM;i++)
{
g_fParamater_w = rnd(0,1);
//更新速度,利用粒子的个体极值和全局极值
v[i] = g_fParamater_w * v[i] +
g_fParamater_c1 * rnd(0,1) * (pbest_pos[i] - pos[i]) +
g_fParamater_c2 * rnd(0,1) * (g_fGbest_pos_global[i] - pos[i]);
//判断是否超出最大速度和最小速度,防止粒子远离搜索空间
if (v[i]<-VMAX)
v[i] = -VMAX;
if (v[i]>VMAX)
v[i]=VMAX;
pos[i]+=v[i]; //更新位移
//判断粒子位置是否出界
if(pos[i]<g_fLowBound[i])
pos[i]=g_fLowBound[i];
if(pos[i]>g_fUpperBound[i])
pos[i]=g_fUpperBound[i];
}
}
void Particle::updatePBest() //更新个体极值
{
if(this->fitness<pbest)
{
pbest=this->fitness;
for(int i=0;i<NDIM;i++)
{
pbest_pos[i]=pos[i];
}
}
}
class PSO //粒子群类
{
public:
float gbest; //全局极值的适应值
float gbest_pos[NDIM]; //全局极值的坐标
Particle PSO_pop[PSO_popsize];//单个粒子定义为粒子群类的属性 PSO_pop[PSO_popsize]为类对象
public:
void init(); //初始化种群
void getGBest(); //获取全局极值
void search(); //迭代
};
void PSO::init() //初始化
{
gbest=1000000;
/*gbest=numeric_limits<float>::max();
srand((unsigned)time(NULL));//将全局最优赋予一个最大的随机数,以便找到最小值*/
for(int t=0;t<NDIM;t++)
{
g_fLowBound[t]=0; //初始化Bound
g_fUpperBound[t]=1;
}
//初始化种群,包括位置,速度,fitness和pbest
for(int i=0;i<PSO_popsize;i++)
{
for(int j=0;j<NDIM;j++)
{
PSO_pop[i].pos[j]=rnd(g_fLowBound[j],g_fUpperBound[j]);
PSO_pop[i].pbest_pos[j]=PSO_pop[i].pos[j];
PSO_pop[i].v[j]=rnd(-VMAX,VMAX);
}
//计算fitness
PSO_pop[i].fitness= PSO_pop[i].calcFitness();//计算适应度的函数不会,见34行
//初始化,将当前fitness赋给pbest
PSO_pop[i].pbest=PSO_pop[i].fitness;
}
getGBest();
cout<<"gen: 0"<<endl; //初始化算作第零代。
cout<<"The lowest value is" <<gbest<<endl;
cout<<"The parameters are:"<<endl;
for(int m=0;m<NDIM;m++)
{
cout<<gbest_pos[m]<<endl;
}
}
void PSO::getGBest() //计算全局最优极值
{
for(int i=0;i<PSO_popsize;i++)
{
if(PSO_pop[i].fitness<gbest)
{
gbest=PSO_pop[i].fitness;
for(int j=0;j<NDIM;j++)
{
gbest_pos[j]=PSO_pop[i].pos[j];
g_fGbest_pos_global[j]=PSO_pop[i].pos[j];
}
}
}
}
void PSO::search() //迭代
{
//float Array[100];
int gen=0;
//范围是:[0, PSO_maxgen-1],总共PSO_maxgen代。
while(gen<PSO_maxgen)
{
// Array[gen] = gbest;
//每个粒子进行运动,求值更新pbest
for(int k=0;k<PSO_popsize;k++)
{
PSO_pop[k].updatePosition();
PSO_pop[k].fitness=PSO_pop[k].calcFitness();
PSO_pop[k].updatePBest();
}
//更新gbest
getGBest();
gen++;
cout<<"gen:"<<gen<<endl;
cout<<"The lowest value is" <<gbest<<endl;
cout<<"The parameters are:"<<endl;
for(int i=0;i<NDIM;i++)
cout<<gbest_pos[i]<< endl;
}
}
int main()
{
Particle R;
R.ReadFile();
PSO p;
p.init();
p.search();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -