自己用C語言寫的乙個模擬退火演算法

2021-08-26 02:36:52 字數 2388 閱讀 7482

首先介紹一下模擬退火演算法(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)步。

源**如下:

#include

#include

#include

#include

#include

#define t0 50000.0    //初始溫度

#define t_end (1e-8)

#define q 0.98   //退火係數

#define l 1000    //每個溫度時的迭代次數,即鏈長

#define n 31     //城市數量

int city_list[n];  //用於存放乙個解

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

,,,,,,,,,,,,

,,,,,,,,,}; 

// 中國31個城市座標

//函式宣告

double distance(double *,double*);   //計算兩個城市的距離

double path_len(int *);       //計算路徑長度

void  init();  //初始化函式

void create_new(); // 產生新解

//距離函式

double distance(double *city1,double *city2)

//主函式

int main()}}

t*=q;  //降溫

count++;

}finish=clock();  //退火過程結束

double duration=((double)(finish-start))/clocks_per_sec;  //計算時間

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

for(int i=0;i",city_list[i]);

}printf("%d\n",city_list[n-1]);

double len = path_len(city_list); // 最優路徑長度

printf("最優路徑長度為:%lf\n",len);

printf("程式執行耗時:%lf秒.\n",duration);

return 0;

}結果如下截圖:

自己用C 寫的乙個推箱子

自己寫了乙個推箱子,不過目前只有兩關,打圖太難了orz。絕不是因為我太懶 include include includeusing namespace std 為到位 為箱子 x為邊界 為人物 o為目標點 int step 關卡 int x,y 人物座標 char m 移動 bool flag fa...

用集算器寫乙個八皇后

有關西洋棋的問題很多,八皇后問題就是其中相當著名的乙個。在8 8的西洋棋棋盤中,放入8個皇后,使它們不互相攻擊,共有多少種方法呢?皇后的攻擊範圍是同一行 同一列以及同一斜行,因此,符合條件的8個皇后必須都不在同一行 同一列或者同一斜行上。由於每一行中只能放入乙個皇后,所以可以使用乙個長度為8的序列,...

自己寫的乙個Vue

下面這裡是我自己寫的乙個小型的vue,原理就是proxy proxy天生沒有prototype,因此要加上,不然extends會報錯 proxy.prototype proxy.prototype object.prototype class myvue extends proxy super da...