AFA人工鱼群算法函数优化求解实例C++(2020.11.4)
AF人工魚群算法C++
- 人工魚群算法Artificial Fish
- 1 基本思想
- 2 算法介紹
- 2.1 一些定義
- 2.2 行為描述
- 2.2.1 覓食行為
- 2.2.2 聚群行為
- 2.2.3 追尾行為
- 2.2.4 隨機(jī)行為
- 2.3 行為選擇
- 2.4 公告板
- 2.5 終止條件
- 3 算法步驟
- 4 函數(shù)優(yōu)化實例
- 4.1 目標(biāo)函數(shù)
- 4.2 C++源代碼(AFA)
- 4.3 運行結(jié)果
- 5 算法特點
人工魚群算法Artificial Fish
1 基本思想
????????魚群算法的基本思想是設(shè)想一片水域,如果某個地方的魚類數(shù)目最多,那么這個地方一般來說就是水域內(nèi)富含營養(yǎng)物質(zhì)最多的地方,依據(jù)這一特點來模仿魚群的覓食等行為,以實現(xiàn)全局尋優(yōu)的目的。
????????魚群模式中,魚類的活動主要分為四種:覓食行為、聚群行為、追尾行為和隨機(jī)行為。
2 算法介紹
????????這樣,在類中將人工魚的自身信息和一些行為進(jìn)行封裝,并且它的狀態(tài)可以被同伴感知到。
2.1 一些定義
????????向量X=(x1,x2,...,xn)X=(x_1,x_2,...,x_n)X=(x1?,x2?,...,xn?) 表示人工魚個體的狀態(tài),其中xi(i=1,2,...,n)x_i(i=1,2,...,n)xi?(i=1,2,...,n)為欲尋優(yōu)的變量;
????????Y=f(X)Y=f(X)Y=f(X) 表示人工魚當(dāng)前所在位置的食物濃度,其中YYY為目標(biāo)函數(shù)值;
????????di,j=∣∣Xi?Xj∣∣d_{i,j}=||X_i -X_j||di,j?=∣∣Xi??Xj?∣∣ 表示人工魚個體之間的距離;
????????VisualVisualVisual 表示人工魚的感知距離;
????????stepstepstep 表示人工魚移動的最大步長;δδδ為擁擠度因子。
2.2 行為描述
人工魚(artificial fish,AF)的主要行為如下:
2.2.1 覓食行為
????????覓食行為指魚循著事物多的方向游動的一種行為,人工魚XiX_iXi?在其視野內(nèi)隨機(jī)選擇一個狀態(tài)XjX_jXj?,分別計算它們的目標(biāo)函數(shù)值進(jìn)行比較,如果發(fā)現(xiàn)YjY_jYj?比YiY_iYi?優(yōu),則XiX_iXi?向XjX_jXj?的方向移動一步;否則,XiX_iXi?繼續(xù)在其視野內(nèi)隨機(jī)選擇狀態(tài)XjX_jXj?,判斷是否滿足前進(jìn)條件;這樣反復(fù)嘗試try?numbertry_{-}numbertry??number次后,如果仍不滿足前進(jìn)條件,則隨機(jī)移動一步。
偽代碼描述如下:
floatArtificial?fish::AF?prey()float Artificial_{-}fish::AF_{-}prey()floatArtificial??fish::AF??prey()
{
????for(i=0;i<try?number;i++)for(i=0;i<try_{-}number;i++)for(i=0;i<try??number;i++)
????{
????????Xj=Xi+Rand()?Visual;X_j = X_i+Rand()\cdot Visual;Xj?=Xi?+Rand()?Visual;
????????if(Yi<Yj)if (Y_i <Y_j)if(Yi?<Yj?)
??????????? ?Xi∣next=Xi+Rand()?Step?Xj?Xi∣∣Xj?Xi∣∣;X_{i|next}=X_i+Rand()\cdot Step \cdot \frac {X_j -X_i}{||X_j-X_i||};Xi∣next?=Xi?+Rand()?Step?∣∣Xj??Xi?∣∣Xj??Xi??;
????????elseelseelse
???? ???????? Xi∣next=Xi+Rand()?StepX_{i|next}=X_i+Rand()\cdot StepXi∣next?=Xi?+Rand()?Step
????}
??returnAF?foodconsistence(Xi∣next)return AF_{-}foodconsistence(X_{i|next})returnAF??foodconsistence(Xi∣next?)
}
2.2.2 聚群行為
????????魚在游動過程中為了保證自身的生存和躲避危害會自然地聚集成群。魚群聚集時所遵守的規(guī)則有三條:①分割規(guī)則,盡量避免與鄰近伙伴過于擁擠; ②對準(zhǔn)規(guī)則,盡量與鄰接伙伴的平均方向一致; ③內(nèi)聚規(guī)則,盡量朝鄰近伙伴的重心移動。人工魚XiX_iXi?搜索其視野內(nèi)(即 di,j<Visuald_{i,j}<Visualdi,j?<Visual)的伙伴數(shù)目nfn_fnf?及中心位置XCX_CXC?,若YC/nf>δYiY_C/n_f >δY_iYC?/nf?>δYi?,表明伙伴中心有較多的食物(位置狀態(tài)較優(yōu))且不太擁擠,則XiX_iXi?朝伙伴的中心位置移動一步,否則執(zhí)行覓食行為。
偽代碼描述如下:
floatArtificial?fish::AF?swarm()float Artificial_{-}fish::AF_{-}swarm()floatArtificial??fish::AF??swarm()
{
????nf=0;XC=0;n_f=0;X_C=0;nf?=0;XC?=0;
????for(j=0;j<friend?number;j++)for(j=0;j<friend_{-}number;j++)for(j=0;j<friend??number;j++)
????????if(di,j<Visual)if (d_{i,j} <Visual)if(di,j?<Visual) nf++;XC+=Xj;{ n_f ++;X_C +=X_j; }nf?++;XC?+=Xj?;
????XC=XCnf;X_C = \frac{X_C}{n_f};XC?=nf?XC??;
????if(YCnf>δYi)if(\frac{Y_C}{n_f} >δY_i)if(nf?YC??>δYi?)
????????Xi∣next=Xi+Rand()?Step?XC?Xi∣∣XC?Xi∣∣;X_{i|next}=X_i+Rand()\cdot Step \cdot \frac {X_C -X_i}{||X_C-X_i||};Xi∣next?=Xi?+Rand()?Step?∣∣XC??Xi?∣∣XC??Xi??;
????elseelseelse
????????AF?prey();AF_{-}prey();AF??prey();
??returnAF?foodconsistence(Xi∣next)return AF_{-}foodconsistence(X_{i|next})returnAF??foodconsistence(Xi∣next?)
}
2.2.3 追尾行為
????????魚向其可視區(qū)域內(nèi)的最優(yōu)方向移動的一種行為。人工魚XiX_iXi?搜索其視野內(nèi)所有伙伴中的函數(shù)最優(yōu)伙伴XjX_jXj?。如果YC/nf>δYiY_C/n_f >δY_iYC?/nf?>δYi?,表明最優(yōu)伙伴XjX_jXj?具有較高的食物濃度并且其周圍不太擁擠,則XiX_iXi?朝伙伴XjX_jXj?的方向前進(jìn)異步;否則執(zhí)行覓食行為。
偽代碼描述如下:
floatArtificial?fish::AF?follow()float Artificial_{-}fish::AF_{-}follow()floatArtificial??fish::AF??follow()
{
????Ymax=?∞;Y_max =- \infty;Ym?ax=?∞;
????for(j=0;j<friend?number;j++)for(j=0;j<friend_{-}number;j++)for(j=0;j<friend??number;j++)
????????if(di,j<Visualif(d_{i,j}<Visualif(di,j?<Visual && Yj>Ymax)Y_j >Y_{max})Yj?>Ymax?)
????????????Ymax=Yj;Xmax=Xj;{Y_{max}=Y_j;X_{max}=X_j;}Ymax?=Yj?;Xmax?=Xj?;
????nf=0;n_f=0;nf?=0;
????for(j=0;j<friend?number;j++)for(j=0;j<friend_{-}number;j++)for(j=0;j<friend??number;j++)
????????if(dmax,j<Visual)if(d_{max,j}<Visual)if(dmax,j?<Visual) nf++;{n_f++;}nf?++;
????if(Ymaxnf>δYi)if(\frac{Y_max}{n_f}>δY_i)if(nf?Ym?ax?>δYi?)
????????Xi∣next=Xi+Rand()?Step?Xmax?Xi∣∣Xmax?Xi∣∣X_{i|next}=X_i+Rand()\cdot Step\cdot \frac{X_{max}-X_i}{||X_{max}-X_i||}Xi∣next?=Xi?+Rand()?Step?∣∣Xmax??Xi?∣∣Xmax??Xi??
????elseelseelse
????????AF?prey();AF_{-}prey();AF??prey();
returnAF?foodconsistence(Xi∣next);return AF_{-}foodconsistence(X_{i|next});returnAF??foodconsistence(Xi∣next?);
}
2.2.4 隨機(jī)行為
????????隨機(jī)行為指人工魚在視野內(nèi)隨機(jī)移動,當(dāng)發(fā)現(xiàn)食物時,會向食物逐漸增多的方向快速移動。隨機(jī)行為的實現(xiàn)較為簡單,就是向視野中隨機(jī)選擇一個狀態(tài)的方向移動,本質(zhì)上講它是覓食行為的一個缺省行為。
2.3 行為選擇
????????根據(jù)所要解決的問題性質(zhì),需要對人工魚當(dāng)前環(huán)境進(jìn)行評價后來選擇一種行為。而較常用的評價方法及時選擇各行為中使得向最優(yōu)方向前進(jìn)最大的行為,也就是個性為中使得人工魚的下一個狀態(tài)最優(yōu)的行為,如果沒有能使下一狀態(tài)優(yōu)于當(dāng)前狀態(tài)的行為,則采取隨機(jī)行為。
2.4 公告板
????????公告板是記錄最優(yōu)人工魚個體狀態(tài)的地方。每條人工魚在執(zhí)行完一次迭代后將自身當(dāng)前狀態(tài)與公告板中記錄的狀態(tài)進(jìn)行比較,若優(yōu)于公告板中的狀態(tài)則用自身狀態(tài)更新,否則公告板的狀態(tài)不變。當(dāng)整個算法的迭代結(jié)束后,輸出公告板的值,就是所求的最優(yōu)值。
2.5 終止條件
????????①判斷連續(xù)多次所得的均方差小于允許的誤差;
????????②判斷一些區(qū)域的人工魚群的數(shù)量達(dá)到某個比率;
????????③連續(xù)多次所獲取的值均不得超過以尋找的極值;
????????④迭代次數(shù)到達(dá)設(shè)定的最大次數(shù)。
3 算法步驟
????????步驟1:初始化,確定種群規(guī)模N,在變量可行域內(nèi)隨機(jī)生成NNN個個體,設(shè)定人工魚的可視域 VisualVisualVisual,步長stepstepstep,擁擠度因子δδδ,嘗試次數(shù)try?numbertry_{-}numbertry??number;
????????步驟2:計算初始魚群各個體的適應(yīng)值,取最優(yōu)人工魚狀態(tài)及其值賦給公告板;
????????步驟3:個體通過覓食行為、聚群行為、追尾行為更新自己,生成新魚群;
????????步驟4:評價所有個體,若某個體優(yōu)于公告板,則將公告板更新為該個體;
????????步驟5:當(dāng)公告板上最優(yōu)解達(dá)到滿意誤差界內(nèi),算法結(jié)束;否則轉(zhuǎn)到步驟3.
4 函數(shù)優(yōu)化實例
4.1 目標(biāo)函數(shù)
f(x,y)=sin(x)xsin(y)yf(x,y) = \frac{sin(x)}{x} \frac{sin(y)}{y}f(x,y)=xsin(x)?ysin(y)?
????????????????其中, $s.t. $ x∈[?10,10]x∈[-10,10]x∈[?10,10] y∈[?10,10]y∈[-10,10]y∈[?10,10]
Matlab繪制函數(shù)圖像代碼如下:
????????函數(shù)圖像如上圖所示,該函數(shù)的極點位于(0,0)(0,0)(0,0)處,極值為1,可以看出,該非線性函數(shù)在全局極大值的周圍密布著許多局部極值,通常的尋優(yōu)算法極易陷入局部極值在各局部極值間振蕩,比較適用于驗證算法的性能。
4.2 C++源代碼(AFA)
main.cpp
#include <iostream> #include <random> #include<time.h> #include <math.h> using namespace std; double Xmax = 10, Xmin = -10;//變量的可行域 std::default_random_engine random((unsigned int)time(NULL)); std::uniform_real_distribution<double> u(Xmin, Xmax); //隨機(jī)數(shù)分布對象 std::uniform_real_distribution<double> r(-1, 1); //隨機(jī)數(shù)分布對象 struct AF { public:int dimension;//個體變量維數(shù)double *X;void Init(int Dim)//初始化函數(shù){dimension = Dim;X = new double[dimension];for (int j = 0; j < dimension; j++)*(X+j) = u(random);}double fitfunctionvalue()//個體適應(yīng)值計算函數(shù){double f = sin(*X)*sin(*(X + 1)) / ((*X) * (*(X + 1)));return f;} }; struct YUQUN {public:int N;//種群規(guī)模int Dimension;//維數(shù)double step = 0;double visual = 0;double try_number = 0;double delta = 0;AF *af;AF Bestfish;//公告板最優(yōu)解void Init(int num, int Dim, double Step, double Visual, double Try_number, double Delta)//初始化函數(shù){N = num;Dimension = Dim;step = Step;visual = Visual;try_number = Try_number;delta = Delta;af = new AF[num];for (int i = 0; i < N; i++)(af + i)->Init(Dimension);Bestfish.Init(Dimension);/*double bestfitvalue = Bestfish.fitfunctionvalue();for(int i=0;i<N;i++)if ((af + i)->fitfunctionvalue() > bestfitvalue){for (int j = 0; j < Dimension; j++)Bestfish.X[j] = (af + i)->X[j];}*/}double Distance(AF af1, AF af2)//計算兩條魚距離的函數(shù){double dist = 0;for (int i = 0; i < Dimension; i++)dist += pow(af1.X[i] - af2.X[i], 2.0);dist = sqrt(dist / float(Dimension));return dist;}void prey(int id)//覓食行為{AF AFNew;AFNew.Init(Dimension);for (int i = 0; i < try_number; i++){for (int j = 0; j < Dimension; j++)AFNew.X[j] = (af+id)->X[j] + r(random) * visual;double Yi = 0, Yj = 0;Yi = (af + id)->fitfunctionvalue();Yj = AFNew.fitfunctionvalue();if (Yi < Yj){for (int j = 0; j < Dimension; j++)(af + id)->X[j] = (af + id)->X[j] + r(random)*step*(AFNew.X[j] - (af + id)->X[j]) / Distance(AFNew, *(af+id));}else{for (int j = 0; j < Dimension; j++)(af + id)->X[j] = (af + id)->X[j] + r(random)*step;}}}void swarm(int id)//聚群行為{AF AFXc;AFXc.Init(Dimension);for (int j = 0; j < Dimension; j++) AFXc.X[j] = 0;double nf = 0;for (int i = 0; i < N; i++)if ((Distance(*(af + id), *(af + i)) < visual) && (Distance(*(af+id), *(af + i)) != 0)){nf++;for (int j = 0; j < Dimension; j++) AFXc.X[j] += (af + i)->X[j];}for (int j = 0; j < Dimension; j++)AFXc.X[j] = AFXc.X[j] / nf;//計算鄰域伙伴的中心位置double Yc= AFXc.fitfunctionvalue(), Yi=(af+id)->fitfunctionvalue();if (Yc / nf > delta*Yi){for (int j = 0; j < Dimension; j++)(af + id)->X[j] = (af + id)->X[j] + r(random)*step*(AFXc.X[j] - (af + id)->X[j]) / Distance(AFXc, *(af + id));}elseprey(id);}void follow(int id)//追尾行為{double Ymax = -INFINITY;AF AFXmax;AFXmax.Init(Dimension);for (int j = 0; j < Dimension; j++) AFXmax.X[j] = 0;for (int i = 0; i < N; i++){double dij = Distance(*(af+id), *(af+i)), Yj = (af+i)->fitfunctionvalue();if (dij != 0 && dij<visual && Yj >Ymax){Ymax = Yj;for (int j = 0; j < Dimension; j++)AFXmax.X[j] = (af+i)->X[j];}}double nf = 0;for (int i = 0; i < N; i++){double dmaxj = Distance(AFXmax,*(af+i));if (dmaxj != 0 && dmaxj < visual) nf++;}double Yi = (af + id)->fitfunctionvalue();if (Ymax / nf > delta *Yi){for (int j = 0; j < Dimension; j++)(af+id)->X[j] = (af + id)->X[j] + r(random)*step*(AFXmax.X[j] - (af+id)->X[j]) / Distance(AFXmax, *(af+id));}elseprey(id);}void evaluate(int id){if ((af + id)->fitfunctionvalue() > Bestfish.fitfunctionvalue()){for (int j = 0; j < Dimension; j++)Bestfish.X[j] = (af + id)->X[j];}}void run(int itetime)//運行函數(shù){for (int k = 0; k < itetime; k++){for (int i = 0; i < N; i++){prey(i);swarm(i);follow(i);evaluate(i);}std::cout << "第" << k + 1 << "次迭代最優(yōu)位置為Bestfish:";for (int j = 0; j<Dimension; j++){if (j == Dimension - 1) std::cout << Bestfish.X[j] <<" "<<Bestfish.fitfunctionvalue()<< endl;else std::cout << Bestfish.X[j] << ",";}}std::cout << "迭代結(jié)束后最優(yōu)位置為Bestfish:";for (int j = 0; j<Dimension; j++){if (j == Dimension - 1) std::cout << Bestfish.X[j] << " " << Bestfish.fitfunctionvalue() << endl;else std::cout << Bestfish.X[j] << ",";}}void shuchu(){for (int i = 0; i < N; i++){for (int j = 0; j < Dimension; j++)std::cout << (af + i)->X[j] << " ";std::cout << endl;}}void doAFAS(int num, int Dim, double Step, double Visual, double Try_number, double Delta,int Itetime){Init(num, Dim, Step, Visual, Try_number, Delta);shuchu();run(Itetime);} }; int main() {YUQUN yq;while (true){int num=0;std::cout << "請輸入迭代的次數(shù):";cin >> num;if (num == 0)break;else yq.doAFAS(10, 2, 0.3, 2.5, 5, 0.618, num);}system("pause");return 0; }4.3 運行結(jié)果
????????迭代20次結(jié)果:
????????迭代50次結(jié)果:
????????迭代100次結(jié)果:
5 算法特點
????????人工魚群算法有良好的克服局部極值取得全局極值的能力,并且算法中只使用目標(biāo)函數(shù)的函數(shù)值,無需目標(biāo)函數(shù)的梯度值等特殊信息,對搜索空間具有一定的自適應(yīng)能力。算法對初值無要求,對各參數(shù)的選擇也不是很敏感。但該算法獲取的僅僅是系統(tǒng)的滿意解域,對于精確解的獲取還需要進(jìn)行適當(dāng)?shù)母倪M(jìn),一些改進(jìn)的算法也被相繼提出。
????????用人工魚群算法解決離散優(yōu)化問題時,該算法具有保持探索與開發(fā)平衡的能力較差和算法運行后期搜索的盲目性較大等缺點,從而影響了該算法搜索的質(zhì)量和效率。
總結(jié)
以上是生活随笔為你收集整理的AFA人工鱼群算法函数优化求解实例C++(2020.11.4)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RichTextBox 右键显示 Con
- 下一篇: struts中文问题,struts国际化