日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

微粒群算法(二、案例实现)

發布時間:2024/8/1 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微粒群算法(二、案例实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡單二維平面的微粒群算法實現效果如下圖所示,上升到多維空間的核心思想類似。

準備工作
新建一個MFC單文檔應用程序,具體步驟如下圖所示:


新建一個類,如下圖所示:

我們用微粒群來求解最優值問題,求解的是一個函數,比如y=x^2。 x給幾個初始值,代表初始的鳥群(比如10只鳥), 每只鳥位置是隨機的,x=0的位置是最優位置。 通過一定的迭代,把最優位置找到。

首先定義一些需要的變量,以及后面需要用到的成員函數,如下圖所示:

1、添加所要求解函數的成員函數,比如這里以f(x) = x02 + x12為例,如下圖所示。

代碼如下:

float CWeiLiQun::f(float x[]) {return (x[0])*(x[0]) + (x[1])*(x[1]);//這里以函數f(x) = x02 + x12為例 }

2、添加運動的成員函數,如下圖所示。

3、添加畫鳥群的成員函數,如下圖所示。


最終變量以及成員函數如下:

// WeiLiQun.h: interface for the CWeiLiQun class. // //#if !defined(AFX_WEILIQUN_H__C52936AD_87DC_4442_A966_93B5BB20BCC8__INCLUDED_) #define AFX_WEILIQUN_H__C52936AD_87DC_4442_A966_93B5BB20BCC8__INCLUDED_#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000#define N 10 //定義N只鳥(這里取10) typedef struct {float x[2];//微粒位置float v[2];//微粒速度float p[2];//曾經經歷過的最好位置 }SWeiLi;//用結構體表示微粒class CWeiLiQun { public:void Draw(CDC *pDC);void Move();float f(float x[]);CWeiLiQun();virtual ~CWeiLiQun();SWeiLi m_wl[N];//定義微粒數組float m_pg[2];//全局的最優(不是一個微粒,而是一個位置)float c1,c2;//c1是調節微粒飛向自身最好位置的步長,c2是調節微粒飛向全局最好位置的步長。float r1,r2;//r1,r2~u(0,1)CPoint m_YD;//原點float m_kx,m_ky;//比例尺int m_times;//迭代次數 };#endif // !defined(AFX_WEILIQUN_H__C52936AD_87DC_4442_A966_93B5BB20BCC8__INCLUDED_)

緊接著初始化,代碼如下:

CWeiLiQun::CWeiLiQun() {int i,j;for( i = 0; i < N; i++){for (j = 0; j < 2; j++){m_wl[i].x[j] = rand()%20 -10;//N只鳥的初始位置,-10到10之間的范圍m_wl[i].v[j] = rand()%6 -3; //N只鳥的初始速度,-3到3之間的范圍m_wl[i].p[j] = m_wl[i].x[j]; //N只鳥當前的最好位置}}m_pg[0] = m_wl[0].p[0];m_pg[1] = m_wl[0].p[1];//全局的最好位置for( i = 1; i < N; i++){if(f(m_wl[i].p) < f(m_pg)){m_pg[0] = m_wl[i].p[0];m_pg[1] = m_wl[i].p[1];}}c1 = 1.2;c2 = 1.2;r1 = 0.6;r2 = 0.6;//按照經驗給定的初始值m_YD.x = 400;m_YD.y = 250;//原點初始值位置m_kx = 10;m_ky = -10;//比例尺放大10倍m_times = 0; }

最關鍵的運動代碼如下:

void CWeiLiQun::Move() {int i,j;int vMax = 10;for(i = 0; i < N; i++){for (j = 0; j < 2; j++){m_wl[i].v[j] += c1*r1*(m_wl[i].p[j] - m_wl[i].x[j]) + c2*r2*(m_pg[j] - m_wl[i].x[j]);//給定的公式if( m_wl[i].v[j] > vMax )m_wl[i].v[j] = vMax;if( m_wl[i].v[j] < -vMax)m_wl[i].v[j] = -vMax;//如果不寫這個限制條件,若X范圍很大,則粒子群震蕩得非常厲害m_wl[i].x[j] += m_wl[i].v[j];//給定的公式if(f(m_wl[i].x) < f(m_wl[i].p))//當前位置是否比曾經經歷過的最優位置要好{m_wl[i].p[0] = m_wl[i].x[0];m_wl[i].p[1] = m_wl[i].x[1];} }}for( i = 0; i < N; i++){if(f(m_wl[i].p) < f(m_pg))//和全局最優位置再做比較{m_pg[0] = m_wl[i].p[0];m_pg[1] = m_wl[i].p[1];}}m_times++;//迭代次數 }

再將鳥群畫出來,代碼如下:

void CWeiLiQun::Draw(CDC *pDC) {int i,j;int x ,y,r;CString str1,str2;r = 20;//坐標原點半徑x = m_YD.x;y = m_YD.y;pDC->Ellipse(x-r,y-r,x+r,y+r);for(i = 0; i < N; i++){x = m_YD.x + m_wl[i].x[0] * m_kx;y = m_YD.y + m_wl[i].x[1] * m_ky;r = 10;pDC->Ellipse(x-r,y-r,x+r,y+r);}str1.Format("迭代次數:%d",m_times);str2.Format("全局最優值位置:(%.2f,%.2f)",m_pg[0],m_pg[1]);pDC->TextOut(600,50,str1);pDC->TextOut(600,100,str2);for(i = 0; i < N; i++){str1.Format("第%d只鳥的當前位置:(%.2f,%.2f);曾經最優值位置:(%.2f,%.2f)",i+1,m_wl[i].x[0],m_wl[i].x[1],m_wl[i].p[0],m_wl[i].p[1]);pDC->TextOut(600,150+50*i,str1);} }

新建一個菜單,如下圖所示:



再添加一個“連續動畫”,如下圖所示:


添加窗口消息響應句柄,如下圖所示:

在CWeiLiQunSuanFaView里引入


代碼如下:

void CWeiLiQunSuanFaView::OnMNext() {m_WeiLiQun.Move();Invalidate(TRUE); }void CWeiLiQunSuanFaView::OnMDongHua() {SetTimer(1,100,NULL); }void CWeiLiQunSuanFaView::OnTimer(UINT nIDEvent) {m_WeiLiQun.Move();Invalidate(TRUE);CView::OnTimer(nIDEvent); }


代碼如下:

void CWeiLiQunSuanFaView::OnDraw(CDC* pDC) {CWeiLiQunSuanFaDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data herem_WeiLiQun.Draw(pDC); }

實現效果圖:

上述案例只是實現了簡單的二維平面的微粒群算法,三維等多維空間的核心思想類似,可自行嘗試。

總結

以上是生活随笔為你收集整理的微粒群算法(二、案例实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。