物流配送路徑優化問題分析與算法解讀(一)
去年五一跳蚤以后,一直在一家公司參與物流配送軟件開發的相關工作,負責的工作內容包括物流配送路徑優化這一塊。關於物流配送這一專業領域,自己以前也是門外漢,對這一領域也沒有接觸過,更談不上理解。所以,一直在學習,一直在探索。在這個過程中因為工作需要學習了很多大牛的博客(太多了,記不住,所以大家別指望了,還是踏實看我的帖子吧),也研究了在開發過程中客戶提出的物流配送路徑優化領域的相關需求(因為客戶來頭較權威,需求比較專業,所以問題很具有代表性),有所收獲。好東西當然要拿出來與大家分享。我會把這段時間的學習和研究所得整理成一個系列(好吧,真心有點裝,不過思考了一下,發現要寫的確實不少),歡迎大家批評指正。另外,在這個過程中,我還使用了大量的谷歌地圖API技術,也有所積累,如果大家有需求,發帖頂起啊,我也可以找個時間整理出來與大家分享!如果遇上同行,還請不吝賜教。
在這個系列里,我會按照從易到難,從簡單到復雜的順序,向大家分類,分級逐步介紹物流配送路徑優化過程中的問題。
今天先起一個頭,這也是一切物流配送路徑優化問題的起點,那就是旅行商問題。相信閱讀這篇文章的同學應該對旅行商問題有所了解,我就不贅述了。
我將物流配送領域中的旅行商問題歸納如下:
物流企業A在B市有一個配送中心,有M個固定的配送客戶。企業A每天需要為這M個客戶配送一定量的貨物。現在,有這樣一個問題,要求企業A派出一輛車配送所有客戶,不考慮車輛載重與結點需求,且該輛車不管如何行駛,均能夠一次性配送完所有客戶,現在只需考慮一個問題,那就是如何行車才能保證所有點均已配送且只配送一次,且總的行車路徑最短。這是典型的TSP問題,也是物流配送路徑優化問題中最基本和最簡單的問題。
目前針對該問題,有很多的解決方法,包括有名的蟻群算法,包括遺傳算法等等,這些都能夠有效的獲取相對最優解。我只撿我實踐過且目前運行良好的幾種算法來說:
1、掃描法
(1)原理介紹:
(1)原理介紹:

如上圖所示,P0為起始點,其它點為配送需求點。采用極坐標來表示各點的相對位置,然后以P0點為坐標原點,以P1為起始點,定其角度為零度,以順時鍾或逆時鍾方向開始掃描各個點,獲得各點與原點連線P0Pn相對於P0P1的角度大小。根據角度大小確定其順序,直至掃描完畢。掃描結束后獲得的點的序列就是各點的配送順序。
(2)結果分析:
簡單掃描法並不能保證獲取最短路徑。但是其算法原理簡單,執行效率高,而且所獲取的結果與最優路徑之間的偏差較小。
2、分支界定法
(1)原理介紹:

分支限界法又稱為剪枝限界法或分支定界法,它類似於回溯法,也是一種在問題的解空間樹T上搜索問題解的算法。它與回溯法有兩點不同:
①回溯法只通過約束條件剪去非可行解,而分支限界法不僅通過約束條件,而且通過目標函數的限界來減少無效搜索,也就是剪掉了某些不包含最優解的可行解。
②在解空間樹上的搜索方式也不相同。回溯法以深度優先的方式搜索解空間樹,而分支限界法則以廣度優先或以最小耗費優先的方式搜索解空間樹。
分支限界法的搜索策略是:在擴展結點處,先生成其所有的子結點(分支),然后再從當前的活結點表中選擇下一個擴展結點。為了有效地選擇下一擴展結點,以加速搜索的進程,在每一活結點處,計算一個函數值(限界),並根據這些已計算出的函數值,從當前活結點表中選擇一個最有利的結點作為擴展結點,使搜索朝着解空間樹上有最優解的分支推進,以便盡快地找出一個最優解。從活結點表中選擇下一擴展結點的不同方式導致不同的分支限界法。最常見的有以下兩種方式:
①隊列式(FIFO)分支限界法:隊列式分支限界法將活結點表組織成一個隊列,並按隊列的先進先出原則選取下一個結點為當前擴展結點。
②優先隊列式分支限界法:優先隊列式分支限界法將活結點表按照某個估值函數C(x)的值組織成一個優先隊列,並按優先隊列中規定的結點優先級選取優先級最高的下一個結點成為當前擴展結點。
(2)結果分析:
分支界定法能獲取最短路徑。
分支限界法常以廣度優先或以最小耗費(最大效益)優先的方式搜索問題的解空間樹。在分支限界法中,每一個活結點只有一次機會成為擴展結點。活結點一旦成為擴展結點,就一次性產生其所有兒子結點。在這些兒子結點中,導致不可行解或導致非最優解的兒子結點被舍棄,其余兒子結點被加入活結點表中。
此后,從活結點表中取下一結點成為當前擴展結點,並重復上述結點擴展過程。這個過程一直持續到找到所需的解或活結點表為空時為止。
影響分支限界法搜索效率的有兩個主要因素:一是優先隊列Q的優先級由C(x)確定,它能否保證在盡可能早的情況下找到最優解,如果一開始找到的就是最優解,那么搜索的空間就能降低到最小;二是限界函數u(x),它越嚴格就越可能多地剪去分支,從而減少搜索空間。
在用分支限界法解決TSP問題時,有不少很好的限界函數和估值函數已經構造出來出了,使得分支限界法在大多數情況下的搜索效率大大高於回溯法。但是,在最壞情況下,該算法的時間復雜度仍然是O(n!),而且有可能所有的(n-1)!個結點都要存儲在隊列中。
3、蟻群算法
(1)原理介紹:
(1)原理介紹:

