diff --git a/src/EvoLP.jl b/src/EvoLP.jl index 1d2e828..d3f7845 100644 --- a/src/EvoLP.jl +++ b/src/EvoLP.jl @@ -20,6 +20,7 @@ include("testfunctions.jl") include("algorithms/ga.jl") include("algorithms/ea.jl") +include("algorithms/sa.jl") include("algorithms/swarm.jl") include("deprecated.jl") @@ -32,6 +33,7 @@ export Particle, normal_rand_particle_pop, unif_rand_particle_pop # Particles # Algorithms export GA, GA! +export SA export oneplusone, oneplusone! export PSO, PSO! diff --git a/src/algorithms/sa.jl b/src/algorithms/sa.jl new file mode 100644 index 0000000..0a13335 --- /dev/null +++ b/src/algorithms/sa.jl @@ -0,0 +1,54 @@ +""" + SA(f, pop, k_max, S, C, M; T_init) + +Simulated annealing. + +## Arguments +- `f::Function`: objective function to **minimise**. +- `population::AbstractVector`: a list of vector individuals. +- `k_max::Integer`: number of iterations. +- `S::ParentSelector`: one of the available [`ParentSelector`](@ref). +- `C::CrossoverMethod`: one of the available [`CrossoverMethod`](@ref). +- `M::MutationMethod`: one of the available [`MutationMethod`](@ref). +- `T₀::Real=100.0`: initial temperature +- `α::Real=0.99`: cooling rate + +Returns a [`Result`](@ref). +""" +function SA( + f::Function, + population::AbstractVector, + k_max::Integer, + S::ParentSelector, + C::Recombinator, + M::Mutator; + T₀::Real=100.0, + α::Real=0.99 +) + fx = Inf + best_ind = copy(population) + T = T₀ + + runtime = @elapsed begin + for _ in 1:k_max + c = mutate(M, population) + fc = f(c) + ΔE = fc - fx # Calculate the difference in objective function values + + # Acceptance probability function + if ΔE < 0 || rand() < exp(-ΔE / T) + population = copy(c) + fx = fc + end + + fx < f(best_ind) && (best_ind = copy(population)) + + T *= α + end + end + + n_evals = k_max + + return Result(fx, best_ind, [best_ind], k_max, n_evals, runtime) +end +