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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

万字长文带你了解蚁群算法及求解复杂约束问题【源码实现】

發布時間:2024/9/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 万字长文带你了解蚁群算法及求解复杂约束问题【源码实现】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

蟻群算法

????蟻群算法是一種源于大自然生物世界的新的仿生進化算法,由意大利學者M. Dorigo, V. Maniezzo和A. Colorni等人于20世紀90年代初期通過模擬自然界中螞蟻集體尋徑行為而提出的一種基于種群的啟發式隨機搜索算法"。螞蟻有能力在沒有任何提示的情形下找到從巢穴到食物源的最短路徑,并且能隨環境的變化,適應性地搜索新的路徑,產生新的選擇。其根本原因是螞蟻在尋找食物時,能在其走過的路徑.上釋放一種特殊的分 泌物一信息素 (也稱外激素),隨著時間的推移該物質會逐漸揮發,后來的螞蟻選擇該路徑的概率與當時這條路徑上信息素的強度成正比。當一條路徑上通過的螞蟻越來越多時,其留下的信息素也越來越多,后來螞蟻選擇該路徑的概率也就越高,從而更增加了該路徑上的信息素強度。而強度大的信息素會吸引更多的螞蟻,從而形成一種正反饋機制。通過這種正反饋機制,螞蟻最終可以發現最短路徑。
????蟻群算法是對自然界螞蟻的尋徑方式進行模擬而得出的一種仿生算法。 螞蟻在運動過程中,能夠在它所經過的路徑.上留下信息素進行信息傳遞,而且螞蟻在運動過程中能夠感知這種物質,并以此來指導自己的運動方向。因此,由大量螞蟻組成的蟻群的集體行為便表現出一種信息正反饋現象:某一路徑上走過的螞蟻越多,則后來者選擇該路徑的概率就越大。

真實蟻群覓食過程

????為了說明蟻群算法的原理,先簡要介紹一下螞蟻搜尋食物的具體過程。在自然界中,蟻群在尋找食物時,它們總能找到一- 條從食物到巢穴之間的最優路徑。這是因為螞蟻在尋找路徑時會在路徑上釋放出一種特殊的信息素。蟻群算法的信息交互主要是通過信息素來完成的。螞蟻在運動過程中,能夠感知這種物質的存在和強度。初始階段,環境中沒有信息素的遺留,螞蟻尋找事物完全是隨機選擇路徑,隨后尋找該事物源的過程中就會受到先前螞蟻所殘留的信息素的影響,其表現為螞蟻在選擇路徑時趨向于選擇信息素濃度高的路徑。同時,信息素是一種揮發性化學物,會隨著時間的推移而慢慢地消逝。如果每只螞蟻在單位距離留下的信息素相同,那對于較短路徑上殘留的信息素濃度就相對較高,這被后來的螞蟻選擇的概率就大,從而導致這條短路徑上走的螞蟻就越多。而經過的螞蟻越多,.該路徑.上殘留的信息素就將更多,這樣使得整個螞蟻的集體行為構成了信息素的正反饋過程,最終整個蟻群會找出最優路徑。

  • 若螞蟻從A點出發,速度相同,食物在D點,則它可能隨機選擇路線ABD
    或ACD。假設初始時每條路線分配一只螞蟻, 每個時間單位行走一步。 圖所示為經過8個時間單位時的情形:走路線ABD的螞蟻到達終點;而走路線ACD的螞蟻剛好走到C點,為一半路程。
  • 圖2表示從開始算起,經過16個時間單位時的情形:走路線ABD的螞蟻
    到達終點后得到食物又返回了起點A,而走路線ACD的螞蟻剛好走到D點。
  • 假設螞蟻每經過一-處所留下的信息素為1個單位,則經過32個時間單位后,
    所有開始一起出發的螞蟻都經過不同路徑從D點取得了食物。此時ABD的路線往返了2趟,每一處的信息素為4個單位:而ACD的路線往返了一趟,每一處
    的信息素為2個單位,其比值為2: 1。
  • 尋找食物的過程繼續進行,則按信息素的指導,蟻群在ABD路線上增派一只螞蟻(共2只),而ACD路線上仍然為一只螞蟻。再經過32個時間單位后,兩條線路.上的信息素單位積累為12和4,比值為3: 1。
  • 若按以上規則繼續,蟻群在ABD路線上再增派-一只螞蟻(共3只),而ACD
    路線.上仍然為一只螞蟻。再經過32個時間單位后,兩條線路上的信息素單位積累為24和6,比值為4: 1。
  • 若繼續進行,則按信息素的指導,最終所有的螞蟻都會放棄ACD路線,而選擇ABD路線。這也就是前面所提到的正反饋效應。
  • 信息素的更新方式有兩種: 一是揮發,也就是所有路徑上的信息素以一定的比率減少,模擬自然蟻群的信息素隨時間揮發的過程:二是增強,給評價值“好”(有螞蟻走過)的邊增加信息素。

