一、原理介紹
模擬退火算法(Simulated Annealing)是一種通用的優化算法,最初由Kirkpatrick于1983年提出,靈感來源于固體物理學中原子的退火過程。簡單來說,模擬退火算法是模擬金屬從高溫狀態到低溫狀態冷卻過程中的微觀行為,使得金屬的內部結構由無序轉變為有序的過程。在優化問題中,可以將最優解看作一個結構有序的狀態,而將優化過程看作從初始狀態到最優狀態迭代過程的退火過程。
模擬退火算法的核心思想是利用概率跳出局部最優解,以期望更好的全局解。模擬退火算法按照一定的比例降低溫度,從而使搜索范圍減小,最終找到全局最優解的概率逐漸增大,隨著時間的推移,概率逐漸趨近于1。
二、優點分析
三、缺點分析
四、代碼示例
算法核心代碼
/**
* 模擬退火算法
* @param func 目標函數
* @param neighbor 鄰域函數
* @param t0 初始溫度
* @param tn 最小溫度
* @param alpha 降溫速率
* @param maxIter 最大迭代次數
*/
double simulatedAnnealing(function)> func, function(vector)> neighbor,
double t0 = 1e4, double tn = 1e-4, double alpha = 0.99, int maxIter = 10000) {
double t = t0; // 當前溫度
vector c = {0, 0}; // 初始解
double best = func(c); // 初始解的目標函數值
for (int i = 0; i < maxIter; i++) {
vector nc = neighbor(c); // 產生新解
double delta = func(nc) - best; // 計算目標函數的值差
if (delta < 0) { // 新解更優
c = nc;
best = func(nc);
} else { // 根據一定概率接受劣解
double p = exp(-delta / t); // 接受概率
double r = ((double) rand() / RAND_MAX); // 隨機數
if (r < p) {
c = nc;
}
}
t *= alpha; // 降溫
if (t < tn) {
break; // 溫度達到最小值,退出迭代
}
}
return best;
}
一個簡單的例子
/**
* 實現一個簡單的例子:在二維平面上尋找離原點最遠的點
*/
double distance(vector p) { // 目標函數:點到原點的距離
return sqrt(p[0] * p[0] + p[1] * p[1]);
}
vector perturb(vector p) { // 鄰域函數:隨機擾動點的坐標
return {p[0] + ((double) rand() / RAND_MAX - 0.5) * 2.0, p[1] + ((double) rand() / RAND_MAX - 0.5) * 2.0};
}
int main() {
srand(time(NULL)); // 初始化隨機數生成器
double ans = simulatedAnnealing(distance, perturb, 1e3, 1e-3, 0.99, 1000);
cout << ans << endl;
return 0;
}