-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
aacd34d
commit fdf2239
Showing
3 changed files
with
230 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
#' @title | ||
#' Implementation of the NSGA-II EMOA algorithm by Deb. | ||
#' | ||
#' @description | ||
#' The AS-EMOA, short for aspiration set evolutionary multi-objective algorithm, | ||
#' aims to incorporate expert knowledge into multi-objective optimization [1]. | ||
#' The algorithm expects an aspiration set, i.e., a set of reference points. It | ||
#' then creates an appriximation of the pareto front close to the aspiration set | ||
#' utilizing the average Hausdorff distance. | ||
#' | ||
#' @note | ||
#' This is a pure R implementation of the NSGA-II algorithm. It hides the regular | ||
#' \pkg{ecr} interface and offers a more R like interface while still being quite | ||
#' adaptable. | ||
#' | ||
#' @references Rudolph, G., Schuetze, S., Grimme, C., Trautmann, H: An Aspiration Set | ||
#' EMOA Based on Averaged Hausdorff Distances. LION 2014: 153-156. | ||
#' | ||
#' @param task [\code{ecr_optimization_task} | \code{smoof_function}]\cr | ||
#' Optimization task or objective function of type \code{smoof_function}. | ||
#' @param n.population [\code{integer(1)}]\cr | ||
#' Population size. Default is \code{100}. | ||
#' @param n.offspring [\code{integer(1)}]\cr | ||
#' Offspring size, i.e., number of individuals generated by variation operators | ||
#' in each iteration. Default is \code{n.population}. | ||
#' @param aspiration.set [\code{matrix}]\cr | ||
#' The aspiration set. Each column contains one point of the set. | ||
#' @param n.archive [\code{integer(1)}]\cr | ||
#' Size of the pareto archive, i.e., the number of nondominated points which we | ||
#' aim to generate. Default is \code{ncol(aspiration.set)}. | ||
#' @template arg_parent_selector | ||
#' @template arg_mutator | ||
#' @template arg_recombinator | ||
#' @param max.iter [\code{integer(1)}]\cr | ||
#' Maximal number of iterations. Default ist \code{100L}. | ||
#' @param max.evals [\code{integer(1)}]\cr | ||
#' Maximal number of iterations/generations. Default is \code{Inf}. | ||
#' @param max.time [\code{integer(1)}]\cr | ||
#' Time budget in seconds. Default ist \code{Inf}. | ||
#' @return [\code{ecr_ecr_multi_objective_result}] | ||
#' @export | ||
asemoa = function( | ||
task, | ||
n.population = 100L, n.offspring = n.population, | ||
aspiration.set = NULL, | ||
n.archive, | ||
parent.selector = makeSimpleSelector(), | ||
mutator = makeGaussMutator(), | ||
recombinator = makeCrossoverRecombinator(), | ||
max.iter = 100L, | ||
max.evals = NULL, | ||
max.time = NULL) { | ||
|
||
if (isSmoofFunction(task)) { | ||
task = makeOptimizationTask(task) | ||
} | ||
assertMatrix(aspiration.set, mode = "numeric", any.missing = FALSE, all.missing = FALSE, min.rows = 2L) | ||
if (nrow(aspiration.set) != task$n.objectives) { | ||
stopf("AS-EMAO: Dimension of the aspiration set needs to be equal to the number of objectives, | ||
but %i <> %i.", nrow(aspiration.set), task$n.objectives) | ||
} | ||
if (is.null(n.archive)) { | ||
n.archive = ncol(aspiration.set) | ||
} | ||
assertInt(n.archive, na.ok = FALSE, lower = 2L) | ||
|
||
# This is the main selection mechanism of the AS-EMOA. | ||
# Remove the point which leads to highest | ||
deltaOneUpdate = function(set, aspiration.set) { | ||
# here we need to apply this strange information. See the reference for details | ||
# yeah, I could use range here but it is more readable this way | ||
min1 = min(aspiration.set[1L, ]) | ||
min2 = min(aspiration.set[2L, ]) | ||
max1 = max(aspiration.set[1L, ]) | ||
max2 = max(aspiration.set[2L, ]) | ||
|
||
# transform | ||
set[1L, ] = (set[1L, ] - min1) / (max2 - min2) | ||
set[2L, ] = (set[2L, ] - min2) / (max1 - min1) | ||
|
||
return(computeAverageHausdorffDistance(set, aspiration.set)) | ||
} | ||
|
||
# Implementation of surival selection operator of the AS-EMOA algorithm. | ||
asemoaSelector = makeSelector( | ||
selector = function(population, storage, n.select, control) { | ||
fitness = population$fitness | ||
population = population$individuals | ||
|
||
# filter nondominated points | ||
nondom.idx = which.nondominated(fitness) | ||
population = population[nondom.idx] | ||
fitness = fitness[, nondom.idx, drop = FALSE] | ||
|
||
n.archive = control$n.archive | ||
# if maximal number of individuals is not exceeded yet | ||
# simply return | ||
if (length(population) <= n.archive) { | ||
return(makePopulation(population, fitness)) | ||
} | ||
|
||
# Otherwise we need to do the computationally more expensive part | ||
hausdorffDistances = lapply(seq(length(population)), function(idx) { | ||
deltaOneUpdate(fitness[, -idx, drop = FALSE], control$aspiration.set) | ||
}) | ||
|
||
#FIXME: here we need to check if there are multiple elements with this distance | ||
tmp = getMinIndex(hausdorffDistances) | ||
|
||
return(makePopulation(population[-tmp], fitness[, -tmp, drop = FALSE])) | ||
}, | ||
supported.objectives = "multi-objective", | ||
name = "AS-EMOA selector", | ||
description = "Selection takes place based on (modified) average Hausdorff metric" | ||
) | ||
|
||
asemoaGenerator = makeGenerator( | ||
generator = function(size, control) { | ||
uniformGenerator = makeUniformGenerator() | ||
population = uniformGenerator(size, control) | ||
#NOTE: here we use the objective function to compute the fitness values | ||
fitness = computeFitness(population, task$fitness.fun) | ||
# now filter out dominated solutions | ||
nondom.idx = which.nondominated(fitness) | ||
population$individuals = population$individuals[nondom.idx] | ||
return(population) | ||
}, | ||
name = "AS-EMOA generator", | ||
description = "Generates uniformaly and reduces to non-dominated set", | ||
supported = "float" | ||
) | ||
|
||
# AS-EMOA control object | ||
ctrl = setupECRControl( | ||
n.population = n.population, | ||
n.offspring = n.offspring, | ||
representation = "float", | ||
monitor = makeConsoleMonitor(), | ||
stopping.conditions = list( | ||
makeMaximumEvaluationsStoppingCondition(max.evals), | ||
makeMaximumTimeStoppingCondition(max.time), | ||
makeMaximumIterationsStoppingCondition(max.iter) | ||
) | ||
) | ||
|
||
ctrl = setupEvolutionaryOperators( | ||
ctrl, | ||
parent.selector = parent.selector, | ||
recombinator = recombinator, | ||
generator = asemoaGenerator, | ||
mutator = mutator, | ||
survival.selector = asemoaSelector | ||
) | ||
|
||
#FIXME: this is rather ugly. We simply add some more args to the control object | ||
# without sanity checks and stuff like that. | ||
ctrl$n.archive = n.archive | ||
ctrl$aspiration.set = aspiration.set | ||
|
||
return(doTheEvolution(task, ctrl)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
% Generated by roxygen2 (4.1.1): do not edit by hand | ||
% Please edit documentation in R/emoa.as-emoa.R | ||
\name{asemoa} | ||
\alias{asemoa} | ||
\title{Implementation of the NSGA-II EMOA algorithm by Deb.} | ||
\usage{ | ||
asemoa(task, n.population = 100L, n.offspring = n.population, | ||
aspiration.set = NULL, n.archive, parent.selector = makeSimpleSelector(), | ||
mutator = makeGaussMutator(), recombinator = makeCrossoverRecombinator(), | ||
max.iter = 100L, max.evals = NULL, max.time = NULL) | ||
} | ||
\arguments{ | ||
\item{task}{[\code{ecr_optimization_task} | \code{smoof_function}]\cr | ||
Optimization task or objective function of type \code{smoof_function}.} | ||
|
||
\item{n.population}{[\code{integer(1)}]\cr | ||
Population size. Default is \code{100}.} | ||
|
||
\item{n.offspring}{[\code{integer(1)}]\cr | ||
Offspring size, i.e., number of individuals generated by variation operators | ||
in each iteration. Default is \code{n.population}.} | ||
|
||
\item{aspiration.set}{[\code{matrix}]\cr | ||
The aspiration set. Each column contains one point of the set.} | ||
|
||
\item{n.archive}{[\code{integer(1)}]\cr | ||
Size of the pareto archive, i.e., the number of nondominated points which we | ||
aim to generate. Default is \code{ncol(aspiration.set)}.} | ||
|
||
\item{parent.selector}{[\code{ecr_selector}]\cr | ||
Selection operator which implements a procedure to copy individuals from a | ||
given population to the mating pool, i. e., allow them to become parents.} | ||
|
||
\item{mutator}{[\code{ecr_mutator}]\cr | ||
Mutation operator of type \code{ecr_mutator}.} | ||
|
||
\item{recombinator}{[\code{ecr_recombinator}]\cr | ||
Recombination operator of type \code{ecr_recombinator}.} | ||
|
||
\item{max.iter}{[\code{integer(1)}]\cr | ||
Maximal number of iterations. Default ist \code{100L}.} | ||
|
||
\item{max.evals}{[\code{integer(1)}]\cr | ||
Maximal number of iterations/generations. Default is \code{Inf}.} | ||
|
||
\item{max.time}{[\code{integer(1)}]\cr | ||
Time budget in seconds. Default ist \code{Inf}.} | ||
} | ||
\value{ | ||
[\code{ecr_ecr_multi_objective_result}] | ||
} | ||
\description{ | ||
The AS-EMOA, short for aspiration set evolutionary multi-objective algorithm, | ||
aims to incorporate expert knowledge into multi-objective optimization [1]. | ||
The algorithm expects an aspiration set, i.e., a set of reference points. It | ||
then creates an appriximation of the pareto front close to the aspiration set | ||
utilizing the average Hausdorff distance. | ||
} | ||
\note{ | ||
This is a pure R implementation of the NSGA-II algorithm. It hides the regular | ||
\pkg{ecr} interface and offers a more R like interface while still being quite | ||
adaptable. | ||
} | ||
\references{ | ||
Rudolph, G., Schuetze, S., Grimme, C., Trautmann, H: An Aspiration Set | ||
EMOA Based on Averaged Hausdorff Distances. LION 2014: 153-156. | ||
} | ||
|