蟻群算法流程

????以TSP問題為例

我自己畫的下面算例的流程圖

????還有些相關術語,自己見代碼吧。這個代碼簡單。這個代碼都看不懂,我勸你放棄掙扎,躺平。

復雜約束算例1

??????求函數f(x, y)=20(x^2- y^2) -(1-y)^2 -3(1 +y)^2+ 0.3的最小值,其中x的取值范圍為[-5,5], y的取值范圍為[-5, 5]。這是一個有多個局部極值的函數.

matlab版代碼

%%%%%%%%%%%%%%%%%%%%蟻群算法求函數極值%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%初始化%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear all; %清除所有變量 close all; %清圖 clc; %清屏 m=20; %螞蟻個數 G_max=200; %最大迭代次數 Rho=0.9; %信息素蒸發系數 P0=0.2; %轉移概率常數 XMAX= 5; %搜索變量x最大值 XMIN= -5; %搜索變量x最小值 YMAX= 5; %搜索變量y最大值 YMIN= -5; %搜索變量y最小值 %%%%%%%%%%%%%%%%%隨機設置螞蟻初始位置%%%%%%%%%%%%%%%%%%%%%% for i=1:mX(i,1)=(XMIN+(XMAX-XMIN)*rand);X(i,2)=(YMIN+(YMAX-YMIN)*rand);Tau(i)=func(X(i,1),X(i,2)); end step=0.1; %局部搜索步長 for NC=1:G_maxlamda=1/NC;[Tau_best,BestIndex]=min(Tau);%%%%%%%%%%%%%%%%%%計算狀態轉移概率%%%%%%%%%%%%%%%%%%%%for i=1:mP(NC,i)=(Tau(BestIndex)-Tau(i))/Tau(BestIndex);end%%%%%%%%%%%%%%%%%%%%%%位置更新%%%%%%%%%%%%%%%%%%%%%%%%for i=1:m%%%%%%%%%%%%%%%%%局部搜索%%%%%%%%%%%%%%%%%%%%%%if P(NC,i)<P0temp1=X(i,1)+(2*rand-1)*step*lamda;temp2=X(i,2)+(2*rand-1)*step*lamda;else%%%%%%%%%%%%%%%%全局搜索%%%%%%%%%%%%%%%%%%%%%%%temp1=X(i,1)+(XMAX-XMIN)*(rand-0.5);temp2=X(i,2)+(YMAX-YMIN)*(rand-0.5);end%%%%%%%%%%%%%%%%%%%%%邊界處理%%%%%%%%%%%%%%%%%%%%%%%if temp1<XMINtemp1=XMIN;endif temp1>XMAXtemp1=XMAX;endif temp2<YMINtemp2=YMIN;endif temp2>YMAXtemp2=YMAX;end%%%%%%%%%%%%%%%%%%螞蟻判斷是否移動%%%%%%%%%%%%%%%%%%if func(temp1,temp2)<func(X(i,1),X(i,2))X(i,1)=temp1;X(i,2)=temp2;endend%%%%%%%%%%%%%%%%%%%%%%%更新信息素%%%%%%%%%%%%%%%%%%%%%%%for i=1:mTau(i)=(1-Rho)*Tau(i)+func(X(i,1),X(i,2));end[value,index]=min(Tau);trace(NC)=func(X(index,1),X(index,2)); end [min_value,min_index]=min(Tau); minX=X(min_index,1); %最優變量 minY=X(min_index,2) ; %最優變量 minValue=func(X(min_index,1),X(min_index,2)); %最優值 figure plot(trace) xlabel('搜索次數'); ylabel('適應度值'); title('適應度進化曲線') %%%%%%%%%%%%%%%%%%%%%%%適應度函數%%%%%%%%%%%%%%%%%%%%%%% function value=func(x,y) value =20*(x^2-y^2)^2-(1-y)^2-3*(1+y)^2+0.3; end

