From d460b68500a5e13b81542fbb8b5dd48198ffd0a2 Mon Sep 17 00:00:00 2001 From: nojhan Date: Wed, 26 Aug 2020 11:57:11 +0200 Subject: [PATCH] add static branching in minimizing_fitness This allows for EOT with empty constructors, if they use eoM[in|ax]imizingFitness fitnesses. Of course this is faster in that case. --- eo/src/utils/selectors.h | 80 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/eo/src/utils/selectors.h b/eo/src/utils/selectors.h index 9621d15d0..7f0f571ed 100644 --- a/eo/src/utils/selectors.h +++ b/eo/src/utils/selectors.h @@ -41,16 +41,55 @@ #include #include "eoRNG.h" +#include "../eoScalarFitness.h" #include "../eoPop.h" /** @addtogroup Selectors @{ */ +// template +// bool minimizing_fitness() +// { +// EOT eo1; // Assuming people don't do anything fancy in the default constructor! +// EOT eo2; +// +// /* Dear user, when the two line below do not compile you are most +// likely not working with scalar fitness values. In that case we're sorry +// but you cannot use lottery or roulette_wheel selection... +// */ +// +// #ifdef _MSC_VER +// eo1.fitness( EOT::Fitness(0.0) ); +// eo2.fitness( EOT::Fitness(1.0) ); +// #else +// eo1.fitness( typename EOT::Fitness(0.0) ); // tried to cast it to an EOT::Fitness, but for some reason GNU barfs on this +// eo2.fitness( typename EOT::Fitness(1.0) ); +// #endif +// +// return eo2 < eo1; // check whether we have a minimizing fitness +// } + +// Machinery for static type checking. +namespace eo { + template + using void_t = void; + + template + struct is_fit_check : std::false_type{}; + + template + struct is_fit_check > : std::true_type{}; + + template + constexpr auto is_fit = is_fit_check::value; +} + +//! Dynamically check if an EOT is minimizing. template -bool minimizing_fitness() +bool minimizing_fitness_atomic() { - EOT eo1; // Assuming people don't do anything fancy in the default constructor! + EOT eo1; // Assuming EOT allow empty construction. EOT eo2; /* Dear user, when the two line below do not compile you are most @@ -66,9 +105,44 @@ bool minimizing_fitness() eo2.fitness( typename EOT::Fitness(1.0) ); #endif - return eo2 < eo1; // check whether we have a minimizing fitness + // Check whether we have a minimizing fitness. + // Note that EO defaults to maximization. + return eo2 < eo1; } +//! Statically check if an eoScalarFitness is an eoMinimizingFitness. +template +bool minimizing_fitness_eo() +{ + if constexpr (std::is_same< + typename EOT::Fitness, + eoMinimizingFitness/**/ + >::value) { + return true; + } else { + return false; + } +} + +/** Return true if the EOT targets a minimization problem. + * + * NOTE: if EOT has an atomic scalar fitness (e.g. double), it expects EOT to have an empty constructor. + */ +template +bool minimizing_fitness() +{ + // Static bypass for eoScalarFitness classes which embedd a comparator. + if constexpr (eo::is_fit) { + // Static case. + return minimizing_fitness_eo(); + } else { + // Dynamic case, expecting empty constructors. + return minimizing_fitness_atomic(); + } +} + + + inline double scale_fitness(const std::pair& _minmax, double _value) { if (_minmax.first == _minmax.second)