Python實現(xiàn)蟻群算法
1、引言
在自然界中各種生物群體顯現(xiàn)出來的智能近幾十年來得到了學者們的廣泛關注,學者們通過對簡單生物體的群體行為進行模擬,進而提出了群智能算法。其中,模擬蟻群覓食過程的蟻群優(yōu)化算法(Ant Colony Optimization, ACO)和模擬鳥群運動方式的粒子群算法(Particle Swarm Optimization, PSO)是兩種最主要的群智能算法。
蟻群算法是一種源于大自然生物世界的新的仿生進化算法,由意大利學者M. Dorigo, V. Maniezzo和A.Colorni等人于20世紀90年代初期通過模擬自然界中螞蟻集體尋徑行為而提出的一種基于種群的啟發(fā)式隨機搜索算法"。螞蟻有能力在沒有任何提示的情形下找到從巢穴到食物源的最短路徑,并且能隨環(huán)境的變化,適應性地搜索新的路徑,產生新的選擇。其根本原因是螞蟻在尋找食物時,能在其走過的路徑上釋放一種特殊的分泌物——信息素(也稱外激素),隨著時間的推移該物質會逐漸揮發(fā),后來的螞蟻選擇該路徑的概率與當時這條路徑上信息素的強度成正比。當一條路徑上通過的螞蟻越來越多時,其留下的信息素也越來越多,后來螞蟻選擇該路徑的概率也就越高,從而更增加了該路徑上的信息素強度。而強度大的信息素會吸引更多的螞蟻,從而形成一種正反饋機制。通過這種正反饋機制,螞蟻最終可以發(fā)現(xiàn)最短路徑。
最早的蟻群算法是螞蟻系統(tǒng)(Ant System,AS),研究者們根據(jù)不同的改進策略對螞蟻系統(tǒng)進行改進并開發(fā)了不同版本的蟻群算法,并成功地應用于優(yōu)化領域。用該方法求解旅行商(TSP)問題、分配問題、車間作業(yè)調度(job-shop)問題,取得了較好的試驗結果。蟻群算法具有分布式計算、無中心控制和分布式個體之間間接通信等特征,易于與其他優(yōu)化算法相結合,它通過簡單個體之間的協(xié)作表現(xiàn)出了求解復雜問題的能力,已被廣泛應用于求解優(yōu)化問題。蟻群算法相對而言易于實現(xiàn),且算法中并不涉及復雜的數(shù)學操作,其處理過程對計算機的軟硬件要求也不高,因此對它的研究在理論和實踐中都具有重要的意義。
目前,國內外的許多研究者和研究機構都開展了對蟻群算法理論和應用的研究,蟻群算法已成為國際計算智能領域關注的熱點課題。雖然目前蟻群算法沒有形成嚴格的理論基礎,但其作為一種新興的進化算法已在智能優(yōu)化等領域表現(xiàn)出了強大的生命力。
2 蟻群算法理論
蟻群算法是對自然界螞蟻的尋徑方式進行模擬而得出的一種仿生算法。螞蟻在運動過程中,能夠在它所經過的路徑上留下信息素進行信息傳遞,而且螞蟻在運動過程中能夠感知這種物質,并以此來指導自己的運動方向。因此,由大量螞蟻組成的蟻群的集體行為便表現(xiàn)出一種信息正反饋現(xiàn)象:某一路徑上走過的螞蟻越多,則后來者選擇該路徑的概率就越大。
3 算法理論圖解
(1)在自然界中,螞蟻的食物源總是隨機分散于蟻巢周圍,在蟻群協(xié)調、分工、合作后總能找到一條通往食物源的最短路徑?,F(xiàn)實中,我們能觀察到大量螞蟻在巢穴與食物源之間形成近乎直線的路徑,而不是曲線、圓等其他形狀,如圖(a)。
(2)螞蟻群體不僅能完成復雜的任務,并且還能適應環(huán)境的變化,如在蟻群運動路線上突然出現(xiàn)障礙物時,一開始各只螞蟻分布是均勻的,不管路徑長短,螞蟻總是先按同等概率選擇各條路徑,如圖(b)。
(3)螞蟻在運動過程中,能在其經過的路徑上留下信息素,并且能感知到這種物質的存在及其強度,并以此指導自己運動的方向,螞蟻傾向于信息素濃度高的方向移動。在相同時間內較短路徑上的信息素量就遺留得較多,則選擇較短路徑得螞蟻也隨即增多,如圖(c)。
(4)不難看出,由于大量螞蟻組成得蟻群集體行為表現(xiàn)出的一種信息正反饋現(xiàn)象,在某一路徑上走過的螞蟻越多,則后來者選擇該路徑的概率就越大,螞蟻個體質檢就是通過這種信息交流機制來搜索食物,并最終沿著最短路徑行進,如圖(d)。
4 人工蟻群優(yōu)化過程
基于以上真實蟻群尋找食物時的最優(yōu)路徑選擇問題,可以構造人工蟻群,來解決最優(yōu)化問題,如TSP問題。人工蟻群中把具有簡單功能的工作單元看作螞蟻。二者的相似之處在于都是優(yōu)先選擇信息素濃度大的路徑。較短路徑的信息素濃度高,所以能夠最終被所有螞蟻選擇,也就是最終的優(yōu)化結果。兩者的區(qū)別在于人工蟻群有一定的記憶能力,能夠記憶已經訪問過的節(jié)點。同時,人工蟻群再選擇下一條路徑的時候是按一定算法規(guī)律有意識地尋找最短路徑,而不是盲目的。例如在TSP問題中,可以預先知道當前城市到下一個目的地的距離。
在TSP問題的人工蟻群算法中,假設m只螞蟻在圖的相鄰節(jié)點間移動,從而協(xié)作異步地得到問題的解。每只螞蟻的一步轉移概率由圖中的每條邊上的兩類參數(shù)決定:一是信息素值,也稱信息素痕跡;二是可見度,即先驗值。
信息素的更新方式有兩種:一是揮發(fā),也就是所有路徑上的信息素以一定的比率減少,模擬自然蟻群的信息素隨時間揮發(fā)的過程;二是增強,給評價值“好”(有螞蟻走過)的邊增加信息素。
螞蟻向下一個目標的運動是通過一個隨機原則來實現(xiàn)的,也就是運用當前所在節(jié)點存儲的信息,計算出下一步可達節(jié)點的概率,并按此概率實現(xiàn)一步移動,如此往復,越來越接近最優(yōu)解。
螞蟻在尋找過程中,或在找到一個解后,會評估該解或解的一部分的優(yōu)化程度,并把評價信息保存在相關連接的信息素中。
這種算法有別于傳統(tǒng)編程模式,其優(yōu)勢在于,避免了冗長的編程和籌劃,程序本身是基于一定規(guī)則的隨機運行來尋找最佳配置。也就是說,當程序最開始找到目標的時候,路徑可能不是最優(yōu)的。但是,程序可以通過螞蟻尋找食物的時候的信息素原理,不斷地去修正原來的路線,使整個路線越來越短,也就是說,程序執(zhí)行的時間越長(在程序中也就是迭代次數(shù)不能太少,同時還要保證一定的螞蟻數(shù)量),所獲得的路徑就越可能接近最優(yōu)路徑。這看起來很類似與我們所見的由無數(shù)例子進行歸納概括形成最佳路徑的過程。實際上好似是程序的一個自我學習的過程。
這種優(yōu)化過程的本質在于:
選擇機制:信息素越多的路徑,被選擇的概率越大。
更新機制:路徑上面的信息素會隨螞蟻的經過而增長,而且同時也隨時間的推移逐漸揮發(fā)消失。
協(xié)調機制:螞蟻間實際上是通過分泌物來互相通信、協(xié)同工作的。
蟻群算法正是充分利用了選擇、更新和協(xié)調的優(yōu)化機制,即通過個體之間的信息交流與相互協(xié)作最終找到最優(yōu)解,使它具有很強的發(fā)現(xiàn)較優(yōu)解的能力。
事實上,每只螞蟻并不是像我們想象的需要知道整個世界的信息,他們其實只關心很小范圍內的眼前信息,而且根據(jù)這些局部信息利用幾條簡單的規(guī)則進行決策,但是,當集群里有無數(shù)螞蟻的時候,復雜性的行為就會凸現(xiàn)出來。這就是人工生命、復雜性科學解釋的規(guī)律!那么,這些簡單規(guī)則是什么呢?下面詳細說明:
1、范圍:
螞蟻觀察到的范圍是一個方格世界,螞蟻有一個參數(shù)為速度半徑(一般是3),那么它能觀察到的范圍就是3*3個方格世界,并且能移動的距離也在這個范圍之內。
2、環(huán)境:
螞蟻所在的環(huán)境是一個虛擬的世界,其中有障礙物,有別的螞蟻,還有信息素,信息素有兩種,一種是找到食物的螞蟻灑下的食物信息素,一種是找到窩的螞蟻灑下的窩的信息素。每個螞蟻都僅僅能感知它范圍內的環(huán)境信息。環(huán)境以一定的速率讓信息素消失。
3、覓食規(guī)則:
在每只螞蟻能感知的范圍內尋找是否有食物,如果有就直接過去。否則看是否有信息素,并且比較在能感知的范圍內哪一點的信息素最多,這樣,它就朝信息素多的地方走,并且每只螞蟻多會以小概率犯錯誤,從而并不是往信息素最多的點移動。螞蟻找窩的規(guī)則和上面一樣,只不過它對窩的信息素做出反應,而對食物信息素沒反應。
4、移動規(guī)則:
每只螞蟻都朝向信息素最多的方向移,并且,當周圍沒有信息素指引的時候,螞蟻會按照自己原來運動的方向慣性的運動下去,并且,在運動的方向有一個隨機的小的擾動。為了防止螞蟻原地轉圈,它會記住最近剛走過了哪些點,如果發(fā)現(xiàn)要走的下一點已經在最近走過了,它就會盡量避開。
5、避障規(guī)則:
如果螞蟻要移動的方向有障礙物擋住,它會隨機的選擇另一個方向,并且有信息素指引的話,它會按照覓食的規(guī)則行為。
6、播撒信息素規(guī)則:
每只螞蟻在剛找到食物或者窩的時候撒發(fā)的信息素最多,并隨著它走遠的距離,播撒的信息素越來越少。
根據(jù)這幾條規(guī)則,螞蟻之間并沒有直接的關系,但是每只螞蟻都和環(huán)境發(fā)生交互,而通過信息素這個紐帶,實際上把各個螞蟻之間關聯(lián)起來了。比如,當一只螞蟻找到了食物,它并沒有直接告訴其它螞蟻這兒有食物,而是向環(huán)境播撒信息素,當其它的螞蟻經過它附近的時候,就會感覺到信息素的存在,進而根據(jù)信息素的指引找到了食物。
那么,螞蟻究竟是怎么找到食物的呢?
在沒有螞蟻找到食物的時候,環(huán)境沒有有用的信息素,那么螞蟻為什么會相對有效的找到食物呢?這要歸功于螞蟻的移動規(guī)則,尤其是在沒有信息素時候的移動規(guī)則。首先,它要能盡量保持某種慣性,這樣使得螞蟻盡量向前方移動(開始,這個前方是隨機固定的一個方向),而不是原地無謂的打轉或者震動;其次,螞蟻要有一定的隨機性,雖然有了固定的方向,但它也不能像粒子一樣直線運動下去,而是有一個隨機的干擾。這樣就使得螞蟻運動起來具有了一定的目的性,盡量保持原來的方向,但又有新的試探,尤其當碰到障礙物的時候它會立即改變方向,這可以看成一種選擇的過程,也就是環(huán)境的障礙物讓螞蟻的某個方向正確,而其他方向則不對。這就解釋了為什么單個螞蟻在復雜的諸如迷宮的地圖中仍然能找到隱蔽得很好的食物。當然,在有一只螞蟻找到了食物的時候,其他螞蟻會沿著信息素很快找到食物的。
螞蟻如何找到最短路徑的?
這一是要歸功于信息素,另外要歸功于環(huán)境,具體說是計算機時鐘。信息素多的地方顯然經過這里的螞蟻會多,因而會有更多的螞蟻聚集過來。假設有兩條路從窩通向食物,開始的時候,走這兩條路的螞蟻數(shù)量同樣多(或者較長的路上螞蟻多,這也無關緊要)。當螞蟻沿著一條路到達終點以后會馬上返回來,這樣,短的路螞蟻來回一次的時間就短,這也意味著重復的頻率就快,因而在單位時間里走過的螞蟻數(shù)目就多,灑下的信息素自然也會多,自然會有更多的螞蟻被吸引過來,從而灑下更多的信息素……;而長的路正相反,因此,越來越多地螞蟻聚集到較短的路徑上來,最短的路徑就近似找到了。也許有人會問局部最短路徑和全局最短路的問題,實際上螞蟻逐漸接近全局最短路的,為什么呢?這源于螞蟻會犯錯誤,也就是它會按照一定的概率不往信息素高的地方走而另辟蹊徑,這可以理解為一種創(chuàng)新,這種創(chuàng)新如果能縮短路途,那么根據(jù)剛才敘述的原理,更多的螞蟻會被吸引過來。
5 基本蟻群算法及其流程
5.1 蟻群算法公式
蟻群算法實際上是正反饋原理和啟發(fā)式算法相結合的一種算法。在選擇路徑時,螞蟻不僅利用了路徑上的信息素,而且用到了城市間距離的倒數(shù)作為啟發(fā)式因子。實驗結果表明,ant-cycle模型比ant-quantity和ant-density模型有更好的性能。這是因為ant-cycle模型利用全局信息更新路徑上的信息素量,而ant-quantity和ant-density模型使用局部信息。
5.2 蟻群算法程序概括
(1)參數(shù)初始化
在尋最短路錢,需對程序各個參數(shù)進行初始化,蟻群規(guī)模m、信息素重要程度因子α、啟發(fā)函數(shù)重要程度因子β、信息素會發(fā)因子、最大迭代次數(shù)ddcs_max,初始迭代值為ddcs=1。
(2)構建解空間
將每只螞蟻隨機放置在不同的出發(fā)地點,對螞蟻訪問行為按照公式計算下一個訪問的地點,直到所有螞蟻訪問完所有地點。
(3)更新信息素
計算每只螞蟻經過的路徑總長Lk,記錄當前循環(huán)中的最優(yōu)路徑,同時根據(jù)公式對各個地點間連接路徑上的信息素濃度進行更新。
(4)判斷終止
迭代次數(shù)達到最大值前,清空螞蟻經過的記錄,并返回步驟2。
5.3 流程圖
6 案例實現(xiàn)
6.1 案例1
求解函數(shù):的最小值,其中x的取值范圍為[-5,5], y的取值范圍為[-5, 5]。這是一個有多個局部極值的函數(shù)。
6.2 Python實現(xiàn)
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 # 解決保存圖像是負號'-'顯示為方塊的問題 #============蟻群算法求函數(shù)極值================ #=======適應度函數(shù)===== 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.3 return value #=======初始化參數(shù)==== m=20 #螞蟻個數(shù) G_max=200 #最大迭代次數(shù) Rho=0.9 #信息素蒸發(fā)系數(shù) P0=0.2 #轉移概率常數(shù) 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)) #狀態(tài)轉移矩陣 fitneess_value_list=[] #迭代記錄最優(yōu)目標函數(shù)值 #==隨機設置螞蟻初始位置== for i in range(m):#遍歷每一個螞蟻 X[i,0]=np.random.uniform(XMIN,XMAX,1)[0] #初始化x X[i,1]=np.random.uniform(YMIN,YMAX,1)[0] #初始化y Tau[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) #最優(yōu)索引 Tau_best=Tau[BestIndex] #最優(yōu)信息素 #==計算狀態(tài)轉移概率=== for i in range(m):#遍歷每一個螞蟻 P[NC,i]=np.abs((Tau_best-Tau[i]))/np.abs(Tau_best)+0.01 #即例最優(yōu)信息素的距離 #=======位置更新========== 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】區(qū)間 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 =XMIN if temp1 > XMAX: temp1 =XMAX if temp2 < XMIN: temp2 =XMIN if temp2 > XMAX: temp2 =XMAX #==判斷螞蟻是否移動(選更優(yōu)=== if func(temp1, temp2) < func(X[i, 0], X[i, 1]): X[i, 0] = temp1 X[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] 信息蒸發(fā)后保留的 index=np.argmin(Tau)#最小值索引 value=Tau[index]#最小值 fitneess_value_list.append(func(X[index,0],X[index,1])) #記錄最優(yōu)目標函數(shù)值 #==打印結果=== min_index=np.argmin(Tau)#最優(yōu)值索引 minX=X[min_index,0] #最優(yōu)變量x minY=X[min_index,1] #最優(yōu)變量y minValue=func(X[min_index,0],X[min_index,1]) #最優(yōu)目標函數(shù)值 print('最優(yōu)變量x',minX,end='') print('最優(yōu)變量y',minY,end='\n') print('最優(yōu)目標函數(shù)值',minValue) plt.plot(fitneess_value_list,label='迭代曲線') plt.legend() plt.show()
6.3 結果
最優(yōu)變量x 5.0最優(yōu)變量y 5.0 最優(yōu)目標函數(shù)值 -123.7
6.4 案例2
6.5 Python實現(xiàn)
#====================導入相關庫============================= 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 #=======================定義函數(shù)========================== #=======目標函數(shù)===== def calc_f(X): """計算粒子的的適應度值,也就是目標函數(shù)值,X 的維度是 size * 2 """ A = 10 pi = np.pi x = X[0] y = X[1] return 2 * A + x ** 2 - A * np.cos(2 * pi * x) + y ** 2 - A * np.cos(2 * pi * y) #====懲罰項函數(shù)====== def calc_e(X): """計算螞蟻的懲罰項,X 的維度是 size * 2 """ ee = 0 """計算第一個約束的懲罰項""" e1 = X[0] + X[1] - 6 ee += max(0, e1) """計算第二個約束的懲罰項""" e2 = 3 * X[0] - 2 * X[1] - 5 ee += 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: 父輩 和子代中較優(yōu)者、適應度、懲罰項 """ # 規(guī)則1,如果 parent 和 child 都沒有違反約束,則取適應度小的 if parent_e <= 0.00001 and child_e <= 0.00001: if parent_fitness <= child_fitness: return parent,parent_fitness,parent_e else: return child,child_fitness,child_e # 規(guī)則2,如果child違反約束而parent沒有違反約束,則取parent if parent_e < 0.00001 and child_e >= 0.00001: return parent,parent_fitness,parent_e # 規(guī)則3,如果parent違反約束而child沒有違反約束,則取child if parent_e >= 0.00001 and child_e < 0.00001: return child,child_fitness,child_e # 規(guī)則4,如果兩個都違反約束,則取適應度值小的 if parent_fitness <= child_fitness: return parent,parent_fitness,parent_e else: return child,child_fitness,child_e #=======================初始化參數(shù)========================== m=20 #螞蟻個數(shù) G_max=200 #最大迭代次數(shù) Rho=0.9 #信息素蒸發(fā)系數(shù) P0=0.2 #轉移概率常數(shù) XMAX= 2 #搜索變量x最大值 XMIN= 1 #搜索變量x最小值 YMAX= 0 #搜索變量y最大值 YMIN= -1 #搜索變量y最小值 step=0.1 #局部搜索步長 P=np.zeros(shape=(G_max,m)) #狀態(tài)轉移矩陣 fitneess_value_list=[] #迭代記錄最優(yōu)目標函數(shù)值 #=======================初始化螞蟻群體位置和信息素========================== 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] # 初始化x X[i, 1] =np.random.uniform(YMIN, YMAX, 1)[0] # 初始化y Tau[i] = calc_f(X[i])#計算信息素 return X,Tau #===位置更新==== def position_update(NC,P,X): """ :param NC: 當前迭代次數(shù) :param P: 狀態(tài)轉移矩陣 :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】區(qū)間 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] # 初始化x if (temp2 < YMIN) or (temp2 > YMAX): temp2 = np.random.uniform(YMIN, YMAX, 1)[0] # 初始化y #=====判斷螞蟻是否移動(選更優(yōu))===== #==子代螞蟻== children=np.array([temp1,temp2])#子代個體螞蟻 children_fit=calc_f(children) #子代目標函數(shù)值 children_e=calc_e(children) #子代懲罰項 parent=X[i]#父輩個體螞蟻 parent_fit=calc_f(parent)#父輩目標函數(shù)值 parent_e=calc_e(parent)#父輩懲罰項 pbesti, pbest_fitness, pbest_e = update_best(parent, parent_fit, parent_e, children, children_fit,children_e) X[i]=pbesti return 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] 信息蒸發(fā)后保留的 return Tau #=============主函數(shù)====================== def main(): X,Tau=initialization() #初始化螞蟻群X 和信息素 Tau for NC in tqdm(range(G_max)): # 遍歷每一代 BestIndex = np.argmin(Tau) # 最優(yōu)索引 Tau_best = Tau[BestIndex] # 最優(yōu)信息素 # 計算狀態(tài)轉移概率 for i in range(m): # 遍歷每一個螞蟻 P[NC, i] = np.abs((Tau_best - Tau[i])) / np.abs(Tau_best) + 0.01 # 即離最優(yōu)信息素的距離 # =======位置更新========== X=position_update(NC,P,X) #X.shape=(20, 2) # =====更新信息素======== Tau=Update_information(Tau, X) # =====記錄最優(yōu)目標函數(shù)值======== index = np.argmin(Tau) # 最小值索引 value = Tau[index] # 最小值 fitneess_value_list.append(calc_f(X[index])) # 記錄最優(yōu)目標函數(shù)值 #=====打印結果======= min_index = np.argmin(Tau) # 最優(yōu)值索引 minX = X[min_index, 0] # 最優(yōu)變量x minY = X[min_index, 1] # 最優(yōu)變量y minValue = calc_f(X[min_index]) # 最優(yōu)目標函數(shù)值 print('最優(yōu)變量x', minX, end='') print('最優(yōu)變量y', minY, end='\n') print('最優(yōu)目標函數(shù)值', minValue) print('最優(yōu)變量對應的懲罰項',calc_e(X[min_index])) #=====可視化======= plt.plot(fitneess_value_list, label='迭代曲線') plt.legend() plt.show() if __name__=='__main__': main()
6.6 結果
100%|██████████| 200/200 [00:00<00:00, 220.49it/s]
最優(yōu)變量x 1.0000085699291246最優(yōu)變量y -0.0040192755525732165
最優(yōu)目標函數(shù)值 1.0032219250172503
最優(yōu)變量對應的懲罰項 0
到此這篇關于Python實現(xiàn)蟻群算法的文章就介紹到這了,更多相關Python 蟻群算法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python Xarray處理設置二維數(shù)組作為coordinates方式
這篇文章主要介紹了python Xarray處理設置二維數(shù)組作為coordinates方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07python 3利用Dlib 19.7實現(xiàn)攝像頭人臉檢測特征點標定
這篇文章主要為大家詳細介紹了python 3利用Dlib 19.7實現(xiàn)攝像頭人臉檢測特征點標定,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-02-02Python命令行參數(shù)解析之argparse模塊詳解
這篇文章主要介紹了Python命令行參數(shù)解析之argparse模塊詳解,argparse?是?Python?的一個標準庫,用于命令行參數(shù)的解析,這意味著我們無需在代碼中手動為變量賦值,而是可以直接在命令行中向程序傳遞相應的參數(shù),再由變量去讀取這些參數(shù),需要的朋友可以參考下2023-08-08