python版代碼

#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Author: yudengwu(余登武) # @Date : 2021/5/26 #@email:1344732766@qq.com import numpy as np from tqdm import tqdm#進度條設置 import matplotlib.pyplot as plt import matplotlib as mpl import matplotlib; matplotlib.use('TkAgg') mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默認字體 mpl.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題#============蟻群算法求函數極值================#=======適應度函數=== def func(x,y):value = 20*np.power(x*x-y*y,2)-np.power(1-y,2)-3*np.power(1+y,2)+0.3return value #=======初始化參數==== m=20 #螞蟻個數 G_max=200 #最大迭代次數 Rho=0.9 #信息素蒸發系數 P0=0.2 #轉移概率常數 XMAX= 5 #搜索變量x最大值 XMIN= -5 #搜索變量x最小值 YMAX= 5 #搜索變量y最大值 YMIN= -5 #搜索變量y最小值 X=np.zeros(shape=(m,2)) #蟻群 shape=(20, 2) Tau=np.zeros(shape=(m,)) #信息素 P=np.zeros(shape=(G_max,m)) #狀態轉移矩陣 fitneess_value_list=[] #迭代記錄最優目標函數值 #==隨機設置螞蟻初始位置== for i in range(m):#遍歷每一個螞蟻X[i,0]=np.random.uniform(XMIN,XMAX,1)[0] #初始化xX[i,1]=np.random.uniform(YMIN,YMAX,1)[0] #初始化yTau[i]=func(X[i,0],X[i,1])step=0.1; #局部搜索步長 for NC in range(G_max):#遍歷每一代lamda=1/(NC+1)BestIndex=np.argmin(Tau) #最優索引Tau_best=Tau[BestIndex] #最優信息素#計算狀態轉移概率for i in range(m):#遍歷每一個螞蟻P[NC,i]=np.abs((Tau_best-Tau[i]))/np.abs(Tau_best)+0.01 #即例最優信息素的距離#=======位置更新==========for i in range(m): # 遍歷每一個螞蟻#===局部搜索===if P[NC,i]<P0:temp1 = X[i, 0] + (2 * np.random.random() - 1) * step * lamda # x(2 * np.random.random() - 1) 轉換到【-1,1】區間temp2 = X[i,1] + (2 * np.random.random() - 1) * step * lamda #y#===全局搜索===else:temp1 = X[i, 0] + (XMAX - XMIN) * (np.random.random() - 0.5)temp2 = X[i, 0] + (YMAX - YMIN) * (np.random.random() - 0.5)#=====邊界處理=====if temp1 < XMIN:temp1 =XMINif temp1 > XMAX:temp1 =XMAXif temp2 < XMIN:temp2 =XMINif temp2 > XMAX:temp2 =XMAX##判斷螞蟻是否移動(選更優)if func(temp1, temp2) < func(X[i, 0], X[i, 1]):X[i, 0] = temp1X[i, 1]= temp2#=====更新信息素========for i in range(m): # 遍歷每一個螞蟻Tau[i] = (1 - Rho) * Tau[i] + func(X[i, 0], X[i, 1]) #(1 - Rho) * Tau[i] 信息蒸發后保留的index=np.argmin(Tau)#最小值索引value=Tau[index]#最小值fitneess_value_list.append(func(X[index,0],X[index,1])) #記錄最優目標函數值#打印結果 min_index=np.argmin(Tau)#最優值索引 minX=X[min_index,0] #最優變量x minY=X[min_index,1] #最優變量y minValue=func(X[min_index,0],X[min_index,1]) #最優目標函數值print('最優變量x',minX,end='') print('最優變量y',minY,end='\n') print('最優目標函數值',minValue)plt.plot(fitneess_value_list,label='迭代曲線') plt.legend() plt.show()