意大利學者M.Dorigo,V.Maniezzo等人在觀察螞蟻的覓食習性時發現,螞蟻總能找到巢穴與食物源之間的最短路徑。經研究發現,螞蟻的這種群體協作功能是通過一種遺留在其來往路徑上的叫做信息素(Pheromone)的揮發性化學物質來進行通信和協調的。化學通信是螞蟻采取的基本信息交流方式之一,在螞蟻的生活習性中起着重要的作用。通過對螞蟻覓食行為的研究,他們發現,整個蟻群就是通過這種信息素進行相互協作,形成正反饋,從而使多個路徑上的螞蟻都逐漸聚集到最短的那條路徑上。
這樣,M.Dorigo等人於1991年首先提出了蟻群算法。其主要特點就是:通過正反饋、分布式協作來尋找最優路徑。這是一種基於種群尋優的啟發式搜索算法。它充分利用了生物蟻群能通過個體間簡單的信息傳遞,搜索從蟻巢至食物間最短路徑的集體尋優特征,以及該過程與旅行商問題求解之間的相似性。得到了具有NP難度的旅行商問題的最優解答。
其求解過程可以形象的解釋如下:
如上圖所示,螞蟻在最開始的時候因為障礙物阻擋,不得不延上下兩條路繞行。上面的路徑比下面的路徑要長。我們假設所有螞蟻的運動速度一樣,那么在單位時間里通過下面路徑的螞蟻數量在概率上說,顯然要比從上面通過的螞蟻數量要多。因為螞蟻的移動過程中會產生信息素,我們假設每只螞蟻單位時間內產生的信息素是一定的,那么下面路徑的信息素濃度顯然要大於上面的路徑。隨着時間的增加,這種差別越來越大,而螞蟻之間是通過信息素來傳遞信息的,所以越來越多的螞蟻因為螞蟻濃度的影響,從下面的路徑通過,直至最后絕大多數的螞蟻都從下面的路經過。
蟻群算法是一種正反饋的算法。從真實螞蟻的覓食過程中我們不難看出,螞蟻能夠最終找到最短路徑,直接依賴於最短路徑上信息激素的堆積,而信息激素的堆積卻是一個正反饋的過程。對蟻群算法來說,初始時刻在環境中存在完全相同的信息激素,給予系統一個微小擾動,使得各個邊上的軌跡濃度不相同,螞蟻構造的解就存在了優劣,算法采用的反饋方式是在較優的解經過的路徑留下更多的信息激素,而更多的信息激素又吸引了更多的螞蟻,這個正反饋的過程使得初始的不同得到不斷的擴大,同時又引導整個系統向最優解的方向進化。因此,正反饋是螞蟻算法的重要特征,它使得算法演化過程得以進行。
(2)結果分析:
蟻群算法並不能保證一定可以獲取最短路徑。但是通過修改其算法因子,我們能夠得到最優近似解。如果對其進行多次循環處理,從得到的一組最優近似解中篩選出的最小值,一般就是最優解。
4、三種算法對比
算法名稱 |
時間復雜度 |
空間復雜度 |
優點 |
缺點 |
簡單掃描法 |
n (n表示結點個數) |
n (n表示結點個數) |
運算速度快,執行效率高。 |
求解結果不一定是最優解。 |
分支界定法 |
n! (n表示結點個數) |
(n-1)! (n表示結點個數) |
能夠求得最優解。 |
運算時間長,對內存空間要求大,如果求解空間太大,容易導致內存溢出。 |
蟻群算法 |
k*m*n (k表示循環次數,m表示螞蟻個數,n表示結點個數) |
m*n (m表示螞蟻個數,n表示結點個數) |
采用分布式計算,具有較強的魯棒性,可以通過控制算法因子對結果進行優化。多次循環能夠得到最優近似解。 |
運算時間長,信息素增量有可能導致錯誤的引導。算法因子確定難。 |