From 4d45970767f0ccb6a0773b14f2f1c29fe15ba317 Mon Sep 17 00:00:00 2001 From: nojhan Date: Tue, 8 Nov 2011 17:55:01 +0100 Subject: [PATCH] refactored vectors repairers that are using a function in a more generic way, added a binary function wrapper for vectors repairers, with the modulus function as an example --- edo/src/edo | 1 + edo/src/edoRepairerApply.h | 98 ++++++++++++++++++++++++++++++++++ edo/src/edoRepairerModulo.h | 47 ++++++++++++++++ edo/src/edoRepairerRound.h | 28 ++++------ edo/test/CMakeLists.txt | 1 + edo/test/t-repairer-modulo.cpp | 55 +++++++++++++++++++ 6 files changed, 213 insertions(+), 17 deletions(-) create mode 100644 edo/src/edoRepairerApply.h create mode 100644 edo/src/edoRepairerModulo.h create mode 100644 edo/test/t-repairer-modulo.cpp diff --git a/edo/src/edo b/edo/src/edo index 69f13f116..c03acd35d 100644 --- a/edo/src/edo +++ b/edo/src/edo @@ -59,6 +59,7 @@ Authors: #include "edoRepairer.h" #include "edoRepairerDispatcher.h" #include "edoRepairerRound.h" +#include "edoRepairerModulo.h" #include "edoBounder.h" #include "edoBounderNo.h" #include "edoBounderBound.h" diff --git a/edo/src/edoRepairerApply.h b/edo/src/edoRepairerApply.h new file mode 100644 index 000000000..fbadacdad --- /dev/null +++ b/edo/src/edoRepairerApply.h @@ -0,0 +1,98 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2011 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoRepairerApply_h +#define _edoRepairerApply_h + +#include + +#include "edoRepairer.h" + + +template < typename EOT, typename F = typename EOT::AtomType(typename EOT::AtomType) > +class edoRepairerApply : public edoRepairer +{ +public: + edoRepairerApply( F function ) : _function(function) {} + +protected: + F * _function; +}; + + +/** Apply an arbitrary unary function as a repairer on each item of the solution + * + * By default, the signature of the expected function is "EOT::AtomType(EOT::AtomType)" + * + * @ingroup Repairers + */ +template < typename EOT, typename F = typename EOT::AtomType(typename EOT::AtomType)> +class edoRepairerApplyUnary : public edoRepairerApply +{ +public: + edoRepairerApplyUnary( F function ) : edoRepairerApply(function) {} + + virtual void operator()( EOT& sol ) + { + std::transform( sol.begin(), sol.end(), sol.begin(), *(this->_function) ); + } +}; + + +/** Apply an arbitrary binary function as a repairer on each item of the solution, + * the second argument of the function being fixed and given at instanciation. + * + * @see edoRepairerApplyUnary + * + * @ingroup Repairers + */ +template < typename EOT, typename F = typename EOT::AtomType(typename EOT::AtomType, typename EOT::AtomType)> +class edoRepairerApplyBinary : public edoRepairerApply +{ +public: + typedef typename EOT::AtomType ArgType; + + edoRepairerApplyBinary( + F function, + ArgType arg + ) : edoRepairerApply(function), _arg(arg) {} + + virtual void operator()( EOT& sol ) + { + // call the binary function on each item + // TODO find a way to use std::transform here? Or would it be too bloated? + for(typename EOT::iterator it = sol.begin(); it != sol.end(); ++it ) { + *it = (*(this->_function))( *it, _arg ); + } + } + +protected: + ArgType _arg; +}; + + +#endif // !_edoRepairerApply_h + diff --git a/edo/src/edoRepairerModulo.h b/edo/src/edoRepairerModulo.h new file mode 100644 index 000000000..213673334 --- /dev/null +++ b/edo/src/edoRepairerModulo.h @@ -0,0 +1,47 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2011 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#ifndef _edoRepairerModulo_h +#define _edoRepairerModulo_h + +#include + +#include "edoRepairerApply.h" + +/** + * + * @ingroup Repairers + */ +template < typename EOT > +class edoRepairerModulo: public edoRepairerApplyBinary +{ +public: + edoRepairerModulo( double denominator ) : edoRepairerApplyBinary( std::fmod, denominator ) {} +}; + + +#endif // !_edoRepairerModulo_h + diff --git a/edo/src/edoRepairerRound.h b/edo/src/edoRepairerRound.h index 032169424..21dd1caec 100644 --- a/edo/src/edoRepairerRound.h +++ b/edo/src/edoRepairerRound.h @@ -30,38 +30,32 @@ Authors: #include -#include "edoRepairer.h" +#include "edoRepairerApply.h" -/** +/** A repairer that calls "floor" on each items of a solution + * + * Just a proxy to "edoRepairerApplyUnary rep( std::floor);" * * @ingroup Repairers */ template < typename EOT > -class edoRepairerFloor : public edoRepairer +class edoRepairerFloor : public edoRepairerApplyUnary { public: - virtual void operator()( EOT& sol ) - { - for( unsigned int i=0; i < sol.size(); ++i ) { - sol[i] = floor( sol[i] ); - } - } + edoRepairerFloor() : edoRepairerApplyUnary( std::floor ) {} }; -/** +/** A repairer that calls "ceil" on each items of a solution + * + * @see edoRepairerFloor * * @ingroup Repairers */ template < typename EOT > -class edoRepairerCeil : public edoRepairer +class edoRepairerCeil : public edoRepairerApplyUnary { public: - virtual void operator()( EOT& sol ) - { - for( unsigned int i=0; i < sol.size(); ++i ) { - sol[i] = ceil( sol[i] ); - } - } + edoRepairerCeil() : edoRepairerApplyUnary( std::ceil ) {} }; diff --git a/edo/test/CMakeLists.txt b/edo/test/CMakeLists.txt index acdabc7b7..61fdd68f1 100644 --- a/edo/test/CMakeLists.txt +++ b/edo/test/CMakeLists.txt @@ -39,6 +39,7 @@ SET(SOURCES t-uniform t-continue t-dispatcher-round + t-repairer-modulo ) FOREACH(current ${SOURCES}) diff --git a/edo/test/t-repairer-modulo.cpp b/edo/test/t-repairer-modulo.cpp new file mode 100644 index 000000000..7a495f318 --- /dev/null +++ b/edo/test/t-repairer-modulo.cpp @@ -0,0 +1,55 @@ +/* +The Evolving Distribution Objects framework (EDO) is a template-based, +ANSI-C++ evolutionary computation library which helps you to write your +own estimation of distribution algorithms. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Copyright (C) 2010 Thales group +*/ +/* +Authors: + Johann Dréo +*/ + +#define _USE_MATH_DEFINES +#include + +#include +#include +#include + +typedef eoReal< eoMinimizingFitness > EOT; + +int main(void) +{ + EOT sol; + sol.push_back( M_PI * 1 ); + sol.push_back( M_PI * 2 ); + sol.push_back( M_PI * 3 ); + sol.push_back( M_PI * 4 ); + sol.push_back( M_PI * 4 + M_PI / 2 ); + sol.push_back( M_PI * 5 + M_PI / 2 ); + // we expect {pi,0,pi,0,pi/2,pi+pi/2} + std::cout << "expect: INVALID 4 3.14159 0 3.14159 0 1.5708 4.71239" << std::endl; + + edoRepairer* repare = new edoRepairerModulo( 2 * M_PI ); // modulo 2pi + + (*repare)(sol); + + std::cout << sol << std::endl; + + return 0; +}