iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 26
0
自我挑戰組

Julia語言—從入門到專案系列 第 26

[Day 26] Simulated annealing -- 重新實作 (i)

Cooling scheduler

這部份我重新設計了一下。

program(pgm::Type{Val{:linear}}, t0::Float64, a::Float64=1.0) = k -> t0 / (1+a*k)
program(pgm::Type{Val{:quadratic}}, t0::Float64, a::Float64=1.0) = k -> t0 / (1+a*k^2)
program(pgm::Type{Val{:exp}}, t0::Float64, a::Float64=0.85) = k -> t0*a^k
program(pgm::Type{Val{:log}}, t0::Float64, a::Float64=1.1) = k -> t0 / (1+a*log(1+k))
program(pgm::Symbol, t0::Float64, a::Float64) = program(Val{pgm}, t0, a)

type CoolingScheduler
    T::Float64
    T_MAX::Float64
    T_MIN::Float64
    cycle::Int64
    process::Function
    cooling::Function
    isfrozen::Function

    function CoolingScheduler(pgm::Type{Val{Symbol}}, tmax=500::Float64, tmin=1::Float64, alpha=nothing)
        this = new()
        (this.T, this.T_MAX, this.T_MIN, this.cycle) = (tmax, tmax, tmin, 1)
        this.process = program(pgm, this.T_MAX, this.alpha)
        this.isfrozen = () -> this.T <= this.T_MIN

        function cooling()
            this.T = this.process(this.cycle)
            cycle += 1
        end
        this.cooling = cooling

        return this
    end
end

CoolingScheduler(pgm::Symbol, tmax::Float64, tmin::Float64, alpha::Float64) = CoolingScheduler(Val{pgm}, tmax, tmin, alpha)

這邊我運用了Julia特有的,至少我沒有在其他語言看過,"Value" type來實作,因為一般來說,multiple dispatch只能對型別做分派,無法對做分派。

當呼叫program函式的時候

program(:linear, t0, a)

他會回傳一個線性的降溫程序,接著你只要給他k他就可以幫你計算出目前的溫度了。

program(:quadratic, t0, a)  # 回傳二次的降溫程序
program(:foo, t0, a)  # 會出現Error

所以他可以針對不同的分派不同的函式去執行。

Stable Counter

type StabilityCounter
    stable_halt::Int64
    tolerance::Float64
    counter::Int64
    ishalt::Function
    update::Function

    function StabilityCounter(halt=150::Int64, tol=1e-12)
        this = new()
        this.stable_halt = halt
        this.tolerance = tol
        this.counter = 0
        this.ishalt = () -> this.counter >= this.stable_halt

        function update(ΔE::Float64)
            if ΔE < this.tolerance
                this.counter += 1
            else
                this.counter = 0
            end
        end
        this.update = update
        return this
    end
end

這個是個穩定計數器,他會計算降溫的過程中是不是已經進入穩定。
穩定的定義在前面沒有講到,他會去計算能量差是否小於某個容忍值,如果比容忍值小就代表兩個幾乎是一樣的,就代表穩定了。
如果連續穩定達到某個水準,那我們就說他可以停機了,所以會去比較ΔEthis.tolerance哪個小,然後決定要不要重新計數。


上一篇
[Day 25] Simulated annealing -- 分析
下一篇
[Day 27] Simulated annealing -- 重新實作(ii)
系列文
Julia語言—從入門到專案31

尚未有邦友留言

立即登入留言