diff --git a/R/doTheEvolution.R b/R/doTheEvolution.R index 8e4888c..b698fcb 100644 --- a/R/doTheEvolution.R +++ b/R/doTheEvolution.R @@ -51,6 +51,16 @@ doTheEvolution = function(objective.fun, control) { par.set = makeParamSet(makeNumericParam("dummy", lower = 0, upper = 1)) } + # check compatibility of selectors and #objectives + selectors = c(control$parent.selector, control$survival.selector) + desired.tag = if (n.objectives == 1L) "single-objective" else "multi-objective" + lapply(selectors, function(selector) { + if (desired.tag %nin% attr(selector, "supported.objectives")) { + stopf("Selector '%s' cannot be applied to problem with %i objectives.", + getOperatorName(selector), n.objectives) + } + }) + y.names = paste0("y", seq(n.objectives)) n.population = control$n.population diff --git a/R/getSupportedRepresentations.R b/R/getOperatorsTags.R similarity index 63% rename from R/getSupportedRepresentations.R rename to R/getOperatorsTags.R index af4ad74..fe74320 100644 --- a/R/getSupportedRepresentations.R +++ b/R/getOperatorsTags.R @@ -1,7 +1,4 @@ -#' Returns the representations which a specific operator supports. -#' -#' Operators and representation types are not mandatory compatible. This function -#' detemines the types an operator can operate on. +#' Returns the character vector of tags which describe a specific operator. #' #' @param operator [\code{ecr_operator}]\cr #' Operator object. diff --git a/R/makeSelector.R b/R/makeSelector.R index 46e7911..46891eb 100644 --- a/R/makeSelector.R +++ b/R/makeSelector.R @@ -10,12 +10,19 @@ # @param supported [\code{character}]\cr # Vector of strings/names of supported parameter representations. For example # 'permutation', 'float', 'binary'. +# @param supported.objectives [\code{character}]\cr +# At least one of \dQuote{single-objective} or \dQuote{multi-objective}. # @return [\code{ecr_selector}] # selector object. -makeSelector = function(selector, name, description, - supported = getAvailableRepresentations()) { +makeSelector = function( + selector, + name, description, + supported = getAvailableRepresentations(), + supported.objectives) { assertFunction(selector, args = c("population", "n.select", "control"), ordered = TRUE) + assertSubset(supported.objectives, c("single-objective", "multi-objective")) selector = makeOperator(selector, name, description, supported) + selector = setAttribute(selector, "supported.objectives", supported.objectives) selector = addClasses(selector, c("ecr_selector")) return(selector) } diff --git a/R/selector.greedy.R b/R/selector.greedy.R index 786e375..f94131d 100644 --- a/R/selector.greedy.R +++ b/R/selector.greedy.R @@ -15,6 +15,7 @@ makeGreedySelector = function() { makeSelector( selector = selector, name = "Greedy selector", - description = "Return the best individuals regarding the fitness value." + description = "Return the best individuals regarding the fitness value.", + supported.objectives = c("single-objective") ) } diff --git a/R/selector.k-tournament.R b/R/selector.k-tournament.R index 40d90e8..4e3cbf5 100644 --- a/R/selector.k-tournament.R +++ b/R/selector.k-tournament.R @@ -31,6 +31,7 @@ makeTournamentSelector = function(k = 3L) { makeSelector( selector = selector, name = "k-Tournament selector", - description = "Select k individuals at random, choose the best, repeat until mating pool is filled." + description = "Select k individuals at random, choose the best, repeat until mating pool is filled.", + supported.objectives = c("single-objective") ) } diff --git a/R/selector.roulettewheel.R b/R/selector.roulettewheel.R index b7a9040..7ea31ed 100644 --- a/R/selector.roulettewheel.R +++ b/R/selector.roulettewheel.R @@ -32,6 +32,7 @@ makeRouletteWheelSelector = function() { makeSelector( selector = selector, name = "Roulette-Wheel selector", - description = "Selects individuals in a fitness-proportional fashion." + description = "Selects individuals in a fitness-proportional fashion.", + supported.objectives = c("single-objective") ) } diff --git a/R/selector.simple.R b/R/selector.simple.R index 65383a3..9a017c8 100644 --- a/R/selector.simple.R +++ b/R/selector.simple.R @@ -17,6 +17,7 @@ makeSimpleSelector = function() { makeSelector( selector = selector, name = "Simple selector", - description = "Simply returns the entire population." + description = "Simply returns the entire population.", + supported.objectives = c("single-objective", "multi-objective") ) } diff --git a/R/setupECRControl.R b/R/setupECRControl.R index 9b9cbfb..885443c 100644 --- a/R/setupECRControl.R +++ b/R/setupECRControl.R @@ -100,7 +100,7 @@ setupECRControl = function( representation = representation, survival.strategy = survival.strategy, n.elite = n.elite, - n.targets = NULL, # we set this by hand here + #n.targets = n.targets, save.population.at = save.population.at, target.name = target.name, stopping.conditions = stopping.conditions, diff --git a/inst/examples/sms_emoa_example.R b/inst/examples/sms_emoa_example.R index c8fa2be..71fe6d3 100644 --- a/inst/examples/sms_emoa_example.R +++ b/inst/examples/sms_emoa_example.R @@ -1,6 +1,14 @@ library(smoof) library(ecr) +# THIS FILE IS WORK-IN-PROGRESS/EXPERIMENAL + +# COLLECTION OF FIXME +#FIXME: integrate NondominatedSetSelector as ecr_selector +#FIXME: we need to check in setupECRControl or in ecr if the operators can work +# on multi-objective stuff +# + # Get set of dominated individuals. # # @param x [list] @@ -8,7 +16,8 @@ library(ecr) # @param fn [function] # Fitness function. # @return [list] -#FIXME: formulate this for matrices where each column describes one vector +#FIXME: formulate this for matrices where each column describes one vector. However, +# this is just a naive imolementation for testing purpose. Will be replaced getDominatedSet = function(x) { n = length(x) @@ -44,41 +53,38 @@ makeNondominatedSetSelector = function() { survive.idx = setdiff(seq(n), idx) return(makePopulation(inds[survive.idx], population$fitness[, survive.idx, drop = FALSE])) }, - supported = "float", + supported.objectives = "multi-objective", name = "Nondominated set selector", description = "description" ) } ctrl = setupECRControl( - n.population = 10L, - n.offspring = 1L, + n.population = 20L, + n.offspring = 10L, representation = "float", monitor = makeConsoleMonitor() ) ctrl = setupEvolutionaryOperators( ctrl, + # tournamend and roulette wheel work on scalar fitness values only + # Thus, simply select two random elements for reproduction parent.selector = makeSimpleSelector(), mutator = makeGaussMutator(), recombinator = makeCrossoverRecombinator(), + # everything can be used, we just needed a multi-objective-specific survival selector survivalSelector = makeNondominatedSetSelector() ) obj.fn = smoof::makeZDT1Function(2L) res = doTheEvolution(obj.fn, ctrl) -stop("FIN") - - -# Determine the number of elements for each individual by which it is dominated. -# -# @param x [list] -# Set of fitness values. -# @return [integer] -# Each position contains the number of individuals by which this one is dominated. -#getDominanceNumber = function() -inds = list(c(1, 2), c(2, 1), c(2, 2), c(1, 3), c(1.5, 1.3)) - -print(getDominatedSet(inds)) +pl = smoof::visualizeParetoOptimalFront(obj.fn) +pf = res$pareto.front +pf = as.data.frame(t(pf)) +names(pf) = paste0("x", 1:2) +pl = pl + geom_point(data = pf, aes(x = x1, y = x2), colour = "green") +print(pl) +stop("FIN") diff --git a/man/getSupportedRepresentations.Rd b/man/getSupportedRepresentations.Rd index f84e8de..22d6c73 100644 --- a/man/getSupportedRepresentations.Rd +++ b/man/getSupportedRepresentations.Rd @@ -1,8 +1,8 @@ % Generated by roxygen2 (4.1.0): do not edit by hand -% Please edit documentation in R/getSupportedRepresentations.R +% Please edit documentation in R/getOperatorsTags.R \name{getSupportedRepresentations} \alias{getSupportedRepresentations} -\title{Returns the representations which a specific operator supports.} +\title{Returns the character vector of tags which describe a specific operator.} \usage{ getSupportedRepresentations(operator) } @@ -15,7 +15,6 @@ Operator object.} Vector of representation types. } \description{ -Operators and representation types are not mandatory compatible. This function -detemines the types an operator can operate on. +Returns the character vector of tags which describe a specific operator. }