模擬退火原理與實作

核心概念

模擬退火 (Simulated Annealing) 靈感來自金屬冶煉:

  • 高溫:原子劇烈運動,可以跳到任何狀態(探索)
  • 降溫:原子逐漸穩定(收斂)
  • 低溫:原子在最低能量狀態附近震盪(利用)

\begin{aligned} P(\text{接受更差的解}) = e^{-\Delta E / T} \end{aligned}

  • $\Delta E$:新解與舊解的差距
  • $T$:當前溫度
  • 高溫時容易接受差解 → 跳出局部最佳
  • 低溫時只接受好解 → 收斂到最佳

TSP 實作

import random, math

def simulated_annealing(cities, initial_temp=1000, cooling_rate=0.995, stop_temp=0.01):
    """
    cities: [(x, y), ...] 城市座標
    """
    n = len(cities)
    
    def distance(i, j):
        return math.sqrt((cities[i][0]-cities[j][0])**2 + (cities[i][1]-cities[j][1])**2)
    
    def total_dist(route):
        return sum(distance(route[i], route[(i+1)%n]) for i in range(n))
    
    # 初始解:隨機排列
    current = list(range(n))
    random.shuffle(current)
    current_dist = total_dist(current)
    
    best = current[:]
    best_dist = current_dist
    
    temp = initial_temp
    while temp > stop_temp:
        # 產生新解:交換兩個城市
        i, j = random.sample(range(n), 2)
        new = current[:]
        new[i], new[j] = new[j], new[i]
        new_dist = total_dist(new)
        
        delta = new_dist - current_dist
        if delta < 0 or random.random() < math.exp(-delta / temp):
            current = new
            current_dist = new_dist
            if current_dist < best_dist:
                best = current[:]
                best_dist = current_dist
        
        temp *= cooling_rate
    
    return best, best_dist

Vibe Prompt

🔥 詠唱:「請幫我用模擬退火解決 TSP,並用 Matplotlib 動畫顯示路線如何逐步最佳化。」

會員專屬免費教學

本章節為註冊會員專屬的免費開放內容!請先登入或註冊會員,即可立即解鎖閱讀。

立即登入 / 註冊