前言
??經(jīng)歷兩小時,終于用C語言寫完了算法焰情,真是不容易陌凳。已經(jīng)將近一年多沒摸過C語言了,很多都忘了内舟,之前計算機網(wǎng)絡(luò)課的大作業(yè)CSMA-CD協(xié)議算法模擬因為要用C語言所以用了兩天的空閑時間重新學了一遍C語言(僅僅學到了指針截止)冯遂,現(xiàn)在也是很多不記得了,寫的比較丑陋谒获。希望大家不要笑話。之前本想用JS寫的但是不好調(diào)試什么的壁却,所以還是用了C語言批狱。(附加一句:物聯(lián)網(wǎng)專業(yè)真的好坑,大二最好就自學號JAVA或者C++不然大三真的比較老火.)
粒子群優(yōu)化算法簡介
&emm oniziranjiesp;?粒子群優(yōu)化算法是進化計算的一個分支展东,是一種模擬自然界的生物活動的隨機搜索算法赔硫。PSO(粒子群優(yōu)化算法)模擬了自然界鳥群捕食和魚群捕食的過程。它是1995年由美國學者Eberhat和Kennedy提出的盐肃,現(xiàn)在已經(jīng)廣泛應(yīng)用于各種工程領(lǐng)域的優(yōu)化問題之中爪膊。
核心
- 速度與位置更新公式
- 速度與位置更新公式
$$ v_i^d =wv_i^d+c_1r_1d*({pBest_id-x_id})+c_2*r_2d*({gBest_id-x_id}) $$
$$ x_i^d =x_id+v_id $$
基本流程
- 初始化
- 更新
- 迭代
- 滿足條件后停止
源程序
用例
已知函數(shù)$ y=f(x_1,x_2)=x_12+x_22 $,其中$ -10<={ x_1,x_2 }<=10 $,用粒子群優(yōu)化算法求解y的最小值。
源程序
/*******************************************************************************
*
* 粒子群優(yōu)化算法
*--------------------------------------------------------------------------------
* 算法題目 : 例題5.1
* 算法說明 :w是慣量權(quán)重砸王,一般取0-1之間數(shù)字推盛,這兒取0.5
* c1,c2為加速系數(shù),通常取固定值2.0
* r1,r2為[0-1]隨機數(shù)
* 注意 :對于越界的位置需要進行合法性的調(diào)整
求最小值則只需要對函數(shù)f進行改動以及204行的update sum計算進行改動谦铃。
如果求最大值耘成,則不僅僅改動上述過程,還包括64行的判斷以及204行的判斷
改動x域值則只需要手動輸入驹闰,改變?nèi)后w只需要define N 群體數(shù)
*******************************************************************************/
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#define N 3
/********************************************************************
*函數(shù)名:init_helper()
*函數(shù)功能:初始化輔助函數(shù)
*函數(shù)輸入:unsigned top ,unsigned bottom 上邊界瘪菌,下邊界
*輸出:無
**********************************************************************************/
void init_helper(int top,int bottom,float arr[N][6]) //位置 速度 個人歷史最好位置6個數(shù)(x,y)形式
{
int i,j;
srand((unsigned)time(NULL));
for(i = 0;i<N;i++)
{
for(j=0;j<4;j++)
{
arr[i][j]=rand()%(top-bottom+1)+bottom;//產(chǎn)生[bottom,top]之間的隨機數(shù)
}
arr[i][4]=arr[i][0];
arr[i][5]=arr[i][1];
}
}
/************************************************************************
*函數(shù)名:f()
*函數(shù)功能:計算每個解
*函數(shù)輸入:particle[][]
*函數(shù)輸出:無
***************************************************************************/
void f(float particle[N][6],float gbest[2],float history_best[2])
{
float sum[N],M_in[1][2];
int i ,j;
M_in[0][0]=100;
M_in[0][1]=0;
for(i=0;i<N;i++)
{
sum[i]=particle[i][0]*particle[i][0] + particle[i][1]*particle[i][1];
if(sum[i]<M_in[0][0])
{
M_in[0][0]=sum[i];
M_in[0][1]=i;
}
}
j=M_in[0][1];
printf("最小坐標為: ");
for(i=0;i<2;i++)
{
history_best[i]=gbest[i];
gbest[i] = particle[j][i];
printf("%5.2f ",gbest[i]);
}
printf("\n");
printf("全局最優(yōu)函數(shù)值和當前最小值位置分別為 ");
printf("%5.2f ",M_in[0][0]);
printf("%5.2f\n",M_in[0][1]+1);
printf("全局最優(yōu)坐標為");
for(i=0;i<2;i++)
{
printf(" %5.2f ",gbest[i]);
}
printf("\n");
printf("歷史最優(yōu)坐標:");
for(i=0;i<2;i++)
{
printf(" %5.2f ",history_best[i]);
}
printf("\n");
}
/*******************************************************************************
*函數(shù)名稱:init()
*函數(shù)功能:初始化
*輸入:
*輸出:
********************************************************************************/
void init(int top,int bottom,float particle[N][6],float gbest[2],float history_best[2])
{
int i,j;
scanf("%d%d",&bottom,&top);
for(i=0;i<N;i++)
{
init_helper(top,bottom,particle);
}
f(particle,gbest,history_best);
for(i=0;i<N;i++)
{
for(j=0;j<6;j++)
{
printf("%5.2f ",particle[i][j]);
}
printf("\n");
}
}
/*******************************************************************************
*函數(shù)名稱:update(int top,int bottom,float particle[N][6],float gbest[2],float history_best[2])
*函數(shù)功能:更新速度和位置
*輸入:int top,int bottom,float particle[N][6],float gbest[2]
*輸出:無
********************************************************************************/
void update(int top,int bottom,float particle[N][6],float gbest[2],float w,float c,float r1,float r2,float history_best[2])
{
int i,j=2,k;
for(i=0;i<N;i++)
{
srand((unsigned)time(NULL));
r1=rand()/(double)(32768);
r2=rand()/(double)(32768);
//更新速度
particle[i][j]=w*particle[i][j]+c*r1*(particle[i][j+2]-particle[i][0])+c*r2*(gbest[0]-particle[i][0]);
particle[i][j+1]=w*particle[i][j+1]+c*r1*(particle[i][j+3]-particle[i][1])+c*r2*(gbest[1]-particle[i][1]);
// 對越界數(shù)進行處理嘹朗,大于大邊界取top师妙,小于下邊界取bottom
for(k=0;k<2;k++)
{
if(particle[i][j+k]>10)
particle[i][j+k]=10;
else if(particle[i][j+k]<-10)
particle[i][j+k]=-10;
}
// 更新位置
particle[i][0]+=particle[i][j];
particle[i][1]+=particle[i][j+1];
// 對越界數(shù)進行處理,大于大邊界取top屹培,小于下邊界取bottom
for(k=0;k<2;k++)
{
if(particle[i][k]>10)
particle[i][k]=10;
else if(particle[i][k]<-10)
particle[i][k]=-10;
}
}
printf("更新后位置速度為默穴,此時個人歷史最優(yōu)尚未更新\n");
for(i=0;i<N;i++)
{
for(j=0;j<6;j++)
{
printf("%5.2f ",particle[i][j]);
}
printf("\n");
}
update_helpaer(particle,gbest,history_best);
printf("更新后位置速度為,此時個人歷史最優(yōu)已經(jīng)更新\n");
for(i=0;i<N;i++)
{
for(j=0;j<6;j++)
{
printf("%5.2f ",particle[i][j]);
}
printf("\n");
}
}
/*******************************************************************************
*函數(shù)名稱:update_helper(float particle[N][6],float gbest[2],float history_best[2])
*函數(shù)功能:更新個人歷史最優(yōu)以及全局最優(yōu)位置
*輸入:float particle[N][6],float gbest[2] float history_best[2]
*輸出:無
********************************************************************************/
void update_helpaer(float particle[N][6],float gbest[2],float history_best[2])
{
float sum[2];
int i,j;
for(i=0;i<N;i++)
{
sum[0]=particle[i][0]*particle[i][0]+particle[i][1]*particle[i][1];
sum[1]=particle[i][4]*particle[i][4]+particle[i][5]*particle[i][5];
if(sum[0]<sum[1])
{
particle[i][4]=particle[i][0];
particle[i][5]=particle[i][1];
}
}
f(particle,gbest,history_best);
}
// 主函數(shù)main()
void main()
{
int top,
bottom,
i=0,
j;
float w=0.5,
c=2.0,
r1=0.0,
r2=0.0,
particle[N][6],
gbest[2]={-10,10},
history_best[2],
pbest[2];
init(top,bottom,particle,gbest,history_best);
while(gbest[0]!=history_best[0]&&gbest[1]!=history_best[1])
{
update(top,bottom,particle,gbest,w,c,r1,r2,history_best);
}
printf("解為:");
for(i=0;i<2;i++)
{
printf("%5.2f ",gbest[i]);
}
}
注:以上為本人原創(chuàng)褪秀,轉(zhuǎn)載請注明出處壁顶,謝謝。