From 27bcecad986ead9f2a365ee4d8020458bc86af46 Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Tue, 28 Feb 2023 14:05:30 -0600 Subject: [PATCH 1/9] implementing coevo --- src/algorithms/Coevo/Coevo.jl | 56 +++++++++++++++++++++++++++++++ src/algorithms/Coevo/migration.jl | 5 +++ 2 files changed, 61 insertions(+) create mode 100644 src/algorithms/Coevo/Coevo.jl create mode 100644 src/algorithms/Coevo/migration.jl diff --git a/src/algorithms/Coevo/Coevo.jl b/src/algorithms/Coevo/Coevo.jl new file mode 100644 index 00000000..ba2f100d --- /dev/null +++ b/src/algorithms/Coevo/Coevo.jl @@ -0,0 +1,56 @@ +mutable struct Coevo <: AbstractParameters + optimizers::Vector + fitness::Vector + migration_scheme + problems::Vector{Problem} + states::Vector{Status} +end + + +function initialize!( + main_status, + coevo::Coevo, + main_problem::AbstractProblem, + information::Information, + options::Options, + args...; + kargs...) + + coevo.problems = [Problem(fn, problem.bounds) for fn in coevo.fitness] + + for (status, optimizer, problem) in zip(coevo.states, coevo.optimizers, coevo.problems) + initialize!(st, parameters, problem, information, options, args...; kargs...) + end + +end + + +function update_state!( + main_status, + parameters::Coevo, + main_problem::AbstractProblem, + information::Information, + options::Options, + args...; + kargs...) + + for (status, optimizer, problem) in zip(coevo.states, coevo.optimizers, coevo.problems) + update_state!(status, parameters, problem, information, options, args...; kargs...) + end + +end + + +function final_stage!( + main_status, + parameters::Coevo, + main_problem::AbstractProblem, + information::Information, + options::Options, + args...; + kargs... + ) + for (status, optimizer, problem) in zip(coevo.states, coevo.optimizers, coevo.problems) + final_stage!(status, parameters, problem, information, options, args...; kargs...) + end +end diff --git a/src/algorithms/Coevo/migration.jl b/src/algorithms/Coevo/migration.jl new file mode 100644 index 00000000..1a75627d --- /dev/null +++ b/src/algorithms/Coevo/migration.jl @@ -0,0 +1,5 @@ +abstract type AbstractMigration end + +struct Migrate <: AbstractMigration + kind::Symbol +end From c87d1e9c9137bb5a93bbcac6207c5e8ec2c65d92 Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Tue, 7 Mar 2023 00:14:30 -0600 Subject: [PATCH 2/9] remove coevo --- src/algorithms/Coevo/Coevo.jl | 56 ------------------------------- src/algorithms/Coevo/migration.jl | 5 --- 2 files changed, 61 deletions(-) delete mode 100644 src/algorithms/Coevo/Coevo.jl delete mode 100644 src/algorithms/Coevo/migration.jl diff --git a/src/algorithms/Coevo/Coevo.jl b/src/algorithms/Coevo/Coevo.jl deleted file mode 100644 index ba2f100d..00000000 --- a/src/algorithms/Coevo/Coevo.jl +++ /dev/null @@ -1,56 +0,0 @@ -mutable struct Coevo <: AbstractParameters - optimizers::Vector - fitness::Vector - migration_scheme - problems::Vector{Problem} - states::Vector{Status} -end - - -function initialize!( - main_status, - coevo::Coevo, - main_problem::AbstractProblem, - information::Information, - options::Options, - args...; - kargs...) - - coevo.problems = [Problem(fn, problem.bounds) for fn in coevo.fitness] - - for (status, optimizer, problem) in zip(coevo.states, coevo.optimizers, coevo.problems) - initialize!(st, parameters, problem, information, options, args...; kargs...) - end - -end - - -function update_state!( - main_status, - parameters::Coevo, - main_problem::AbstractProblem, - information::Information, - options::Options, - args...; - kargs...) - - for (status, optimizer, problem) in zip(coevo.states, coevo.optimizers, coevo.problems) - update_state!(status, parameters, problem, information, options, args...; kargs...) - end - -end - - -function final_stage!( - main_status, - parameters::Coevo, - main_problem::AbstractProblem, - information::Information, - options::Options, - args...; - kargs... - ) - for (status, optimizer, problem) in zip(coevo.states, coevo.optimizers, coevo.problems) - final_stage!(status, parameters, problem, information, options, args...; kargs...) - end -end diff --git a/src/algorithms/Coevo/migration.jl b/src/algorithms/Coevo/migration.jl deleted file mode 100644 index 1a75627d..00000000 --- a/src/algorithms/Coevo/migration.jl +++ /dev/null @@ -1,5 +0,0 @@ -abstract type AbstractMigration end - -struct Migrate <: AbstractMigration - kind::Symbol -end From 5fcab6581bc3b0444e323f2ba2e1dfaca1d003f6 Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Tue, 7 Mar 2023 00:14:46 -0600 Subject: [PATCH 3/9] fix issue --- src/DecisionMaking/ROI.jl | 2 +- test/decisionmaking.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DecisionMaking/ROI.jl b/src/DecisionMaking/ROI.jl index dac61a41..92e524f6 100644 --- a/src/DecisionMaking/ROI.jl +++ b/src/DecisionMaking/ROI.jl @@ -91,7 +91,7 @@ function roiarchiving(population, w, parameters::ROIArchiving; verbose=true) δ_w = parameters.δ_w_transformed - size(w,2) != length(δ_w) && error("|weight_points| is different to |δ_w|") + size(w,1) != length(δ_w) && error("|weight_points| is different to |δ_w|") non_dominated = Metaheuristics.get_non_dominated_solutions_perm(population) isempty(non_dominated) && return Int[] diff --git a/test/decisionmaking.jl b/test/decisionmaking.jl index 2a903005..ed3f059a 100644 --- a/test/decisionmaking.jl +++ b/test/decisionmaking.jl @@ -21,20 +21,20 @@ end @testset "DecisionMaking: ROI" begin - function test_roi() + function test_roi(w = [0.1 0.9; 0.9 0.1], δ = [0.1,0.1]) _, _, pf = Metaheuristics.TestProblems.ZDT1(); res = State(pf[1], pf) - - w = [0.1 0.9; 0.9 0.1] - δ = [0.1,0.1] + method = ROIArchiving(δ) idx = decisionmaking(res, w, method) @test !isempty(idx) sols = best_alternative(res, w, method) @test length(sols) == length(idx) end + test_roi() + test_roi([0.0 1; 1 0; 0.5 0.5], [0.1, 0.2, 0.3]) end @testset "DecisionMaking: JMcDM" begin From 4b316eb4beba04189526a402b1c19b7049f3ecb7 Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Tue, 7 Mar 2023 14:57:39 -0600 Subject: [PATCH 4/9] add set_inital_solutions method --- src/Metaheuristics.jl | 3 ++ src/algorithms/algorithm.jl | 42 ------------------- src/common/gen_initial_state.jl | 67 ++++++++++++++++++++++++++++++ src/common/set_inital_solutions.jl | 49 ++++++++++++++++++++++ test/initial_solution.jl | 41 ++++++++++++++++++ test/runtests.jl | 15 +++---- 6 files changed, 168 insertions(+), 49 deletions(-) create mode 100644 src/common/gen_initial_state.jl create mode 100644 src/common/set_inital_solutions.jl create mode 100644 test/initial_solution.jl diff --git a/src/Metaheuristics.jl b/src/Metaheuristics.jl index 267aad54..deb34698 100644 --- a/src/Metaheuristics.jl +++ b/src/Metaheuristics.jl @@ -26,6 +26,7 @@ export GenerationalReplacement, ElitistReplacement export sample, LatinHypercubeSampling, Grid export εDE, Restart export optimize! +export set_inital_solutions! include("externals.jl") @@ -51,6 +52,8 @@ include("common/repair.jl") include("common/stop.jl") include("common/compare.jl") include("common/non-dominated-sorting.jl") +include("common/set_inital_solutions.jl") + include("TestProblems/TestProblems.jl") diff --git a/src/algorithms/algorithm.jl b/src/algorithms/algorithm.jl index 824f2f10..e69de29b 100644 --- a/src/algorithms/algorithm.jl +++ b/src/algorithms/algorithm.jl @@ -1,42 +0,0 @@ -""" - gen_initial_state(problem,parameters,information,options) - -Generate an initial state, i.e., compute uniformly distributed random vectors in bounds, -after that are evaluated in objective function. This method require that `parameters.N` -is valid attribute. -""" -gen_initial_state(problem,parameters,information,options,status::State{Any}) = gen_initial_state(problem,parameters,information,options) - - -function gen_initial_state(problem,parameters,information,options, status) - parameters.N != length(status.population) && - error("Population size in provided State differs from that in parameters") - - - size(problem.bounds,2) != length(get_position(status.best_sol)) && - error("Invalid population (dimension does not match with bounds)") - - return State(status.best_sol, status.population) - - -end - -function gen_initial_state(problem,parameters,information,options) - # population array - population = generate_population(parameters.N, problem,ε=options.h_tol) - - # best solution - best_solution = get_best(population) - - return State(best_solution, population; f_calls = length(population), iteration=1) -end - -function Base.show(io::IO, parameters::AbstractParameters) - s = typeof(parameters) - - vals = string.(map(f -> getfield(parameters, f), fieldnames(s))) - str = string(s) * "(" * join(string.(fieldnames(s)) .* "=" .* vals, ", ") * ")" - - print(io, str) -end - diff --git a/src/common/gen_initial_state.jl b/src/common/gen_initial_state.jl new file mode 100644 index 00000000..75f8ab20 --- /dev/null +++ b/src/common/gen_initial_state.jl @@ -0,0 +1,67 @@ +""" + gen_initial_state(problem,parameters,information,options) + +Generate an initial state, i.e., compute uniformly distributed random vectors in bounds, +after that are evaluated in objective function. This method require that `parameters.N` +is valid attribute. +""" +gen_initial_state(problem,parameters,information,options,status::State{Any}) = gen_initial_state(problem,parameters,information,options) + + +function gen_initial_state(problem,parameters,information,options, status) + if parameters.N != length(status.population) + options.debug && @warn("Population size in provided State differs from that in parameters") + end + + size(problem.bounds,2) != length(get_position(status.best_sol)) && + error("Invalid population (dimension does not match with bounds)") + + _complete_population!(status,problem,parameters,information,options) + + best_solution = get_best(status.population) + # check if a better solution was found + if is_better(status.best_sol, best_solution) + best_solution = status.best_sol + end + + return State(best_solution, status.population;f_calls = length(status.population)) +end + +function gen_initial_state(problem,parameters,information,options) + # population array + population = generate_population(parameters.N, problem,ε=options.h_tol) + + # best solution + best_solution = get_best(population) + + return State(best_solution, population; f_calls = length(population), iteration=1) +end + +function Base.show(io::IO, parameters::AbstractParameters) + s = typeof(parameters) + + vals = string.(map(f -> getfield(parameters, f), fieldnames(s))) + str = string(s) * "(" * join(string.(fieldnames(s)) .* "=" .* vals, ", ") * ")" + + print(io, str) +end + +function _complete_population!(status,problem,parameters,information,options) + if parameters.N < length(status.population) + # increase population if necessary + parameters.N = length(status.population) + # TODO: use this options.debug == true to show the message? + @warn("Population size increased to $(parameters.N) due to initial solutions.") + return + end + + if parameters.N > length(status.population) + # complete population with random in bounds + n = parameters.N - length(status.population) + missing_sols = generate_population(n, problem,ε=options.h_tol) + # insert new solution into population + append!(status.population, missing_sols) + end + +end + diff --git a/src/common/set_inital_solutions.jl b/src/common/set_inital_solutions.jl new file mode 100644 index 00000000..0604bf71 --- /dev/null +++ b/src/common/set_inital_solutions.jl @@ -0,0 +1,49 @@ +include("gen_initial_state.jl") + +function set_inital_solutions!(algo::AbstractAlgorithm, solution::AbstractSolution) + status = algo.status + if !isnothing(status.best_sol) && !isempty(status.population) + push!(status.population, solution) + else + algo.status = State(solution, [solution]) + end + algo +end + + +function set_inital_solutions!(algo::AbstractAlgorithm, x::AbstractVector, fx) + set_inital_solutions!(algo, create_child(x, fx)) +end + +function set_inital_solutions!(algo::AbstractAlgorithm, x::AbstractVector, f::Function) + set_inital_solutions!(algo, x, f(x)) +end + + +function set_inital_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, fX::AbstractVector) + n = size(X, 1) + m = length(fX) + + if n != m + @warn "$(n) decision vectors provided but $(m) objective values." + n = min(m, n) + println("Taking ", n, " as the number of initial solutions.") + end + + # nothing to do due to it is necessary the objective value + n == 0 && (return algo) + + # TODO: this part can be parallelized + for i in 1:n + set_inital_solutions!(algo, X[i,:], fX[i]) + end + + # TODO check population size provided in algo.parameters.N + + algo +end + +function set_inital_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, f::Function) + set_inital_solutions!(algo, X, [f(X[i,:]) for i in 1:size(X,1)]) +end + diff --git a/test/initial_solution.jl b/test/initial_solution.jl new file mode 100644 index 00000000..45230b94 --- /dev/null +++ b/test/initial_solution.jl @@ -0,0 +1,41 @@ + +@testset "Combinatorial" begin + + function run_initialized(problem) + ff, bounds, optimums = Metaheuristics.TestProblems.get_problem(problem) + + # number of function evaluations + f_calls = 0 + + f(x) = begin + f_calls += 1 + ff(x) + end + + options = Options(iterations = 3, f_calls_limit = 500) + information = Information() + + methods = [ABC, DE, ECA, PSO, SA, WOA, MCCGA, CGSA] + + for method in methods + println(method) + for N in [5, 10, 20] # vary the population size + println(N) + algo = method(N = N, options = options, information = information) + + # initial solutions + X = rand(10, size(bounds, 2)) + set_inital_solutions!(algo, X, f) + + res = optimize(f, bounds, algo) + @test length(res.population) == N #max(N, size(X, 1)) + #@test f_calls == nfes(res) + end + println("-----") + end + end + + for problem in [:sphere] + run_initialized(problem) + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 51c2d505..b4c9df8c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,13 +10,14 @@ Aqua.test_all(Metaheuristics, ambiguities = false) end for tests in [ - "common-methods.jl", - "box-constrained.jl", - "optimize_api.jl", - "constrained.jl", - "multi-objective.jl", - "combinatorial.jl", - "decisionmaking.jl" + # "common-methods.jl", + # "box-constrained.jl", + # "optimize_api.jl", + # "constrained.jl", + # "multi-objective.jl", + # "combinatorial.jl", + # "decisionmaking.jl" + "initial_solution.jl", ] include(tests) end From d641610668666803448bcdfc9bd035a1b828b79e Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Tue, 7 Mar 2023 21:50:41 -0600 Subject: [PATCH 5/9] handling initial solutions --- src/algorithms/ABC/ABC.jl | 5 ++++- src/algorithms/ABC/bee_dynamics.jl | 3 ++- src/algorithms/CGSA/CGSA.jl | 15 ++++----------- src/algorithms/MCCGA/MCCGA.jl | 7 ++----- src/algorithms/WOA/WOA.jl | 10 ++++------ 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/algorithms/ABC/ABC.jl b/src/algorithms/ABC/ABC.jl index cd1c3676..4f7f4218 100644 --- a/src/algorithms/ABC/ABC.jl +++ b/src/algorithms/ABC/ABC.jl @@ -90,7 +90,10 @@ function initialize!( options.debug && @info "Increasing f calls limit to $(options.f_calls_limit)" end - bees = initialbees(parameters.N, problem) + + _st = gen_initial_state(problem,parameters,information,options,status) + bees = [Bee(sol) for sol in _st.population] + nevals = length(bees) best_sol = deepcopy(getBestBee(bees)) diff --git a/src/algorithms/ABC/bee_dynamics.jl b/src/algorithms/ABC/bee_dynamics.jl index 9ee951b5..6489408b 100644 --- a/src/algorithms/ABC/bee_dynamics.jl +++ b/src/algorithms/ABC/bee_dynamics.jl @@ -137,9 +137,10 @@ function chooseBest(bees, best) return best end +#= function initialbees(N, problem) P = generate_population(N, problem) return [ Bee(sol) for sol in P ] end - +=# diff --git a/src/algorithms/CGSA/CGSA.jl b/src/algorithms/CGSA/CGSA.jl index 45f2be27..10a911e1 100644 --- a/src/algorithms/CGSA/CGSA.jl +++ b/src/algorithms/CGSA/CGSA.jl @@ -135,17 +135,11 @@ function initialize!( max_it = 500 options.iterations = options.iterations == 0 ? max_it : options.iterations - options.f_calls_limit = options.f_calls_limit == 0 ? options.iterations * N : options.f_calls_limit # random initialization for agents. - P = generate_population(N, problem) - - # Current best - theBest = get_best(P) - - - status = State(theBest, P) - status.f_calls = N + status = gen_initial_state(problem,parameters,information,options,status) + N = parameters.N + options.f_calls_limit = options.f_calls_limit == 0 ? options.iterations * N : options.f_calls_limit # Velocity parameters.V = isempty(parameters.V) ? zeros(N,D) : parameters.V @@ -153,8 +147,7 @@ function initialize!( parameters.X = isempty(parameters.X) ? positions(status) : parameters.X # function values if isempty(parameters.fitness) - - parameters.fitness = fval.(status.population) + parameters.fitness = fvals(status.population) end diff --git a/src/algorithms/MCCGA/MCCGA.jl b/src/algorithms/MCCGA/MCCGA.jl index e6d34043..0aafc47a 100644 --- a/src/algorithms/MCCGA/MCCGA.jl +++ b/src/algorithms/MCCGA/MCCGA.jl @@ -125,11 +125,8 @@ function initialize!( parameters.probvector = initialprobs(lower, upper, maxsamples = parameters.maxsamples) - # sample a vector to create an initial State - x = sample(parameters.probvector) |> floats - initial_sol = create_solution(x, problem) - return State(initial_sol, [initial_sol for i in 1:parameters.N]) - + # sample vectors to create an initial State + return gen_initial_state(problem,parameters,information,options,status) end function update_state!( diff --git a/src/algorithms/WOA/WOA.jl b/src/algorithms/WOA/WOA.jl index 66230098..3b826ef1 100644 --- a/src/algorithms/WOA/WOA.jl +++ b/src/algorithms/WOA/WOA.jl @@ -82,16 +82,14 @@ function initialize!( options.iterations * parameters.N : options.f_calls_limit - P = generate_population(parameters.N, problem) - best_sol = deepcopy(get_best(P)) - status = State(best_sol, P) + # P = generate_population(parameters.N, problem) + # best_sol = deepcopy(get_best(P)) + # status = State(best_sol, P) #= status.population = P status.best_sol = deepcopy(get_best(status.population)) =# - status.f_calls = parameters.N - - status + return gen_initial_state(problem,parameters,information,options,status) end From a01dbfd7829a902a0e23f5483a7a81b3fbcce62a Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Tue, 7 Mar 2023 21:51:17 -0600 Subject: [PATCH 6/9] test initial solutions --- test/initial_solution.jl | 55 ++++++++++++++++++++++++++++++++++------ test/runtests.jl | 14 +++++----- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/test/initial_solution.jl b/test/initial_solution.jl index 45230b94..067342d7 100644 --- a/test/initial_solution.jl +++ b/test/initial_solution.jl @@ -1,5 +1,4 @@ - -@testset "Combinatorial" begin +@testset "Initial Solutions" begin function run_initialized(problem) ff, bounds, optimums = Metaheuristics.TestProblems.get_problem(problem) @@ -14,28 +13,68 @@ options = Options(iterations = 3, f_calls_limit = 500) information = Information() + x_optimum = get_position(first(optimums)) - methods = [ABC, DE, ECA, PSO, SA, WOA, MCCGA, CGSA] + methods = [ABC, DE, ECA, PSO, WOA, MCCGA, CGSA] for method in methods - println(method) for N in [5, 10, 20] # vary the population size - println(N) algo = method(N = N, options = options, information = information) - # initial solutions X = rand(10, size(bounds, 2)) + X[1,:] = x_optimum #zeros(size(bounds, 2)) set_inital_solutions!(algo, X, f) res = optimize(f, bounds, algo) - @test length(res.population) == N #max(N, size(X, 1)) + + @test length(res.population) == algo.parameters.N + @test minimum(res) ≈ first(fvals(optimums)) + @test sum(abs,minimizer(res)-x_optimum) ≈ 0 + # TODO check the number of function evaluations #@test f_calls == nfes(res) end - println("-----") + end + end + + function run_initialized_multiobjective(problem) + ff, bounds, optimums = Metaheuristics.TestProblems.get_problem(problem) + + # number of function evaluations + f_calls = 0 + + f(x) = begin + f_calls += 1 + ff(x) + end + + options = Options(iterations = 3, f_calls_limit = 500) + information = Information() + x_optimum = get_position(first(optimums)) + + methods = [SPEA2, SMS_EMOA, NSGA2, NSGA3] + + for method in methods + for N in [5, 10, 20] # vary the population size + algo = method(N = N, options = options, information = information) + # initial solutions + X = rand(10, size(bounds, 2)) + X[1,:] = x_optimum + set_inital_solutions!(algo, X, f) + + res = optimize(f, bounds, algo) + @test length(res.population) == algo.parameters.N + # check whether optimum was used by optimizer + v = sum(abs.(positions(res) .- x_optimum'), dims=2) |> minimum + @test v ≈ 0 + end end end for problem in [:sphere] run_initialized(problem) end + + for problem in [:ZDT1] + run_initialized_multiobjective(problem) + end end diff --git a/test/runtests.jl b/test/runtests.jl index b4c9df8c..7e312ce4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,13 +10,13 @@ Aqua.test_all(Metaheuristics, ambiguities = false) end for tests in [ - # "common-methods.jl", - # "box-constrained.jl", - # "optimize_api.jl", - # "constrained.jl", - # "multi-objective.jl", - # "combinatorial.jl", - # "decisionmaking.jl" + "common-methods.jl", + "box-constrained.jl", + "optimize_api.jl", + "constrained.jl", + "multi-objective.jl", + "combinatorial.jl", + "decisionmaking.jl", "initial_solution.jl", ] include(tests) From e657910c45c2ddd8acad963657857415b23871f2 Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Wed, 8 Mar 2023 00:31:56 -0600 Subject: [PATCH 7/9] dostring for #68 --- docs/src/api.md | 4 ++++ src/common/set_inital_solutions.jl | 37 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/docs/src/api.md b/docs/src/api.md index a65644eb..b89950ad 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -106,6 +106,10 @@ Metaheuristics.compare Metaheuristics.gen_initial_state ``` +```@docs +set_inital_solutions! +``` + ## Variation ```@docs diff --git a/src/common/set_inital_solutions.jl b/src/common/set_inital_solutions.jl index 0604bf71..3bdfa9cd 100644 --- a/src/common/set_inital_solutions.jl +++ b/src/common/set_inital_solutions.jl @@ -1,5 +1,42 @@ include("gen_initial_state.jl") +""" + set_inital_solutions!(optimizer, x, fx) + +Provide initial solutions to the `optimizer`. +- `x` can be a `Vector` and `fx` a function or `fx = f(x)` +- `x` can be a matrix containing solutions in rows. + +### Example + +```julia-repl +julia> f(x) = abs(x[1]) + x[2] + x[3]^2 # objective function +f (generic function with 1 method) + +julia> algo = ECA(N = 61); # optimizer + +julia> # one solution can be provided + x0 = [0.5, 0.5 0.5]; + +julia> set_inital_solutions!(algo, x0, f); + +julia> # providing multiple solutions + X0 = rand(30, 3); # 30 solutions with dim 3 + +julia> set_inital_solutions!(algo, X0, f); + +julia> optimize(f, [0 0 0; 1 1 1.0], algo) ++=========== RESULT ==========+ + iteration: 413 + minimum: 0 + minimizer: [0.0, 0.0, 0.0] + f calls: 25132 + total time: 0.0856 s +stop reason: Small difference of objective function values. ++============================+ +``` + +""" function set_inital_solutions!(algo::AbstractAlgorithm, solution::AbstractSolution) status = algo.status if !isnothing(status.best_sol) && !isempty(status.population) From dcf87a4e92786a1ae385501743bd049bdc960e4a Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Wed, 8 Mar 2023 09:57:51 -0600 Subject: [PATCH 8/9] rename method set_user_solutions --- docs/src/api.md | 2 +- src/Metaheuristics.jl | 4 ++-- ...tal_solutions.jl => set_user_solutions.jl} | 24 +++++++++---------- test/initial_solution.jl | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) rename src/common/{set_inital_solutions.jl => set_user_solutions.jl} (65%) diff --git a/docs/src/api.md b/docs/src/api.md index b89950ad..5a0ef53b 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -107,7 +107,7 @@ Metaheuristics.gen_initial_state ``` ```@docs -set_inital_solutions! +set_user_solutions! ``` ## Variation diff --git a/src/Metaheuristics.jl b/src/Metaheuristics.jl index deb34698..4da88a80 100644 --- a/src/Metaheuristics.jl +++ b/src/Metaheuristics.jl @@ -26,7 +26,7 @@ export GenerationalReplacement, ElitistReplacement export sample, LatinHypercubeSampling, Grid export εDE, Restart export optimize! -export set_inital_solutions! +export set_user_solutions! include("externals.jl") @@ -52,7 +52,7 @@ include("common/repair.jl") include("common/stop.jl") include("common/compare.jl") include("common/non-dominated-sorting.jl") -include("common/set_inital_solutions.jl") +include("common/set_user_solutions.jl") diff --git a/src/common/set_inital_solutions.jl b/src/common/set_user_solutions.jl similarity index 65% rename from src/common/set_inital_solutions.jl rename to src/common/set_user_solutions.jl index 3bdfa9cd..b1c3f123 100644 --- a/src/common/set_inital_solutions.jl +++ b/src/common/set_user_solutions.jl @@ -1,7 +1,7 @@ include("gen_initial_state.jl") """ - set_inital_solutions!(optimizer, x, fx) + set_user_solutions!(optimizer, x, fx) Provide initial solutions to the `optimizer`. - `x` can be a `Vector` and `fx` a function or `fx = f(x)` @@ -18,12 +18,12 @@ julia> algo = ECA(N = 61); # optimizer julia> # one solution can be provided x0 = [0.5, 0.5 0.5]; -julia> set_inital_solutions!(algo, x0, f); +julia> set_user_solutions!(algo, x0, f); julia> # providing multiple solutions X0 = rand(30, 3); # 30 solutions with dim 3 -julia> set_inital_solutions!(algo, X0, f); +julia> set_user_solutions!(algo, X0, f); julia> optimize(f, [0 0 0; 1 1 1.0], algo) +=========== RESULT ==========+ @@ -37,7 +37,7 @@ stop reason: Small difference of objective function values. ``` """ -function set_inital_solutions!(algo::AbstractAlgorithm, solution::AbstractSolution) +function set_user_solutions!(algo::AbstractAlgorithm, solution::AbstractSolution) status = algo.status if !isnothing(status.best_sol) && !isempty(status.population) push!(status.population, solution) @@ -48,16 +48,16 @@ function set_inital_solutions!(algo::AbstractAlgorithm, solution::AbstractSoluti end -function set_inital_solutions!(algo::AbstractAlgorithm, x::AbstractVector, fx) - set_inital_solutions!(algo, create_child(x, fx)) +function set_user_solutions!(algo::AbstractAlgorithm, x::AbstractVector, fx) + set_user_solutions!(algo, create_child(x, fx)) end -function set_inital_solutions!(algo::AbstractAlgorithm, x::AbstractVector, f::Function) - set_inital_solutions!(algo, x, f(x)) +function set_user_solutions!(algo::AbstractAlgorithm, x::AbstractVector, f::Function) + set_user_solutions!(algo, x, f(x)) end -function set_inital_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, fX::AbstractVector) +function set_user_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, fX::AbstractVector) n = size(X, 1) m = length(fX) @@ -72,7 +72,7 @@ function set_inital_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, fX::A # TODO: this part can be parallelized for i in 1:n - set_inital_solutions!(algo, X[i,:], fX[i]) + set_user_solutions!(algo, X[i,:], fX[i]) end # TODO check population size provided in algo.parameters.N @@ -80,7 +80,7 @@ function set_inital_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, fX::A algo end -function set_inital_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, f::Function) - set_inital_solutions!(algo, X, [f(X[i,:]) for i in 1:size(X,1)]) +function set_user_solutions!(algo::AbstractAlgorithm, X::AbstractMatrix, f::Function) + set_user_solutions!(algo, X, [f(X[i,:]) for i in 1:size(X,1)]) end diff --git a/test/initial_solution.jl b/test/initial_solution.jl index 067342d7..6ceab1ed 100644 --- a/test/initial_solution.jl +++ b/test/initial_solution.jl @@ -23,7 +23,7 @@ # initial solutions X = rand(10, size(bounds, 2)) X[1,:] = x_optimum #zeros(size(bounds, 2)) - set_inital_solutions!(algo, X, f) + set_user_solutions!(algo, X, f) res = optimize(f, bounds, algo) @@ -59,7 +59,7 @@ # initial solutions X = rand(10, size(bounds, 2)) X[1,:] = x_optimum - set_inital_solutions!(algo, X, f) + set_user_solutions!(algo, X, f) res = optimize(f, bounds, algo) @test length(res.population) == algo.parameters.N From 48a7eabf63b31283b63e375442010168abbd21a7 Mon Sep 17 00:00:00 2001 From: Jesus Mejia Date: Wed, 8 Mar 2023 10:04:49 -0600 Subject: [PATCH 9/9] update version, and other minor update --- Project.toml | 2 +- src/common/set_user_solutions.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 75614acf..99b7ebd9 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Metaheuristics" uuid = "bcdb8e00-2c21-11e9-3065-2b553b22f898" authors = ["Jesus Mejia "] -version = "3.2.14" +version = "3.2.15" [deps] Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" diff --git a/src/common/set_user_solutions.jl b/src/common/set_user_solutions.jl index b1c3f123..757d78b1 100644 --- a/src/common/set_user_solutions.jl +++ b/src/common/set_user_solutions.jl @@ -16,7 +16,7 @@ f (generic function with 1 method) julia> algo = ECA(N = 61); # optimizer julia> # one solution can be provided - x0 = [0.5, 0.5 0.5]; + x0 = [0.5, 0.5, 0.5]; julia> set_user_solutions!(algo, x0, f);