二、完整Python代碼
import random
import mathdef rastrigin(x, y):"""二維Rastrigin函數(目標函數,需最小化)參數:x: 自變量xy: 自變量y返回:函數值f(x,y)"""return 20 + x**2 + y**2 - 10 * math.cos(2 * math.pi * x) - 10 * math.cos(2 * math.pi * y)def simulated_annealing(T0=100, alpha=0.9, L=100, T_end=1e-5):"""模擬退火算法實現(解決二維Rastrigin函數最小化問題)參數:T0: 初始溫度(默認100,越大探索越充分)alpha: 溫度衰減系數(默認0.9,0.8-0.95之間,越小降溫越快)L: 每個溫度下的迭代次數(默認100,越大搜索越充分)T_end: 停止溫度(默認1e-5,越小收斂越徹底)返回:best_solution: 全局最優解(x,y)best_value: 全局最優目標函數值"""# 1. 初始化當前解(隨機生成x,y ∈ [-5.12, 5.12])x = random.uniform(-5.12, 5.12)y = random.uniform(-5.12, 5.12)current_sol = (x, y) # 當前解(tuple)current_val = rastrigin(x, y) # 當前解的目標函數值# 2. 初始化最好解(初始時最好解為當前解)best_sol = current_solbest_val = current_val# 3. 溫度循環(從高溫到低溫)T = T0 # 當前溫度while T > T_end:# 4. 每個溫度下的迭代(搜索當前溫度下的解空間)for _ in range(L):# a. 生成新解(在當前解附近隨機擾動,用正態分布,標準差與溫度相關)# 溫度越高,擾動越大(探索范圍廣);溫度越低,擾動越小(聚焦局部)new_x = current_sol[0] + random.gauss(0, T**0.5) # 正態分布擾動xnew_y = current_sol[1] + random.gauss(0, T**0.5) # 正態分布擾動y# b. 截斷新解(確保x,y在定義域[-5.12, 5.12]內)new_x = max(min(new_x, 5.12), -5.12)new_y = max(min(new_y, 5.12), -5.12)new_sol = (new_x, new_y) # 新解new_val = rastrigin(new_x, new_y) # 新解的目標函數值# c. 計算目標函數差(新解 - 當前解)delta_f = new_val - current_val# d. Metropolis準則:判斷是否接受新解if delta_f <= 0:# 情況1:新解更好(目標函數值更小),直接接受current_sol = new_solcurrent_val = new_val# 更新最好解(如果新解比當前最好解更好)if new_val < best_val:best_sol = new_solbest_val = new_valelse:# 情況2:新解更差,以概率exp(-delta_f/T)接受prob = math.exp(-delta_f / T) # 接受概率(溫度越高,概率越大)if random.random() < prob: # 生成0-1隨機數,小于prob則接受current_sol = new_solcurrent_val = new_val# 5. 溫度衰減(指數衰減:T = alpha * T)T *= alpha# 6. 返回最好解和最好目標函數值return best_sol, best_valif __name__ == "__main__":# ---------------------- 參數設置(小白可調整) ----------------------T0 = 100 # 初始溫度(推薦值:50-200)alpha = 0.9 # 衰減系數(推薦值:0.8-0.95)L = 100 # 每個溫度下的迭代次數(推薦值:50-200)T_end = 1e-5 # 停止溫度(推薦值:1e-4-1e-6)# -------------------------------------------------------------------# 運行模擬退火算法best_sol, best_val = simulated_annealing(T0, alpha, L, T_end)# 輸出結果print("="*50)print("模擬退火算法求解二維Rastrigin函數最小值結果:")print(f"全局最優解(x, y):({best_sol[0]:.4f}, {best_sol[1]:.4f})")print(f"全局最優目標函數值:{best_val:.4f}")print(f"理論全局最小值:0(對應解(0,0))")print("="*50)
三、代碼使用說明
1.環境準備
安裝Python(推薦3.7及以上版本,下載地址:https://www.python.org/downloads/)。
無需額外安裝第三方庫(代碼使用Python標準庫random和math)。
2.運行代碼
將代碼保存為sa_rastrigin.py(或任意文件名)。
打開命令行(Windows:Win+R輸入cmd;Mac:Launchpad搜索終端),進入代碼所在目錄,運行:
Python?sa_rastrigin.py
3.參數調整說明(小白重點)
代碼中的T0(初始溫度)、alpha(衰減系數)、L(每個溫度下的迭代次數)是核心可調參數,影響算法性能:
初始溫度T0:
越大:算法初期探索范圍越廣(敢接受差解),越不容易陷入局部最優,但計算時間越長。
推薦值:50-200(比如T0=100)。
衰減系數alpha:
越小:溫度下降越快(比如alpha=0.8,10次迭代后溫度從100降到100*0.8^10≈10.7),計算時間短,但可能提前收斂到局部最優。
越大:溫度下降越慢(比如alpha=0.95,10次迭代后溫度≈59.8),探索更充分,但計算時間長。
推薦值:0.8-0.95(比如alpha=0.9)。
每個溫度下的迭代次數L:
越大:每個溫度下搜索越充分(比如L=200,每個溫度下嘗試200次新解),越可能找到更好的解,但計算時間越長。
推薦值:50-200(比如L=100)。
4.結果解釋
運行代碼后,會輸出類似以下結果(因隨機種子不同,結果略有差異):
==================================================
模擬退火算法求解二維Rastrigin函數最小值結果:
全局最優解(x, y):(0.0012, -0.0008)
全局最優目標函數值:0.0002
理論全局最小值:0(對應解(0,0))
==================================================
全局最優解:接近(0,0)(理論全局最優解)。
全局最優目標函數值:接近0(理論全局最小值)。
四、拓展建議(小白進階)
可視化結果:可以用matplotlib庫繪制Rastrigin函數圖像和算法搜索路徑,更直觀看到算法如何從“亂撞”到“收斂”。
解決其他問題:將rastrigin函數替換為其他優化問題的目標函數(比如TSP的總距離、背包問題的總價值),即可用該代碼解決其他優化問題(需調整新解生成方式,比如TSP用交換城市位置)。
通過本案例,小白可以掌握模擬退火算法的核心邏輯(Metropolis準則、溫度衰減)和代碼實現,并能調整參數解決實際優化問題。