復雜約束算例2

問題如下:其中a=10

python版求解

import pandas as pd import numpy as np from tqdm import tqdm#進度條設置 import matplotlib.pyplot as plt import matplotlib; matplotlib.use('TkAgg') from pylab import * mpl.rcParams['font.sans-serif'] = ['SimHei'] mpl.rcParams['axes.unicode_minus'] = False#=======================定義一些函數==========================def calc_f(X):"""計算粒子的的適應度值,也就是目標函數值,X 的維度是 size * 2 """A = 10pi = np.pix = X[0]y = X[1]return 2 * A + x ** 2 - A * np.cos(2 * pi * x) + y ** 2 - A * np.cos(2 * pi * y)def calc_e(X):"""計算螞蟻的懲罰項,X 的維度是 size * 2 """ee = 0"""計算第一個約束的懲罰項"""e1 = X[0] + X[1] - 6ee += max(0, e1)"""計算第二個約束的懲罰項"""e2 = 3 * X[0] - 2 * X[1] - 5ee += max(0, e2)return ee#子代和父輩之間的選擇操作 def update_best(parent,parent_fitness,parent_e,child,child_fitness,child_e):"""針對不同問題,合理選擇懲罰項的閾值。本例中閾值為0.00001:param parent: 父輩個體:param parent_fitness:父輩適應度值:param parent_e :父輩懲罰項:param child: 子代個體:param child_fitness 子代適應度值:param child_e :子代懲罰項:return: 父輩 和子代中較優者、適應度、懲罰項"""# 規則1,如果 parent 和 child 都沒有違反約束,則取適應度小的if parent_e <= 0.00001 and child_e <= 0.00001:if parent_fitness <= child_fitness:return parent,parent_fitness,parent_eelse:return child,child_fitness,child_e# 規則2,如果child違反約束而parent沒有違反約束,則取parentif parent_e < 0.00001 and child_e >= 0.00001:return parent,parent_fitness,parent_e# 規則3,如果parent違反約束而child沒有違反約束,則取childif parent_e >= 0.00001 and child_e < 0.00001:return child,child_fitness,child_e# 規則4,如果兩個都違反約束,則取適應度值小的if parent_fitness <= child_fitness:return parent,parent_fitness,parent_eelse:return child,child_fitness,child_e#=======================定義一些參數========================== m=20 #螞蟻個數 G_max=200 #最大迭代次數 Rho=0.9 #信息素蒸發系數 P0=0.2 #轉移概率常數 XMAX= 2 #搜索變量x最大值 XMIN= 1 #搜索變量x最小值 YMAX= 0 #搜索變量y最大值 YMIN= -1 #搜索變量y最小值 step=0.1 #局部搜索步長 P=np.zeros(shape=(G_max,m)) #狀態轉移矩陣 fitneess_value_list=[] #迭代記錄最優目標函數值#=======================初始化螞蟻群體位置和信息素========================== def initialization():""":return: 初始化蟻群和初始信息素"""X = np.zeros(shape=(m, 2)) # 蟻群 shape=(20, 2)Tau = np.zeros(shape=(m,)) # 信息素for i in range(m): # 遍歷每一個螞蟻X[i, 0] = np.random.uniform(XMIN, XMAX, 1)[0] # 初始化xX[i, 1] =np.random.uniform(YMIN, YMAX, 1)[0] # 初始化yTau[i] = calc_f(X[i])#計算信息素return X,Tau#位置更新 def position_update(NC,P,X):""":param NC: 當前迭代次數:param P: 狀態轉移矩陣:param X: 蟻群:return: 蟻群X"""lamda = 1 / (NC + 1)# =======位置更新==========for i in range(m): # 遍歷每一個螞蟻# ===局部搜索===if P[NC, i] < P0:temp1 = X[i, 0] + (2 * np.random.random() - 1) * step * lamda # x(2 * np.random.random() - 1) 轉換到【-1,1】區間temp2 = X[i, 1] + (2 * np.random.random() - 1) * step * lamda # y# ===全局搜索===else:temp1 = X[i, 0] + (XMAX - XMIN) * (np.random.random() - 0.5)temp2 = X[i, 0] + (YMAX - YMIN) * (np.random.random() - 0.5)# =====邊界處理=====if (temp1 < XMIN) or (temp1 > XMAX):temp1 = np.random.uniform(XMIN, XMAX, 1)[0] # 初始化xif (temp2 < YMIN) or (temp2 > YMAX):temp2 = np.random.uniform(YMIN, YMAX, 1)[0] # 初始化y##判斷螞蟻是否移動(選更優)#子代螞蟻children=np.array([temp1,temp2])#子代個體螞蟻children_fit=calc_f(children) #子代目標函數值children_e=calc_e(children) #子代懲罰項parent=X[i]#父輩個體螞蟻parent_fit=calc_f(parent)#父輩目標函數值parent_e=calc_e(parent)#父輩懲罰項pbesti, pbest_fitness, pbest_e = update_best(parent, parent_fit, parent_e, children, children_fit,children_e)X[i]=pbestireturn X#信息素更新 def Update_information(Tau,X):""":param Tau: 信息素:param X: 螞蟻群:return: Tau信息素"""for i in range(m): # 遍歷每一個螞蟻Tau[i] = (1 - Rho) * Tau[i] + calc_f(X[i]) #(1 - Rho) * Tau[i] 信息蒸發后保留的return Taudef main():X,Tau=initialization() #初始化螞蟻群X 和信息素 Taufor NC in tqdm(range(G_max)): # 遍歷每一代BestIndex = np.argmin(Tau) # 最優索引Tau_best = Tau[BestIndex] # 最優信息素# 計算狀態轉移概率for i in range(m): # 遍歷每一個螞蟻P[NC, i] = np.abs((Tau_best - Tau[i])) / np.abs(Tau_best) + 0.01 # 即離最優信息素的距離# =======位置更新==========X=position_update(NC,P,X) #X.shape=(20, 2)# =====更新信息素========Tau=Update_information(Tau, X)# =====記錄最優目標函數值========index = np.argmin(Tau) # 最小值索引value = Tau[index] # 最小值fitneess_value_list.append(calc_f(X[index])) # 記錄最優目標函數值# 打印結果min_index = np.argmin(Tau) # 最優值索引minX = X[min_index, 0] # 最優變量xminY = X[min_index, 1] # 最優變量yminValue = calc_f(X[min_index]) # 最優目標函數值print('最優變量x', minX, end='')print('最優變量y', minY, end='\n')print('最優目標函數值', minValue)print('最優變量對應的懲罰項',calc_e(X[min_index]))plt.plot(fitneess_value_list, label='迭代曲線')plt.legend()plt.show()if __name__=='__main__':main()

作者:電氣-余登武。原創不易,禁止轉載

總結

以上是生活随笔為你收集整理的万字长文带你了解蚁群算法及求解复杂约束问题【源码实现】的全部內容,希望文章能夠幫你解決所遇到的問題。

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