Mímisbrunnr知恵の泉

← 数理最適化 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:局所探索と近傍 | 関連:タブー探索

要点(BLUF)

概念 ── 金属の焼きなましに学ぶ

金属を高温から ゆっくり冷やすと、原子が低エネルギー状態(規則正しい結晶)に落ち着く。急冷すると欠陥だらけの局所最適に固まる。この物理を最適化に借りたのが SA。「目的関数=エネルギー」「解=状態」「制御パラメータ=温度」と読み替える。

山登り(局所探索と近傍)は改善する隣にしか動かないので局所最適で止まる。SA は 温度が高いうちは悪化する隣にも飛び移れるので、谷を登って別の谷へ抜けられる。

メトロポリス基準

近傍からランダムに候補解を選び、目的の変化 ΔE=f()f()\Delta E = f(\text{新}) - f(\text{現}) に応じて受理する:

P(受理)={1ΔE0(改善ならば必ず受理)exp ⁣(ΔET)ΔE>0(悪化は確率的に受理)P(\text{受理}) = \begin{cases} 1 & \Delta E \le 0 \quad (\text{改善ならば必ず受理}) \\ \exp\!\left(-\dfrac{\Delta E}{T}\right) & \Delta E > 0 \quad (\text{悪化は確率的に受理}) \end{cases}

冷却スケジュールTTTαTT \leftarrow \alpha Tα<1\alpha<1、幾何冷却)などで徐々に下げる。

Pythonで脱出を確認

山登りが局所最適 7.05-7.05 に捕まった初期点(局所探索と近傍x=12x=-12)から SA を走らせ、大域最適 1.45-1.45 へ抜けられるか見る。

import numpy as np

xs = np.linspace(-15, 15, 601)
def f(x): return 0.1*x**2 + 2*np.sin(x)
fvals = f(xs)

def simulated_annealing(seed, T0=10.0, cooling=0.9995, steps=6000):
    rng = np.random.default_rng(seed)
    i = 60                  # 初期 x=-12 (山登りなら-7.05で停止する側)
    best_i = i
    T = T0
    for step in range(steps):
        j = i + rng.integers(-3, 4)          # 近傍へランダム移動
        if not (0 <= j < len(xs)):
            continue
        dE = fvals[j] - fvals[i]             # エネルギー変化
        if dE < 0 or rng.random() < np.exp(-dE / T):   # メトロポリス基準
            i = j
            if fvals[i] < fvals[best_i]:
                best_i = i
        T *= cooling                          # 冷却
    return best_i

print(f"参照(全探索)最小: x={xs[np.argmin(fvals)]:.3f}, f={fvals.min():.4f}")
r = simulated_annealing(seed=0)
print(f"焼きなまし(初期x=-12): x={xs[r]:+.3f}, f={fvals[r]:.4f}")

実行結果:

参照(全探索)最小: x=-1.450, f=-1.7752
焼きなまし(初期x=-12): x=-1.450, f=-1.7752

山登りなら 7.05-7.05f=3.58f=3.58)で止まる初期点から、SA は局所最適の壁を温度の力で乗り越え、大域最適 x=1.45x=-1.45f=1.78f=-1.78)に到達。序盤の高温で広く動き回り、冷却とともに良い谷へ収束した。

数式の直観的意味

メトロポリス基準 exp(ΔE/T)\exp(-\Delta E/T) は統計力学の ボルツマン分布そのもの。温度 TT での状態の確率は exp(f(x)/T)\propto \exp(-f(x)/T) で、SA はこの分布からのサンプリング(マルコフ連鎖)を、TT を下げながら行う。T0T\to0 の極限でボルツマン分布は最小エネルギー状態に集中する ── だから「十分ゆっくり冷やせば大域最適に確率1で収束」という理論保証がある(対数冷却 Tk=c/logkT_k = c/\log k)。ただし理論的な冷却は遅すぎて実用にならず、現実は幾何冷却で「ほぼ最適」を狙う。温度は「悪化をどれだけ許すか」=探索(exploration)と活用(exploitation)のつまみで、高温=探索、低温=活用。この調整がベイズ最適化や強化学習の温度パラメータにも通じる普遍的な考え。

⚠️ よくある誤解・落とし穴

関連ノート