粒子群优化算法,每次运行结果不一样。

yicheng751 2016-06-12 06:46:23
用粒子群算法优化一个问题,继承了https://github.com/AlieYu/Particle-Swarm-Optimization-PSO-_C----
的PSO类,按算法的原理,应该每次运行优化出的结果是一样的,但是随着运行次数的增多,偏差增大。

触发函数
void MainWindow::calButtonClicked()
{
prodData.listVectorData=ui->prodData->getListVectorData();
injData.listVectorData=ui->injData->getListVectorData();
QVectorConvertEigen q1;
ArrayXd tnP0=q1.QVectorToVectorXd(prodData.listVectorData.at(0)).array();
ArrayXd prodDataArray=q1.QVectorToVectorXd(prodData.listVectorData.at(1)).array();
ArrayXXd injDataArray=q1.ListVectorToMatrix(injData.listVectorData).array();
CmpModel cmp;
cmp.setData(tnP0,injDataArray,prodDataArray);
cmp.setFitParams(600,100);
cmp.Run(100);
cmp.printResult();
CmpModel cmp1;
cmp1.setData(tnP0,injDataArray,prodDataArray);
cmp1.setFitParams(600,50);
cmp1.Run(50);
cmp1.printResult();
}

继承PSO类 修改的适应度函数
double CmpModel::GetFit(PARTICLE &particle)
{
int injNums=injDataMatrix.cols();
MatrixXd prodInjMatrix=getProdInjMatrix(timeList,particle.X[injNums+1],injDataMatrix,prodDataVector);
int cols=prodInjMatrix.cols();
int rows=prodInjMatrix.rows();
ArrayXd prodData=prodDataVector.tail(rows);
MatrixXd injMatrix=prodInjMatrix.leftCols(cols-1);
VectorXd resVector(injNums+1);
for (int i=0;i<injNums+1;i++)
{
resVector(i)=particle.X[i];
}
ArrayXd prodObs=(injMatrix*resVector).array();//计算出的产量
double qoj=prodData.mean()-prodObs.mean();//注采不平衡系数
prodObs+=qoj;
double err=-(prodData-prodObs).pow(2).sum()/rows;//相对误差
// double err=particle.X[0]*sin(particle.X[0]*3.1415926*10)+2;
return err;
}

添加的设置参数函数
//设置计算适应度参数
void CmpModel::setFitParams(int pNum,int maxIter)
{
int injNums=injDataMatrix.cols();
SetDimN(injNums+2,pNum);
double xDown[injNums+2],xUp[injNums+2];
for (int i=0;i<injNums;i++)
{
xDown[i]=0;
xUp[i]=1;
}
xDown[injNums]=0;
xUp[injNums]=2;
xDown[injNums+1]=0.01;
xUp[injNums+1]=100;
SetXdown(xDown);
SetXup(xUp);
SetVmax(0.125);
SetIteorMax(maxIter);
}
void CmpModel::printResult()
{
int injNums=injDataMatrix.cols();
double result[injNums+2];
double gBestFit=GetBest(result);
qDebug()<<"gBestFit:"<<gBestFit;
for (int i=0;i<injNums+2;i++)
{
qDebug()<<result[i];
}
}

运行结果:
第1次触发
初始化所有粒子的个体
gBestFit: -0.0106852
0.124679
0.129975
0.118851
0.0695183
0.0621348
1.11824
7.1922
初始化所有粒子的个体
gBestFit: -0.0163799
0.125802
0.123954
0.110999
0.0605069
0.0627186
0.939009
10.7074
第2次触发
初始化所有粒子的个体
gBestFit: -0.00572
0.123246
0.127932
0.117957
0.0668491
0.0630871
1.10139
9.26076
初始化所有粒子的个体
gBestFit: -1.56042
0.0482683
0.211839
0.187464
0.047509
0.177201
1.57394
57.4806
第3次触发
初始化所有粒子的个体
gBestFit: -0.133401
0.102157
0.159354
0.14124
0.0888743
0.0896266
1.65061
12.747
初始化所有粒子的个体
gBestFit: -3.4611
0.155183
0.243381
0.172704
0.135338
0.111841
1.81003
72.7145
第4次触发
初始化所有粒子的个体
gBestFit: -1.27257
0.073802
0.169055
0.160619
0.018564
0.161117
1.26562
72.6809
初始化所有粒子的个体
gBestFit: -6.41726
0.20154
0.226871
0.0451014
0.0630959
0.153779
1.34195
59.6622
第5次触发
初始化所有粒子的个体
gBestFit: -1.66646
0.063878
0.214967
0.173773
0.00151516
0.164087
1.34985
76.219
初始化所有粒子的个体
gBestFit: -6.02889
0.0983612
0.0824
0.0578501
0.206366
0.14068
1.25472
89.2219
但是优化简单的问题
double CmpModel::GetFit(PARTICLE &particle)
{
double err=particle.X[0]*sin(particle.X[0]*3.1415926*10)+2;
return err;
}

