Skip to content

Commit

Permalink
initialize Matrix individuals, fixes #55
Browse files Browse the repository at this point in the history
  • Loading branch information
wildart committed Jun 23, 2020
1 parent 9e5a18a commit 516ce4f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 16 deletions.
25 changes: 17 additions & 8 deletions src/api/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,18 @@ end
Initialize population by replicating the `inividual` vector.
"""
initial_population(method::M, individual::I) where {M<:AbstractOptimizer, I<:AbstractVector} =
return [copy(individual) for i in 1:population_size(method)]
[copy(individual) for i in 1:population_size(method)]

"""
initial_population(method, individuals::AbstractVector{<:AbstractVector})
Initialize population from the collection of `inividuals` vectors.
"""
function initial_population(method::M, individuals::AbstractVector{I}) where {M<:AbstractOptimizer, I<:AbstractVector}
n = population_size(method)
@assert length(individuals) == n "Size of initial population must be $n"
individuals
end

"""
initial_population(method, individual::Function)
Expand All @@ -97,14 +108,12 @@ initial_population(method::M, individualFunc::Function) where {M<:AbstractOptimi
[individualFunc() for i in 1:population_size(method)]

"""
initial_population(method, individuals::AbstractMatrix)
initial_population(method, individual::AbstractMatrix)
Initialize population from the `inividuals` matrix where each individual is a column.
Initialize population by replicating the `inividual` matrix.
"""
function initial_population(method::M, individuals::I) where {M<:AbstractOptimizer, I<:AbstractMatrix}
n = population_size(method)
@assert size(individuals,2) >= n "Size of initial population must be no smaller then $n"
return [individuals[:,i] for i in 1:n]
function initial_population(method::M, individual::I) where {M<:AbstractOptimizer, I<:AbstractMatrix}
[copy(individual) for i in 1:population_size(method)]
end

"""
Expand Down Expand Up @@ -133,5 +142,5 @@ function initial_population(method::M, bounds::ConstraintBounds) where {M<:Abstr
indv[j,i] += l
end
end
initial_population(method, indv)
initial_population(method, [collect(i) for i in eachcol(indv)])
end
16 changes: 10 additions & 6 deletions src/cmaes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,13 @@ function update_state!(objfun, state::CMAESState{T,TI}, population::AbstractVect
weights = view(w, 1:μ)
E_NormN = sqrt(N)*(1-1/(4*N)+1/(21*N*N))

parent = reshape(state.parent,N)
parentshape = size(state.parent)

z = zeros(T, N, λ)
# y = zeros(T, N, λ)
= zeros(T, N)
offspring = Array{TI}(undef, λ)
offspring = Array{Vector{T}}(undef, λ)
fitoff = fill(Inf, λ)

B, D = try
Expand All @@ -141,23 +144,23 @@ function update_state!(objfun, state::CMAESState{T,TI}, population::AbstractVect
# y[:,i] = B * D * z[:,i]
# y[:,i] = SqrtC * z[:,i]
# offspring[i] = state.parent + σ * y[:,i]
offspring[i] = state.parent + σ * B * D * z[:,i]
fitoff[i] = value(objfun, offspring[i]) # Evaluate fitness
offspring[i] = parent + σ * B * D * z[:,i]
fitoff[i] = value(objfun, reshape(offspring[i],parentshape...)) # Evaluate fitness
end

# Select new parent population
idx = sortperm(fitoff)
for i in 1:μ
o = offspring[idx[i]]
population[i] = o
.+=(o.-state.parent).*(w[i]/σ)
population[i] = reshape(o,parentshape...)
.+=(o.-parent).*(w[i]/σ)
state.fitpop[i] = fitoff[idx[i]]
end

# y_λ = view(y,:,idx)
z_λ = view(z,:,idx)
= vec(sum(z_λ[:,1:μ].*weights', dims=2))
state.parent += (cₘ*σ).*# forming recombinant perent for next generation
parent += (cₘ*σ).*# forming recombinant perent for next generation
state.s_σ = (1 - c_σ)*state.s_σ + sqrt(μ_eff*c_σ*(2 - c_σ))*(B*z̄)
# state.s_σ = (1 - c_σ)*state.s_σ + sqrt(μ_eff*c_σ*(2 - c_σ))*(SqrtC*ȳ)
state.σ = σ * exp((c_σ/d_σ)*(norm(state.s_σ)/E_NormN - 1))
Expand All @@ -175,6 +178,7 @@ function update_state!(objfun, state::CMAESState{T,TI}, population::AbstractVect
state.C = (1 - c_1 - c_μ*sum(w)).*state.C + rank_1 + rank_μ

state.fittest = population[1]
state.parent = reshape(parent,parentshape...)

return false
end
9 changes: 8 additions & 1 deletion test/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,20 @@
##############
pop = Evolutionary.initial_population(mthd, BitVector(ones(dimension)))
@test length(pop) == population_size(mthd)
@test size(first(pop)) == (dimension,)

@test_throws AssertionError Evolutionary.initial_population(mthd, fill(BitVector(ones(dimension)),4))
pop = Evolutionary.initial_population(mthd, fill(BitVector(ones(dimension)),5))
@test length(pop) == population_size(mthd)
@test size(first(pop)) == (dimension,)

@test_throws AssertionError Evolutionary.initial_population(mthd, BitMatrix(ones(dimension,4)))
pop = Evolutionary.initial_population(mthd, BitMatrix(ones(dimension,6)))
@test length(pop) == population_size(mthd)
@test size(first(pop)) == (dimension,6)

pop = Evolutionary.initial_population(mthd, (()->rand(Bool,dimension)))
@test length(pop) == population_size(mthd)
@test size(first(pop)) == (dimension,)

lb = [0,1,2,-1]
ub = [0,3,2,1]
Expand Down
21 changes: 21 additions & 0 deletions test/regression.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@testset "Rastrigin" begin
## data
m, n, n2 = 9, 6, 3
X, A, E = randn(m, n), randn(n, n2), randn(m, n2) * 0.1
Y = X * A + E
r = 0.1

linear(w) = sum(abs2, Y .- X*w)
ridge(w) = linear(w) + r*sum(abs2, w)
ridgevec(w) = ridge(reshape(w,n,n2))

# using vector individual
result = Evolutionary.optimize(ridgevec, randn(n*n2), CMAES=100, c_1=0.05))
@test sum(abs, inv(X'X + r * I)*X'*Y .- reshape(Evolutionary.minimizer(result), n, n2)) 0.001 atol=1e-3

# using matrix individual
res1 = Evolutionary.optimize(linear, randn(n,n2), CMAES=100, c_1=0.05))
res2 = Evolutionary.optimize(ridge, randn(n,n2), CMAES=100, c_1=0.05))
@test sum(abs, inv(X'X )*X'*Y .- Evolutionary.minimizer(res1)) 0.001 atol=1e-3
@test sum(abs, inv(X'X + r * I)*X'*Y .- Evolutionary.minimizer(res2)) 0.001 atol=1e-3
end
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ for tests in [
"rastrigin.jl",
"n-queens.jl",
"knapsack.jl",
"onemax.jl"
"onemax.jl",
"regression.jl"
]
include(tests)
end

0 comments on commit 516ce4f

Please sign in to comment.