範例程式碼下載/Files/gpcuster/TSP.zip
介紹
組合最佳化演算法用於解決在一個解空間非常大的情況下快速地求解近似解。這類演算法可用於資源管理,操作管理,品質控制等等問題,並且可以在有效時間裡給出一個足夠好的近似解。
常見的啟發演算法有:simulated annealing, tabu search, harmony search, scatter search, genetic algorithms, ant colony optimization等等。在這篇文章中,我們將討論simulated annealing(類比退火演算法)和他在解決TSP(旅行商)問題中的實際應用。
背景
類比退火演算法來源於固體退火原理,將固體加溫至充分高,再讓其徐徐冷卻,加溫時,固體內部粒子隨溫升變為無序狀,內能增大,而徐徐冷卻時粒子漸趨有序,在每個溫度都達到平衡態,最後在常溫時達到基態,內能減為最小。所以,類比退火演算法的目標就是通過一個目標函數來隨機搜尋。(這也是所有啟發搜尋演算法的一個共性)
類比退火演算法的優勢在於能夠有效地避免局部最優問題。在這裡,我們現在討論的這個演算法並不總是拒絕使總體目標函數值上升(變差)的結果,而是依據這樣一個機率函數:
P = exp (-∆f/T)
T代表溫度控制參數(類比問題),∆f是新參數的結果和當前最優解的差值。
這個機率函數是由Metropolis準則而得來的。
旅行商問題
旅行商問題就是指旅行商按一定的順序訪問N個城市的每個城市,使得每個城市都能被訪問且僅能被訪問一次,最後回到起點,而使花費的代價最小。
為瞭解決該問題,我們需要瞭解下面兩個問題:
1 產生新解的策略: 我們將隨機交換已有解中的任意2個城市的順序,來產生新的訪問順序(新解)。
2 目標函數 (用於求最小值): 按照對所有城市的訪問順序來求解路徑的長度。
代碼的使用
TravellingSalesmanProblem.cs是最要的類. 調用Anneal()方法將計算出訪問各個城市的最短路徑。
TravellingSalesmanProblem problem = new TravellingSalesmanProblem();
problem.FilePath = "Cities.txt";
problem.Anneal();
下面的代碼說明了類比退火演算法的基本流程:
1 /**//// <summary>
2 /// Annealing Process
3 /// </summary>
4 public void Anneal()
5 {
6 int iteration = -1;
7
8 double temperature = 10000.0;
9 double deltaDistance = 0;
10 double coolingRate = 0.9999;
11 double absoluteTemperature = 0.00001;
12
13 LoadCities();
14
15 double distance = GetTotalDistance(currentOrder);
16
17 while (temperature > absoluteTemperature)
18 {
19 nextOrder = GetNextArrangement(currentOrder);
20
21 deltaDistance = GetTotalDistance(nextOrder) - distance;
22
23 //if the new order has a smaller distance
24 //or if the new order has a larger distance but satisfies Boltzman condition then accept the arrangement
25 if ((deltaDistance < 0) || (distance > 0 && Math.Exp(-deltaDistance / temperature) > random.NextDouble()))
26 {
27 for (int i = 0; i < nextOrder.Count; i++)
28 currentOrder[i] = nextOrder[i];
29
30 distance = deltaDistance + distance;
31 }
32
33 //cool down the temperature
34 temperature *= coolingRate;
35
36 iteration++;
37 }
38
39 shortestDistance = distance;
40 }