
優(yōu)化算法—人工蜂群算法(ABC)
一、人工蜂群算法的介紹
人工蜂群算法(Artificial Bee Colony, ABC)是由Karaboga于2005年提出的一種新穎的基于群智能的全局優(yōu)化算法,其直觀背景來源于蜂群的采蜜行為,蜜蜂根據各自的分工進行不同的活動,并實現蜂群信息的共享和交流,從而找到問題的最優(yōu)解。人工蜂群算法屬于群智能算法的一種。
二、人工蜂群算法的原理
1、原理
標準的ABC算法通過模擬實際蜜蜂的采蜜機制將人工蜂群分為3類: 采蜜蜂、觀察蜂和偵察蜂。整個蜂群的目標是尋找花蜜量最大的蜜源。在標準的ABC算法中,采蜜蜂利用先前的蜜源信息尋找新的蜜源并與觀察蜂分享蜜源信息;觀察蜂在蜂房中等待并依據采蜜蜂分享的信息尋找新的蜜源;偵查蜂的任務是尋找一個新的有價值的蜜源,它們在蜂房附近隨機地尋找蜜源。
假設問題的解空間是維的,采蜜蜂與觀察蜂的個數都是,采蜜蜂的個數或觀察蜂的個數與蜜源的數量相等。則標準的ABC算法將優(yōu)化問題的求解過程看成是在維搜索空間中進行搜索。每個蜜源的位置代表問題的一個可能解,蜜源的花蜜量對應于相應的解的適應度。一個采蜜蜂與一個蜜源是相對應的。與第個蜜源相對應的采蜜蜂依據如下公式尋找新的蜜源:
其中是區(qū)間
上的隨機數,
。標準的ABC算法將新生成的可能解
與原來的解
作比較,并采用貪婪選擇策略保留較好的解。每一個觀察蜂依據概率選擇一個蜜源,概率公式為
其中,是可能解
的適應值。對于被選擇的蜜源,觀察蜂根據上面概率公式搜尋新的可能解。當所有的采蜜蜂和觀察蜂都搜索完整個搜索空間時,如果一個蜜源的適應值在給定的步驟內(定義為控制參數“l(fā)imit”) 沒有被提高, 則丟棄該蜜源,而與該蜜源相對應的采蜜蜂變成偵查蜂,偵查蜂通過已下公式搜索新的可能解。
其中,r是區(qū)間上的隨機數,是第d維的下界和上界。
2、流程
初始化;
重復以下過程:
將采蜜蜂與蜜源一一對應,根據上面第一個公式更新蜜源信息,同時確定蜜源的花蜜量;
觀察蜂根據采蜜蜂所提供的信息采用一定的選擇策略選擇蜜源,根據第一個公式更新蜜源信息,同時確定蜜源的花蜜量;
確定偵查蜂,并根據第三個公式尋找新的蜜源;數據分析師培訓
記憶迄今為止最好的蜜源;
判斷終止條件是否成立;
三、人工蜂群算法用于求解函數優(yōu)化問題
對于函數
其中。
代碼:
[cpp] view plain copy 在CODE上查看代碼片派生到我的代碼片
#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<cmath>
#include<fstream>
#include<iomanip>
using namespace std;
const int NP=40;//種群的規(guī)模,采蜜蜂+觀察蜂
const int FoodNumber=NP/2;//食物的數量,為采蜜蜂的數量
const int limit=20;//限度,超過這個限度沒有更新采蜜蜂變成偵查蜂
const int maxCycle=10000;//停止條件
/*****函數的特定參數*****/
const int D=2;//函數的參數個數
const double lb=-100;//函數的下界
const double ub=100;//函數的上界
double result[maxCycle]={0};
/*****種群的定義****/
struct BeeGroup
{
double code[D];//函數的維數
double trueFit;//記錄真實的最小值
double fitness;
double rfitness;//相對適應值比例
int trail;//表示實驗的次數,用于與limit作比較
}Bee[FoodNumber];
BeeGroup NectarSource[FoodNumber];//蜜源,注意:一切的修改都是針對蜜源而言的
BeeGroup EmployedBee[FoodNumber];//采蜜蜂
BeeGroup OnLooker[FoodNumber];//觀察蜂
BeeGroup BestSource;//記錄最好蜜源
/*****函數的聲明*****/
double random(double, double);//產生區(qū)間上的隨機數
void initilize();//初始化參數
double calculationTruefit(BeeGroup);//計算真實的函數值
double calculationFitness(double);//計算適應值
void CalculateProbabilities();//計算輪盤賭的概率
void evalueSource();//評價蜜源
void sendEmployedBees();
void sendOnlookerBees();
void sendScoutBees();
void MemorizeBestSource();
/*******主函數*******/
int main()
{
ofstream output;
output.open("dataABC.txt");
srand((unsigned)time(NULL));
initilize();//初始化
MemorizeBestSource();//保存最好的蜜源
//主要的循環(huán)
int gen=0;
while(gen<maxCycle)
{
sendEmployedBees();
CalculateProbabilities();
sendOnlookerBees();
MemorizeBestSource();
sendScoutBees();
MemorizeBestSource();
output<<setprecision(30)<<BestSource.trueFit<<endl;
gen++;
}
output.close();
cout<<"運行結束!!"<<endl;
return 0;
}
/*****函數的實現****/
double random(double start, double end)//隨機產生區(qū)間內的隨機數
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
void initilize()//初始化參數
{
int i,j;
for (i=0;i<FoodNumber;i++)
{
for (j=0;j<D;j++)
{
NectarSource[i].code[j]=random(lb,ub);
EmployedBee[i].code[j]=NectarSource[i].code[j];
OnLooker[i].code[j]=NectarSource[i].code[j];
BestSource.code[j]=NectarSource[0].code[j];
}
/****蜜源的初始化*****/
NectarSource[i].trueFit=calculationTruefit(NectarSource[i]);
NectarSource[i].fitness=calculationFitness(NectarSource[i].trueFit);
NectarSource[i].rfitness=0;
NectarSource[i].trail=0;
/****采蜜蜂的初始化*****/
EmployedBee[i].trueFit=NectarSource[i].trueFit;
EmployedBee[i].fitness=NectarSource[i].fitness;
EmployedBee[i].rfitness=NectarSource[i].rfitness;
EmployedBee[i].trail=NectarSource[i].trail;
/****觀察蜂的初始化****/
OnLooker[i].trueFit=NectarSource[i].trueFit;
OnLooker[i].fitness=NectarSource[i].fitness;
OnLooker[i].rfitness=NectarSource[i].rfitness;
OnLooker[i].trail=NectarSource[i].trail;
}
/*****最優(yōu)蜜源的初始化*****/
BestSource.trueFit=NectarSource[0].trueFit;
BestSource.fitness=NectarSource[0].fitness;
BestSource.rfitness=NectarSource[0].rfitness;
BestSource.trail=NectarSource[0].trail;
}
double calculationTruefit(BeeGroup bee)//計算真實的函數值
{
double truefit=0;
/******測試函數1******/
truefit=0.5+(sin(sqrt(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))*sin(sqrt(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))-0.5)
/((1+0.001*(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))*(1+0.001*(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1])));
return truefit;
}
double calculationFitness(double truefit)//計算適應值
{
double fitnessResult=0;
if (truefit>=0)
{
fitnessResult=1/(truefit+1);
}else
{
fitnessResult=1+abs(truefit);
}
return fitnessResult;
}
void sendEmployedBees()//修改采蜜蜂的函數
{
int i,j,k;
int param2change;//需要改變的維數
double Rij;//[-1,1]之間的隨機數
for (i=0;i<FoodNumber;i++)
{
param2change=(int)random(0,D);//隨機選取需要改變的維數
/******選取不等于i的k********/
while (1)
{
k=(int)random(0,FoodNumber);
if (k!=i)
{
break;
}
}
for (j=0;j<D;j++)
{
EmployedBee[i].code[j]=NectarSource[i].code[j];
}
/*******采蜜蜂去更新信息*******/
Rij=random(-1,1);
EmployedBee[i].code[param2change]=NectarSource[i].code[param2change]+Rij*(NectarSource[i].code[param2change]-NectarSource[k].code[param2change]);
/*******判斷是否越界********/
if (EmployedBee[i].code[param2change]>ub)
{
EmployedBee[i].code[param2change]=ub;
}
if (EmployedBee[i].code[param2change]<lb)
{
EmployedBee[i].code[param2change]=lb;
}
EmployedBee[i].trueFit=calculationTruefit(EmployedBee[i]);
EmployedBee[i].fitness=calculationFitness(EmployedBee[i].trueFit);
/******貪婪選擇策略*******/
if (EmployedBee[i].trueFit<NectarSource[i].trueFit)
{
for (j=0;j<D;j++)
{
NectarSource[i].code[j]=EmployedBee[i].code[j];
}
NectarSource[i].trail=0;
NectarSource[i].trueFit=EmployedBee[i].trueFit;
NectarSource[i].fitness=EmployedBee[i].fitness;
}else
{
NectarSource[i].trail++;
}
}
}
void CalculateProbabilities()//計算輪盤賭的選擇概率
{
int i;
double maxfit;
maxfit=NectarSource[0].fitness;
for (i=1;i<FoodNumber;i++)
{
if (NectarSource[i].fitness>maxfit)
maxfit=NectarSource[i].fitness;
}
for (i=0;i<FoodNumber;i++)
{
NectarSource[i].rfitness=(0.9*(NectarSource[i].fitness/maxfit))+0.1;
}
}
void sendOnlookerBees()//采蜜蜂與觀察蜂交流信息,觀察蜂更改信息
{
int i,j,t,k;
double R_choosed;//被選中的概率
int param2change;//需要被改變的維數
double Rij;//[-1,1]之間的隨機數
i=0;
t=0;
while(t<FoodNumber)
{
R_choosed=random(0,1);
if(R_choosed<NectarSource[i].rfitness)//根據被選擇的概率選擇
{
t++;
param2change=(int)random(0,D);
/******選取不等于i的k********/
while (1)
{
k=(int)random(0,FoodNumber);
if (k!=i)
{
break;
}
}
for(j=0;j<D;j++)
{
OnLooker[i].code[j]=NectarSource[i].code[j];
}
/****更新******/
Rij=random(-1,1);
OnLooker[i].code[param2change]=NectarSource[i].code[param2change]+Rij*(NectarSource[i].code[param2change]-NectarSource[k].code[param2change]);
/*******判斷是否越界*******/
if (OnLooker[i].code[param2change]<lb)
{
OnLooker[i].code[param2change]=lb;
}
if (OnLooker[i].code[param2change]>ub)
{
OnLooker[i].code[param2change]=ub;
}
OnLooker[i].trueFit=calculationTruefit(OnLooker[i]);
OnLooker[i].fitness=calculationFitness(OnLooker[i].trueFit);
/****貪婪選擇策略******/
if (OnLooker[i].trueFit<NectarSource[i].trueFit)
{
for (j=0;j<D;j++)
{
NectarSource[i].code[j]=OnLooker[i].code[j];
}
NectarSource[i].trail=0;
NectarSource[i].trueFit=OnLooker[i].trueFit;
NectarSource[i].fitness=OnLooker[i].fitness;
}else
{
NectarSource[i].trail++;
}
}
i++;
if (i==FoodNumber)
{
i=0;
}
}
}
/*******只有一只偵查蜂**********/
void sendScoutBees()//判斷是否有偵查蜂的出現,有則重新生成蜜源
{
int maxtrialindex,i,j;
double R;//[0,1]之間的隨機數
maxtrialindex=0;
for (i=1;i<FoodNumber;i++)
{
if (NectarSource[i].trail>NectarSource[maxtrialindex].trail)
{
maxtrialindex=i;
}
}
if(NectarSource[maxtrialindex].trail>=limit)
{
/*******重新初始化*********/
for (j=0;j<D;j++)
{
R=random(0,1);
NectarSource[maxtrialindex].code[j]=lb+R*(ub-lb);
}
NectarSource[maxtrialindex].trail=0;
NectarSource[maxtrialindex].trueFit=calculationTruefit(NectarSource[maxtrialindex]);
NectarSource[maxtrialindex].fitness=calculationFitness(NectarSource[maxtrialindex].trueFit);
}
}
void MemorizeBestSource()//保存最優(yōu)的蜜源
{
int i,j;
for (i=1;i<FoodNumber;i++)
{
if (NectarSource[i].trueFit<BestSource.trueFit)
{
for (j=0;j<D;j++)
{
BestSource.code[j]=NectarSource[i].code[j];
}
BestSource.trueFit=NectarSource[i].trueFit;
}
}
}
收斂曲線:
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
CDA 數據分析師報考條件詳解與準備指南? ? 在數據驅動決策的時代浪潮下,CDA 數據分析師認證愈發(fā)受到矚目,成為眾多有志投身數 ...
2025-07-18剛入職場或是在職場正面臨崗位替代、技能更新、人機協(xié)作等焦慮的打工人,想要找到一條破解職場焦慮和升職瓶頸的系統(tǒng)化學習提升 ...
2025-07-182025被稱為“AI元年”,而AI,與數據密不可分。網易公司創(chuàng)始人丁磊在《AI思維:從數據中創(chuàng)造價值的煉金術 ...
2025-07-18CDA 數據分析師:數據時代的價值挖掘者 在大數據席卷全球的今天,數據已成為企業(yè)核心競爭力的重要組成部分。從海量數據中提取有 ...
2025-07-18SPSS 賦值后數據不顯示?原因排查與解決指南? 在 SPSS( Statistical Package for the Social Sciences)數據分析過程中,變量 ...
2025-07-18在 DBeaver 中利用 MySQL 實現表數據同步操作指南? ? 在數據庫管理工作中,將一張表的數據同步到另一張表是常見需求,這有助于 ...
2025-07-18數據分析師的技能圖譜:從數據到價值的橋梁? 在數據驅動決策的時代,數據分析師如同 “數據翻譯官”,將冰冷的數字轉化為清晰的 ...
2025-07-17Pandas 寫入指定行數據:數據精細化管理的核心技能? 在數據處理的日常工作中,我們常常需要面對這樣的場景:在龐大的數據集里精 ...
2025-07-17解碼 CDA:數據時代的通行證? 在數字化浪潮席卷全球的今天,當企業(yè)決策者盯著屏幕上跳動的數據曲線尋找增長密碼,當科研人員在 ...
2025-07-17CDA 精益業(yè)務數據分析:數據驅動業(yè)務增長的實戰(zhàn)方法論 在企業(yè)數字化轉型的浪潮中,“數據分析” 已從 “加分項” 成為 “必修課 ...
2025-07-16MySQL 中 ADD KEY 與 ADD INDEX 詳解:用法、差異與優(yōu)化實踐 在 MySQL 數據庫表結構設計中,索引是提升查詢性能的核心手段。無論 ...
2025-07-16解析 MySQL Update 語句中 “query end” 狀態(tài):含義、成因與優(yōu)化指南? 在 MySQL 數據庫的日常運維與開發(fā)中,開發(fā)者和 DBA 常會 ...
2025-07-16如何考取數據分析師證書:以 CDA 為例? ? 在數字化浪潮席卷各行各業(yè)的當下,數據分析師已然成為企業(yè)挖掘數據價值、驅動決策的 ...
2025-07-15CDA 精益業(yè)務數據分析:驅動企業(yè)高效決策的核心引擎? 在數字經濟時代,企業(yè)面臨著前所未有的數據洪流,如何從海量數據中提取有 ...
2025-07-15MySQL 無外鍵關聯表的 JOIN 實戰(zhàn):數據整合的靈活之道? 在 MySQL 數據庫的日常操作中,我們經常會遇到需要整合多張表數據的場景 ...
2025-07-15Python Pandas:數據科學的瑞士軍刀? ? 在數據驅動的時代,面對海量、復雜的數據,如何高效地進行處理、分析和挖掘成為關鍵。 ...
2025-07-15用 SQL 生成逆向回滾 SQL:數據操作的 “后悔藥” 指南? 在數據庫操作中,誤刪數據、錯改字段或誤執(zhí)行批量更新等問題時有發(fā)生。 ...
2025-07-14t檢驗與Wilcoxon檢驗的選擇:何時用t.test,何時用wilcox.test? t 檢驗與 Wilcoxon 檢驗的選擇:何時用 t.test,何時用 wilcox. ...
2025-07-14AI 浪潮下的生存與進階: CDA數據分析師—開啟新時代職業(yè)生涯的鑰匙(深度研究報告、發(fā)展指導白皮書) 發(fā)布機構:CDA數據科 ...
2025-07-13LSTM 模型輸入長度選擇技巧:提升序列建模效能的關鍵? 在循環(huán)神經網絡(RNN)家族中,長短期記憶網絡(LSTM)憑借其解決長序列 ...
2025-07-11