本來以為在了解蟻群算法的基礎上實現這道奇怪的算法題並不難,結果實際上大相徑庭啊。做了近三天時間,才改成現在這能勉強拿的出手的模樣。由於公式都是圖片,暫且以截圖代替那部分內容吧,mark一記。
1 蟻群算法
(1) 蟻群AS算法簡介
20世紀90年代意大利學者M.Dorigo,V.Maniezzo,A.Colorni等從生物進化的機制中受到啟發,通過模擬自然界螞蟻搜索路徑的行為,提出來一種新型的模擬進化算法—— 蟻群算法,是群智能理論研究領域的一種主要算法。用該方法求解TSP問題、分配問題、job-shop調度問題,取得了較好的試驗結果.雖然研究時間不長,但是現在的研究顯示出,蟻群算法在求解復雜優化問題(特別是離散優化問題)方面有一定優勢,表明它是一種有發展前景的算法。
這種方法能夠被用於解決大多數優化問題或者能夠轉化為優化求解的問題。現在其應用領域已擴展到多目標優化、數據分類、數據聚類、模式識別、電信QoS管理、生物系統建模、流程規划、信號處理、機器人控制、決策支持以及仿真和系統辯識等方面,群智能理論和方法為解決這類應用問題提供了新的途徑。
(2) 蟻群AS算法過程
蟻群算法是對自然界螞蟻的尋徑方式進行模似而得出的一種仿生算法。螞蟻在運動過程中,能夠在它所經過的路徑上留下一種稱之為外激素(pheromone)的物質進行信息傳遞,而且螞蟻在運動過程中能夠感知這種物質,並以此指導自己的運動方向,因此由大量螞蟻組成的蟻群集體行為便表現出一種信息正反饋現象:某一路徑上走過的螞蟻越多,則后來者選擇該路徑的概率就越大。
為了說明蟻群算法的原理,先簡要介紹一下螞蟻搜尋食物的具體過程。在蟻群尋找食物時,它們總能找到一條從食物到巢穴之間的最優路徑。這是因為螞蟻在尋找路徑時會在路徑上釋放出一種特殊的信息素。當它們碰到一個還沒有走過的路口時.就隨機地挑選一條路徑前行。與此同時釋放出與路徑長度有關的信息素。路徑越長,釋放的激索濃度越低.當后來的螞蟻再次碰到這個路口的時候.選擇激素濃度較高路徑概率就會相對較大。這樣形成一個正反饋。最優路徑上的激索濃度越來越大.而其它的路徑上激素濃度卻會隨着時間的流逝而消減。最終整個蟻群會找出最優路徑。
圖1 螞蟻單次行走示意圖
螞蟻從A點出發,速度相同,食物在D點,可能隨機選擇路線ABD或ACD。假設初始時每條分配路線一只螞蟻,每個時間單位行走一步,本圖為經過9個時間單位時的情形:走ABD的螞蟻到達終點,而走ACD的螞蟻剛好走到C點,為一半路程。
圖2 螞蟻來回行走示意圖
圖2為從開始算起,經過18個時間單位時的情形:走ABD的螞蟻到達終點后得到食物又返回了起點A,而走ACD的螞蟻剛好走到D點。
假設螞蟻每經過一處所留下的信息素為一個單位,則經過36個時間單位后,所有開始一起出發的螞蟻都經過不同路徑從D點取得了食物,此時ABD的路線往返了2趟,每一處的信息素為4個單位,而 ACD的路線往返了一趟,每一處的信息素為2個單位,其比值為2:1。
尋找食物的過程繼續進行,則按信息素的指導,蟻群在ABD路線上增派一只螞蟻(共2只),而ACD路線上仍然為一只螞蟻。再經過36個時間單位后,兩條線路上的信息素單位積累為12和4,比值為3:1。
若按以上規則繼續,蟻群在ABD路線上再增派一只螞蟻(共3只),而ACD路線上仍然為一只螞蟻。再經過36個時間單位后,兩條線路上的信息素單位積累為24和6,比值為4:1。
若繼續進行,則按信息素的指導,最終所有的螞蟻會放棄ACD路線,而都選擇ABD路線。這也就是前面所提到的正反饋效應。
(3) 蟻群AS算法TSP問題應用
基於以上蟻群尋找食物時的最優路徑選擇問題,可以構造人工蟻群,來解決最優化問題,如TSP問題。
人工蟻群中把具有簡單功能的工作單元看作螞蟻。二者的相似之處在於都是優先選擇信息素濃度大的路徑。較短路徑的信息素濃度高,所以能夠最終被所有螞蟻選擇,也就是最終的優化結果。兩者的區別在於人工蟻群有一定的記憶能力,能夠記憶已經訪問過的節點。同時,人工蟻群再選擇下一條路徑的時候是按一定算法規律有意識地尋找最短路徑,而不是盲目的。例如在TSP問題中,可以預先知道當前城市到下一個目的地的距離。
TSP問題表示為一個N個城市的有向圖G=(N,A),
TSP問題的人工蟻群算法中,假設m只螞蟻在圖的相鄰節點間移動,從而協作異步地得到問題的解。每只螞蟻的一步轉移概率由圖中的每條邊上的兩類參數決定:
1. 信息素值 也稱信息素痕跡。
2. 可見度,即先驗值。
信息素的更新方式有2種,一是揮發,也就是所有路徑上的信息素以一定的比率進行減少,模擬自然蟻群的信息素隨時間揮發的過程;二是增強,給評價值“好”(有螞蟻走過)的邊增加信息素。
螞蟻向下一個目標的運動是通過一個隨機原則來實現的,也就是運用當前所在節點存儲的信息,計算出下一步可達節點的概率,並按此概率實現一步移動,逐此往復,越來越接近最優解。
螞蟻在尋找過程中,或者找到一個解后,會評估該解或解的一部分的優化程度,並把評價信息保存在相關連接的信息素中。 。
(4) 蟻群算法應用於TSP步驟
2蟻群系統(Ant Colony System, ACS)
(1) 蟻群系統
為了進一步克服AS中暴露出的問題,提出了蟻群系統(Ant Colony System, ACS)。該系統的提出是以Ant-Q算法為基礎的。Ant-Q將螞蟻算法和一種增強型學習算法Q-learning有機的結合了起來。ACS與AS之間存在三方面的主要差異:首先,ACS采用了更為大膽的行為選擇規則;其次,只增強屬於全局最優解的路徑上的信息素。其中,0<ρ<1是信息素揮發參數, 是從尋路開始到當前為止全局最優的路徑長度。
再次,還引入了負反饋機制,每當一只螞蟻由一個節點移動到另一個節點時,該路徑上的信息素都按照如下公式被相應的消除一部分,從而實現一種信息素的局部調整,以減小已選擇過的路徑再次被選擇的概率。
(2) ACS解決TSP問題
在本文中,使用ACS解決對稱TSP問題,具體的解題步驟如下:
A.初始化全局參數
n:城市數n,
m:螞蟻只數m (用隨機數取n^0.5 ~ n/2之間的值),
p:信息素蒸發系數p=0.7,
NC,NC_max:初始外循環次數NC=1,最大循環次數NC_max=60,
D:用坐標計算兩兩城市之間的距離矩陣D,
T:初始城市路線之間的信息素濃度矩陣T(初始默認相等,均為1/(n*(n-1)),即和為1),
E:每只螞蟻前進時的城市路線信息素濃度矩陣E(每一輪均為當時的T,假設每一輪的螞蟻之間相互影響極小,忽略不計,留下的信息素主要對后面的螞蟻起作用),
last,lastRoute:用於存儲當前最優路線的總長度last和最優過程lastRoute。
B.外循環
循環變量為輪數NC。每一次外循環均初始化當前輪數當前螞蟻i的行走路徑。每一次內循環結束之后計算當前NC下每只螞蟻的總行走長度sAll,記錄每只螞蟻的行走過程並由此得到當前最短的行走總長度last和路線lastRoute,之后按照公式1相對增強當前最佳路線的信息素,揮發其它路線信息素,再進入下一輪。
C.內循環
對於每一只螞蟻i,記錄它們的需要訪問城市列表route。
默認從城市0出發(從哪兒出發其實都一樣),按照到其它城市信息素的比例隨機選擇下一個城市。具體做法為求出下一個城市到當前城市的距離比上總的距離之和,然后逐個累加,於是求得比例區間[0 ~ p1 , p1 ~ p1 + p2 , p1 + p2 ~ p1 + p2 + p3......1]。用Math.random函數取0~1之間的隨機值判斷在哪個區間,則下一步走到對應的城市。然后將route中對應的城市置0,並將已選城市與原始城市之間的距離置0,重新計算比例區間的時候即可不影響,當route中所有的數值之和為0時說明除了初始城市全部都訪問了,最后訪問初始城市0,一只螞蟻即完成使命。
3 具體實現
根據以上算法過程,可以寫出程序如下:
(1) Functions.js
自定義工具函數,減少全局對象,盡可能代碼重用。
其中:
minAll(arr): 返回一維數組arr中的最小值
all(arr) :一維數組arr求和
nextStep(x,E): 根據當前城市x和所有路徑信息素的濃度矩陣E隨機確定下一座城市,類似轉盤法。詳細算法見上面2.(2).C。
sum(x,E) :配合nextStep實現轉盤效果
new2Arr(arr,x): 將undefined類型的新建arr轉化為二維數組,一般用來初始化
getAntNum(x) :通過城市數量得到最佳螞蟻數量
getType(o) , extend(destination,source): 實現對象的深復制,尤其針對多維數組(一般情況下的一維的用slice或者concat就行),見參考文獻[6]。
(2) AntSystem.js
ACS蟻群算法的具體實現,封裝於AntSystem(C)中,便於調用。輸入城市坐標矩陣C,輸入最優路徑總長度last和最優路徑lastRoute。
(3) Action.js
利用jquery.js工具庫實現自定義數據輸入和最終結果展現。有部分數據類型判斷。(基於關注算法本身的准則,僅對輸入的螞蟻數量n有一定的判斷和提示)
(4) Jquery-1.11.0.js
一種流行的js庫,用於js快速兼容開發
4 算法測試
點擊default.html 按照提示輸入數據一步步提交即可。兼容IE8.0+,firefox,chrome等瀏覽器。
運行過程截圖:
- 輸入合適數目后點擊確認彈出坐標矩陣輸入窗口
2.輸入坐標矩陣點擊確認得到最終的結果
輸入為(0,0), (0,1), (0,2), (0,3), (0,4), (1,0), (1,1), (1,2), (1,3), (2,2), (2,3), (2,4), (3,3), (3,4)。
3.在FF的控制台腳本中合適的地方設置斷點可以單步查看具體的運行過程(由於具體展示出來過於占據篇幅,全部輸出網頁顯示過於瑣細,這兒列一張圖)(可以按照需要將每一輪的重要數據抽取出來查看具體變化)
5 分析和總結
本次ACS解決對稱TSP問題的javascript實現,相對於經典的ACS,有一些修改的地方:
1.外循環結束條件只有循環輪數NC<NC_max。不考慮是否已經收斂。
2.采用參考文獻[4]上的推薦揮發系數p值,不是多次數據測量確認。
Js作為一種弱變量的語言,擁有一些隱性默認的規則:
1.使用+符號時可能會默認將兩邊變量的數據類型改為string。參見參考文獻[7]。
2.在函數內部申明變量x時,如果不使用var語句而是直接給變量x賦值會導致變量x變為全局變量,污染全局空間。
3.函數的參數在函數內部作為局部變量存在,當函數結束時結束(除非使用閉包),不會對外面同名變量產生影響。
4.對象變量之間使用=號是對象的引用傳遞,即兩個對象指向內存中同一塊區域,當一個變量改變對象的屬性時,另外一個變量對應的屬性也會變。因此,需要用到對象的深復制。對於一維數組使用slice和concat函數,對於多維數組參照參考文獻[6]。
6 參考文獻
[1] 彭喜元 彭宇 戴毓豐. 群智能理論及應用. 電子學報, 2003年 S1期.
[2] 李士勇. 蟻群算法及其應用. 哈工大出版社.
[3] 吳啟迪. 智能蟻群算法及應用. 上海科技出版社.
[4] 詹士昌,徐婕,吳俊. 蟻群算法中有關算法參數的最優選擇[J]. 科技通報,2003,05:381-386.
[5] 宋志飛. 基於蟻群算法的TSP問題研究[D].江西理工大學,2013.
[6] js深復制http://www.cnblogs.com/Loofah/archive/2012/03/23/2413665.html
[7] js類型轉換http://weibo.com/p/230418c3aa9eb60102vh10#_loginLayer_1436233053863
具體的源碼可以在我的github上下載 https://github.com/codetker/AntSystem 。
由於最近開始實習,得先完成公司手頭的工作(忙里偷閑才是真閑,,,)。所以后續的想法:在不同的瀏覽器中對算法執行平均速度的測試,以及用C和matlab對於同一代碼的平均執行時間的比較,還有 線性神經網絡實現spammer判斷系統的JavaScript實現,估計得要一段時間才能出爐咯。
鑒於我對許多JavaScript內置函數不熟悉,代碼里面肯定有很多的彎路,求大家指出來,謝謝。