则正常,不知道是哪出问题了,求大神指点
...全文
4468 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
ooolinux 2018-01-25
  • 打赏
  • 举报
回复
@qq_40429293 设置同一个随机数种子。
阳光怪兽 2018-01-25
  • 打赏
  • 举报
回复
运用粒子群算法做参数辨识,由于每次运行的随机数不一样导致每次结果不同,该怎样在MATLAB中设置随机数
Waiting4you 2016-06-23
  • 打赏
  • 举报
回复 3
PSO算法是一种随机搜索算法,每次运行结果不一样是正常的啊。 简单问题因为维数少,解分布简单(就如曲面上只有一个高峰),所有很容易收敛到最优解上。 如果是复杂的问题的话,维数多,解高低分布复杂,PSO经常会收敛到局部优解上。
粒子群算法PSO入门代码火经典案例求Ackley函数附-PSO.zip 本帖最后由 当当的花生 于 2016-7-30 20:09 编辑 回帖获得更多 粒子群算法 遗传算法前面有人讲了,我来讲讲PSO。 1)先看看百度百科解释: 粒子群算法,也称粒子群优化算法(Particle Swarm Optimization),缩写为 PSO, 是近年来由J. Kennedy和R. C. Eberhart等[1] 开发的一种新的进化算法。PSO 算法属于进化算法的一种,和模拟退火算法相似,它也是从随机解出发,通过迭代寻找最优解,它也是通过适应度来评价解的品质,但它比遗传算法规则更为简单,它没有遗传算法的“交叉” 和“变异” 操作,它通过追随当前搜索到的最优值来寻找全局最优。这种算法以其实现容易、精度高、收敛快等优点引起了学术界的重视,并且在解决实际问题中展示了其优越性。粒子群算法是一种并行算法。 2) 什么? 看不懂? 我来通俗解释: 粒子群算法是生物学家研究鸟类捕食创造的,把一只鸟比作成一个粒子,设想一个有20只秃鹫(粒子)的群体吧,秃鹫相互独立具有个体特征但又相互协助体现群体特征,现在我就是这20只中的一只好了(人丑),我现在和小伙伴去 觅食(找非洲野牛的尸体),假设我是一只老婆在家里孵蛋所以我得很认真找食物的秃鹫,每时每刻我都在记录我周围中最可能有猎物的地方,并以这个依据(设为依据一)在下一刻立即调整速度矢量(有大小方向)来趋向我上一时刻发现的最有可能有尸肉的地方。 假如我飞了一小时,上面说到我每时每刻都在记录最有当刻最有可能有肉的地方,那么在这一个小时的记录中肯定有一个最可能有肉的地方,这个地方就是依据二了,我有种往这个移动的趋势。 前面都是我的个鸟行为,我是一只善于观察和沟通并成功让酋长漂亮女儿当我老婆的鸟,所以群里其他秃鹫找到了一个小尸体就会立即告诉我,那我就看谁发现的小尸肉最有分量了,并有一个往这个地方移动的趋势,这是依据三。 再加一些假设以尽可能地模仿一个群体,1)每时每刻有随机从3只傻鸟中抽出一只鸟让他分心,在下一刻瞎移动位置,假设其他秃鹫和我一样机智并且有才华(不太可能),好了有了这些,经过2个小时的觅食,我们这十只鸟最终飞到了同一地点:一头最大野牛尸体旁边。这就是粒子群算法啦,显然是一个找大尸肉的优化算法。 3)来举个经典栗子,求Ackley函数的最小值。 什么很好求?可不是,这个函数的局部最小值太多了,一不小心就掉坑了,函数是这样的: ackley函数.png MATLAB画图如下: 图像.png 画图代码: %经典函数 Ackley clear,clc,close all; x1=-5:0.01:5; x2=-5:0.01:5; for i=1:1001     for j=1:1001         %目标函数         z=-20*exp^2 x2^2)/2))-exp)) cos))/2 20 2.71289;     end end [x,y]=meshgrid; figure mesh xlabel ylabel zlabel复制代码 这么多局部最小值,那么怎么用PSO求最小值呢? 少说废话,先上MATLAB代码: 1)定义函数: function y = fun y=-20*exp^2 x^2)/2))-exp)) cos))/2 20 2.71289;   复制代码 2)PSO求解: 要先定义函数哦 clear,clc,close all; %参数初始化 %粒子群算法中的俩个参数 c1 = 0.1; %惯量因子 c2 = 0.1; maxg=400; %进化次数 移动400回啊 sizepop=20; %总群规模 20只鸟啊 %初始速度和总群上下边界值 Vmax=1; Vmin=-1; %速度范围 上帝让我飞这么快啊 popmax=5; popmin=-5; %粒子范围 我不能飞到老王的领地啊 %%产生初始粒子和速度,上帝说要有鸟,就有了鸟 for i= 1:sizepop pop=popmax*rands ; %初始种群 V=rand; %初始速度 fitness=fun); %染色体的适应度 end %%找最好的染色体,最大的小肉块啊 [bestfitness,bestindex]=min; zbest=pop; %全局最佳 gbest=pop; %个体最佳 fitnessgbest=fitness; %个体最佳适应度 fitnesszbest=bestfitness; %全局最佳适应度 %%迭代寻优,我要找俩百回啊,老婆在家孵蛋啊 for i=1:maxg for j = 1:sizepop %速度更新,要找最好吃的肉啊 V = V c1*rand*-pop) c2*rand*); V>popmax))=popmax; V0.99 k=ceil; pop=rand; end %适应度值,函数最小的点(鸟) fitness=fun); %个体最优更新,我找到最好吃的肉要实时追踪啊 if fitness < fitnessgbest gebest = pop; fitnessgbest = fitness; end %群体最优更新,我是一只善于观察和沟通并成功让酋长漂亮女儿当我老婆的鸟 if fitness < fitnesszbest zbest = pop; fitnesszbest = fitness; end end yy = fitnesszbest; end %结果分析,20个鸟到了同一个地方,来啊互相伤害啊 plot% title]); grid on xlabel; ylabel; %结果输出 zbest %最佳个体,(点的位置) fitnesszbest %最优值(函数最小值)复制代码 说明:且把一个点(x,y)当成我这只鸟的位置,把这个点代到Ackley函数里得到一个值并记录下来。第一,我移动十次以后十次里有一个位置函数值最小(函数最小就是我们要的尸肉啊),那么我总有种往这个位置移动的趋势,第二,20个点带到函数我是不是得有个最小的,那我就又有种往这个点移动的趋势。 V = V c1*rand*-pop) c2*rand*); 而上面的速度更新公式巧妙的结合了上面俩点啊,精彩绝伦啊 c1,c2是个巧妙的常数,选大了搜索范围广,选小了局部搜索强啊 砖家现在在研究动态调整这俩个惯性因子啊 3)运行结果: 适应度.png 这里的适应度其实就是 把20个点带进函数的那个最小值的变化呀 最小值最后是接近真实最小值0啊,好吃的肉啊 结果: 360反馈意见截图16751106316927.png 每次运行结果都不是相同的哦,pso最终得到函数在(0.1070,0.0199)得到最小值0.0694.成功避开所有菊部最优值十分接近真实的在(0,0),最小值0 的结果。 啊我是一只神奇的秃鹫。第一次认真的回答啊,来啊点赞啊,来啊智能算法有什么: 算法.png ----Mr.Dang 转载注明出处,侵删 回复 支持 获得更多 M文件如下:

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