Skip to content

Commit

Permalink
Refactor algorithm local search
Browse files Browse the repository at this point in the history
  • Loading branch information
ajnebro committed May 9, 2024
1 parent ae3da9f commit b4726af
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 138 deletions.
61 changes: 61 additions & 0 deletions src/algorithm/NSGAII.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Dates

mutable struct NSGAII <: Algorithm
problem::Problem
populationSize::Int
numberOfEvaluations::Int

foundSolutions::Vector

termination::Termination
mutation::MutationOperator
crossover::CrossoverOperator

solver::EvolutionaryAlgorithm

dominanceComparator::Function

function NSGAII()
algorithm = new()
algorithm.solver = EvolutionaryAlgorithm()
algorithm.solver.name = "NSGA-II"

algorithm.dominanceComparator = compareForDominance
return algorithm
end
end

function nsgaII(nsgaII::NSGAII)
solver = nsgaII.solver

solver.problem = nsgaII.problem
solver.populationSize = nsgaII.populationSize
solver.offspringPopulationSize = nsgaII.populationSize

solver.solutionsCreation = DefaultSolutionsCreation((problem = solver.problem, numberOfSolutionsToCreate = solver.populationSize))

solver.evaluation = SequentialEvaluation((problem = solver.problem, ))

solver.termination = nsgaII.termination
solver.variation = CrossoverAndMutationVariation(solver.offspringPopulationSize, nsgaII.crossover, nsgaII.mutation)

solver.replacement = RankingAndDensityEstimatorReplacement(nsgaII.dominanceComparator)

solver.selection = BinaryTournamentSelection(solver.variation.matingPoolSize, compareRankingAndCrowdingDistance)

return evolutionaryAlgorithm(solver)
end

function optimize(algorithm::NSGAII)
algorithm.foundSolutions = nsgaII(algorithm)

return Nothing
end

function name(nsgaII::NSGAII)
return name(nsgaII.solver)
end

function getObservable(nsgaII::NSGAII)
return getObservable(nsgaII.solver)
end
136 changes: 0 additions & 136 deletions src/algorithm/algorithm.jl

This file was deleted.

74 changes: 74 additions & 0 deletions src/algorithm/evolutionaryAlgorithm.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Dates

mutable struct EvolutionaryAlgorithm <: Algorithm
name::String
problem::Problem
populationSize::Int
offspringPopulationSize::Int

foundSolutions::Vector

solutionsCreation::SolutionsCreation
evaluation::Evaluation
termination::Termination
selection::Selection
variation::Variation
replacement::Replacement

observable::Observable

status::Dict

function EvolutionaryAlgorithm()
x = new()
x.name = "Evolutionary algorithm"
x.observable = Observable("EvolutionaryAlgorithm observable")
return return x
end
end

function getObservable(algorithm::EvolutionaryAlgorithm)
return algorithm.observable
end

function evolutionaryAlgorithm(ea::EvolutionaryAlgorithm)
startingTime = Dates.now()

population = create(ea.solutionsCreation)
population = evaluate(population, ea.evaluation)

evaluations = length(population)
ea.status = Dict("EVALUATIONS" => evaluations, "POPULATION" => population, "COMPUTING_TIME" => (Dates.now() - startingTime))

notify(ea.observable, ea.status)

while !isMet(ea.status, ea.termination)
matingPool = select(population, ea.selection)

offspringPopulation = variate(population, matingPool, ea.variation)
offspringPopulation = evaluate(offspringPopulation, ea.evaluation)

population = replace_(population, offspringPopulation, ea.replacement)

evaluations += length(offspringPopulation)
ea.status["EVALUATIONS"] = evaluations
ea.status["POPULATION"] = population
ea.status["COMPUTING_TIME"] = Dates.now() - startingTime

notify(ea.observable, ea.status)
end

foundSolutions = population
return foundSolutions
end

function optimize(algorithm::EvolutionaryAlgorithm)
algorithm.foundSolutions = evolutionaryAlgorithm(algorithm)

return Nothing
end

function name(algorithm::EvolutionaryAlgorithm)
return algorithm.name
end

8 changes: 6 additions & 2 deletions src/algorithm/localSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ mutable struct LocalSearch <: Algorithm
numberOfIterations::Int
mutation::MutationOperator
foundSolution::Solution

function LocalSearch(startingSolution, problem, numberOfIterations, mutation)
return new(startingSolution, problem, numberOfIterations, mutation, copySolution(startingSolution))
end
end

function optimize(algorithm::LocalSearch)::Solution
Expand All @@ -14,7 +18,7 @@ function optimize(algorithm::LocalSearch)::Solution

for _ in 1:numberOfIterations
mutatedSolution = copySolution(algorithm.startingSolution)
mutatedSolution.variables = mutate(mutatedSolution.variables, mutation)
mutatedSolution = mutate(mutatedSolution, mutation)

mutatedSolution = evaluate(mutatedSolution, problem)

Expand All @@ -23,7 +27,7 @@ function optimize(algorithm::LocalSearch)::Solution
end
end

algorithm.foundSolution = foundSolution
algorithm.foundSolution = currentSolution

return currentSolution
end
6 changes: 6 additions & 0 deletions src/metajul.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ include("component/evolutionaryAlgorithm/replacement.jl")
export normalizeObjectives, distanceBasedSubsetSelection
include("util/utils.jl")

export Observable, EvaluationObserver
include("util/observer.jl")

export BinaryProblem, ContinuousProblem, constrainedProblem
export addObjective, addVariable, addConstraint, createSolution, evaluate, setName, name
export bounds
Expand All @@ -88,5 +91,8 @@ include("problem/multiObjective/kursawe.jl")
include("problem/multiObjective/ZDT.jl")
include("problem/multiObjective/oneZeroMax.jl")

export LocalSearch
export optimize
include("algorithm/localSearch.jl")

end # module metajul
29 changes: 29 additions & 0 deletions test/algorithm/localSearchTest.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function localSearchIsProperlyInitialized()
problem = schaffer()
startingSolution = createSolution(problem)
numberOfIterations = 10
mutation = PolynomialMutation(1.0 / numberOfVariables(problem), 20.0, problem.bounds)

algorithm = LocalSearch(startingSolution, problem, numberOfIterations, mutation)

return problem == algorithm.problem && numberOfIterations == algorithm.numberOfIterations && mutation == algorithm.mutation && startingSolution == algorithm.startingSolution
end

function localSearchWithZeroIterationsReturnsTheStartingSolution()
problem = schaffer()
startingSolution = createSolution(problem)
numberOfIterations = 0
mutation = UniformMutation(0.01, 20.0, problem.bounds)

algorithm = LocalSearch(startingSolution, problem, numberOfIterations, mutation)
optimize(algorithm)

return startingSolution == algorithm.foundSolution
end


@testset "Constraint handling functions tests" begin
@test localSearchIsProperlyInitialized()
@test localSearchWithZeroIterationsReturnsTheStartingSolution()
end

8 changes: 8 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,11 @@ problemTests = [
for testProgram in problemTests
include(testProgram)
end

algorithmTests = [
"algorithm/localSearchTest.jl",
]

for testProgram in algorithmTests
include(testProgram)
end

0 comments on commit b4726af

Please sign in to comment.