之前有了大致的框架,不過對於控制溫度下降的速度也是重要的一環。
這決定了整體函數收斂的情況。
參考了A Comparison of Cooling Schedules for Simulated Annealing (Artificial Intelligence)
SCHEDULES = Dict{Symbol, Function}()
SCHEDULES[:linear] = (k, a, t0) -> t0 / (1+a*k)
SCHEDULES[:quadratic] = (k, a, t0) -> t0 / (1+a*k^2)
SCHEDULES[:exp] = (k, a, t0) -> t0*a^k
SCHEDULES[:log] = (k, a, t0) -> t0 / (1+a*log(1+k))
type CoolingScheduler
T::Float64
T_MAX::Float64
T_MIN::Float64
alpha::Float64
cooling::Function
isfrozen::Function
function CoolingScheduler(sch, tmax=500, tmin=1, alpha=nothing)
this = new()
(this.T, this.T_MAX, this.T_MIN) = (tmax, tmax, tmin)
if alpha == nothing
if sch == :exp
alpha = 0.85
elseif sch == :log
alpha = 1.1
else
alpha = 1.0
end
end
this.alpha = alpha
this.cooling = k -> this.T = SCHEDULES[sch](k, this.alpha, this.T_MAX)
this.isfrozen = () -> this.T <= this.T_MIN
return this
end
end
前面宣告了不同種的scheduler,後面宣告了CoolingScheduler
,他基本上掌管了溫度跟降溫的程序,所以每次呼叫cooling
的時候就進行一次降溫,isfrozen
去檢查是不到到達T_MIN的意思,如果到達,那就freeze起來!
這邊的cooling
跟isfrozen
用了傳統OOP的寫法,把行為寫在型別的定義當中,這麼做只是覺得在行為的解釋上比較直覺。