模擬退火演算法(SA)求解TSP 問題(C語言實現)

2021-09-20 07:58:41 字數 3704 閱讀 8287

這篇文章是之前寫的智慧型演算法(遺傳演算法(ga)、粒子群演算法(pso))的補充。其實**我老早之前就寫完了,今天恰好重新翻到了,就拿出來給大家分享一下,也當是回顧與總結了。

首先介紹一下模擬退火演算法(sa)。模擬退火演算法(simulated annealing,sa)演算法最早是由metropolis等人提出的。其出發點是基於物理中固體物質的退火過程與一般組合優化問題之間的相似性。模擬退火演算法是一種通用的優化演算法,其物理退火過程由以下三部分組成:

(1)加溫過程

(2)等溫過程

(3)冷卻過程

其中加溫過程對應演算法設定的初始溫度,等溫過程對應演算法的metropolis抽樣過程,冷卻過程對應控制引數的下降。這裡能量的變化就是目標函式,要得到的最優解就是能量最低狀態。metropolis準則是sa演算法收斂於全域性最優解的關鍵所在,metropolis準則以一定的概率接受惡化解,這樣就使得演算法可以跳離區域性最優解的陷阱。

模擬退火演算法為求解傳統方法難以處理的tsp問題提供了乙個有效的途徑和通用的處理框架,並逐漸發展成為一種迭代自適應啟發式概率搜尋演算法。模擬退火演算法可以用於求解不同的非線性問題,對於不可微甚至不連續函式的優化,能以較大概率求得全域性最優解,該演算法還具有較強的魯棒性、全域性收斂性、隱含並行性以及廣泛的適應性,對目標函式以及約束函式沒有任何要求。

sa 演算法實現的步驟如下:(下面以最小化問題為例)

(1)初始化:取溫度t0足夠大,令t = t0,取任意解s1,確定每個t時 的迭代次數,即 metropolis鏈長l。

(2)對當前溫度t和k=1,2,3,...,l,重複步驟(3)~(6)

(3)對當前解s1隨機產生乙個擾動得到乙個新解 s2.

(4) 計算s2的增量df = f(s2) - f(s1),其中f(s1)為s1的代價函式。

(5)若df < 0,接受s2作為新的當前解,即s1 = s2;否則s2的接受概率為 exp(-df/t),即隨機產生(0,1)上的均勻分布的隨機數rand,若 exp(-df/t)>rand

,則接受s2作為新的當前解,s1 = s2;否則保留當前解。

(6)如果滿足最終的終止條件,stop,則輸出當前解s1作為最優解,結束程式。終止條件stop通常為:在連續若干個metropolis鏈中新解s2都沒有被接受時終止演算法,或者是設定結束溫度。否則按衰減函式衰減t後返回(2)

以上的步驟稱之為metropolis過程。逐步降低控制溫度,重複metropolis過程,直至滿足結束準則stop求出最優解。可以看出sa整體的步驟相比ga以及pso還是簡單了很多了,而且親測效果還不錯,所以屬於價效比較高的演算法。關鍵的步驟在第(6)步。

不廢話了,直接上**吧。tsp的資料和之前的資料一樣,使用c語言實現。**如下:

1/*2

* 使用模擬退火演算法(sa)求解tsp問題(以中國tsp問題為例)

3* 參考自《matlab 智慧型演算法30個案例分析》45

* update: 16/12/11

6* author:lyrichu

7* email:[email protected]*/

9 #include10 #include11 #include

12 #include13 #include14

#define t0 50000.0 //

初始溫度

15#define t_end (1e-8)

16#define q 0.98 //

退火係數

17#define l 1000 //

每個溫度時的迭代次數,即鏈長

18#define n 31 //

城市數量

19int city_list[n]; //

用於存放乙個解

20double city_pos[n][2] = ,,,,,,,,,

21 ,,,,,,,,,,,,

22 ,,,,,,,,,}; //

中國31個城市座標

23//

函式宣告

24double distance(double *,double *); //

計算兩個城市距離

25double path_len(int *); //

計算路徑長度

26void init(); //

初始化函式

27void create_new(); //

產生新解

28//

距離函式

29double distance(double * city1,double *city2)

3038

39//

計算路徑長度

40double path_len(int *arr)

4151

int last_index = *(arr+n-1); //

最後乙個城市序號

52int first_index = *arr; //

第乙個城市序號

53double last_dis = distance(city_pos[last_index-1],city_pos[first_index-1

]);54 path = path +last_dis;

55return path; //

返回總的路徑長度56}

5758

//初始化函式

59void

init()

6064

65//

產生乙個新解

66//

此處採用隨機交叉兩個位置的方式產生新的解

67void

create_new()

6877

78//

主函式79

int main(void)80

108}

109}

110 t *= q; //

降溫111 count++;

112}

113 finish = clock(); //

退火過程結束

114double duration = ((double)(finish-start))/clocks_per_sec; //

計算時間

115 printf("

採用模擬退火演算法,初始溫度t0=%.2f,降溫係數q=%.2f,每個溫度迭代%d次,共降溫%d次,得到的tsp最優路徑為:\n

",t0,q,l,count);

116for(int i=0;i1;i++) //

輸出最優路徑

117120 printf("

%d\n

",city_list[n-1

]);121

double len = path_len(city_list); //

最優路徑長度

122 printf("

最優路徑長度為:%lf\n

",len);

123 printf("

程式執行耗時:%lf秒.\n

",duration);

124return0;

125 }

執行結果截圖如下:

注:如果使用gcc編譯報錯,可能需要加上 -std=c99選項以及在末尾加上 -lm(鏈結math庫)。

熱愛程式設計,熱愛機器學習! github: github blog: 個人部落格站點:不再維護)

模擬退火求解TSP問題

1.尋找下乙個解 2.計算下乙個解的能量 3.決定是否接受這個解 4.降溫 double randfloat double t0 1000000 tk 1,t t0,d 0.9999 int x initx 當前解 初始解 int anse,nowe 全域性最優解的能量,當前解的能量 anse no...

基於模擬退火的tsp問題求解

模擬退火演算法 於固體退火原理,是一種基於概率的演算法,將固體加溫至充分高,再讓其徐徐冷卻,加溫時,固體內部粒子隨溫公升變為無序狀,內能增大,而徐徐冷卻時粒子漸趨有序,在每個溫度都達到平衡態,最後在常溫時達到基態,內能減為最小。這是關於模擬退火的科普 模擬退火 模擬退火實現起來主要分為三個部分 1....

模擬退火演算法(SA)

介紹模擬退火前,先介紹爬山演算法。爬山演算法是一種簡單的貪心搜尋演算法,該演算法每次從當前解的臨近解空間中選擇乙個最優解作為當前解,直到達到乙個區域性最優解。爬山演算法實現很簡單,其主要缺點是會陷入區域性最優解,而不一定能搜尋到全域性最優解。如圖1所示 假設c點為當前解,爬山演算法搜尋到a點這個區域...