From 150333ef7c47bfccb65507db4c959171929043c7 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 30 Apr 2013 15:56:24 +0200 Subject: [PATCH 01/21] bugfix: include nessary headers for eoRealBounds --- eo/src/utils/eoRealBounds.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eo/src/utils/eoRealBounds.h b/eo/src/utils/eoRealBounds.h index a41646d47..9d046be1a 100644 --- a/eo/src/utils/eoRealBounds.h +++ b/eo/src/utils/eoRealBounds.h @@ -27,9 +27,12 @@ #ifndef _eoRealBounds_h #define _eoRealBounds_h +#include #include #include // std::exceptions! + #include +#include "eoLogger.h" /** \defgroup Real Vector of reals From 6e56f634c37af521e9c7f215204a3a2e01bc239b Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 30 Apr 2013 15:56:54 +0200 Subject: [PATCH 02/21] use a sub-directory in the zip archive --- archive_current.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/archive_current.sh b/archive_current.sh index d43952087..3ba2d2bc2 100755 --- a/archive_current.sh +++ b/archive_current.sh @@ -1,3 +1,5 @@ today=`date --iso-8601` -git archive --format zip master > paradisEO-${today}.zip +name=paradiseo_$today +git archive --prefix=$name/ --format zip master > $name.zip +echo $name.zip From defb8382bf00a7502f1e427f4099467a25681d24 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 30 Apr 2013 16:05:29 +0200 Subject: [PATCH 03/21] Explicit iterator instead of auto, for old C++ compat --- eo/src/serial/Utils.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eo/src/serial/Utils.h b/eo/src/serial/Utils.h index b6ea360b3..5acc558ba 100644 --- a/eo/src/serial/Utils.h +++ b/eo/src/serial/Utils.h @@ -155,7 +155,7 @@ namespace eoserial inline void unpackBasePushBack( const Entity* obj, T& container ) { const Array* arr = static_cast( obj ); - for( auto it = arr->begin(), end = arr->end(); + for( Array::const_iterator it = arr->begin(), end = arr->end(); it != end; ++it ) { @@ -190,7 +190,7 @@ namespace eoserial inline void unpackBase( const Entity* entity, std::map & m ) { const Object* obj = static_cast< const Object* >( entity ); - for( auto it = obj->begin(), end = obj->end(); + for( Object::const_iterator it = obj->begin(), end = obj->end(); it != end; ++it ) { @@ -298,7 +298,7 @@ namespace eoserial inline Entity* packIterable( const T& container ) { Array* arr = new Array; - for( auto it = container.begin(), end = container.end(); + for( Array::const_iterator it = container.begin(), end = container.end(); it != end; ++it ) { @@ -332,7 +332,7 @@ namespace eoserial inline Entity* pack( const std::map& map ) { Object* obj = new Object; - for( auto it = map.begin(), end = map.end(); + for( Object::const_iterator it = map.begin(), end = map.end(); it != end; ++it ) { From bc544cc4a4bafaa06bb02b9e700519ab2731dfb7 Mon Sep 17 00:00:00 2001 From: nojhan Date: Sat, 25 May 2013 17:21:08 +0200 Subject: [PATCH 04/21] buildfix: do not always build release Remove a test that was building Release if DEBUG was not set. The correct way to specify build is to use CMAKE_BUILD_TYPE. --- cmake/Config.cmake | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmake/Config.cmake b/cmake/Config.cmake index c0576397f..55e1b7c41 100644 --- a/cmake/Config.cmake +++ b/cmake/Config.cmake @@ -31,12 +31,6 @@ endif() ### 0) Define general CXX flags for DEBUG and RELEASE ###################################################################################### -if(DEBUG) - set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE) -else(DEBUG) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) -endif(DEBUG) - add_definitions(-DDEPRECATED_MESSAGES) set(CMAKE_CXX_FLAGS_DEBUG "-Wunknown-pragmas -O0 -g -Wall -Wextra -ansi -pedantic" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "-Wunknown-pragmas -O2" CACHE STRING "" FORCE) From 97e1da3e4a1fa32e6ec81143be0009ad30278de1 Mon Sep 17 00:00:00 2001 From: quemy Date: Fri, 31 May 2013 00:10:47 +0200 Subject: [PATCH 05/21] Fix build for SMP --- cmake/Config.cmake | 1 + smp/src/island.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/Config.cmake b/cmake/Config.cmake index 55e1b7c41..02593bac3 100644 --- a/cmake/Config.cmake +++ b/cmake/Config.cmake @@ -36,6 +36,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "-Wunknown-pragmas -O0 -g -Wall -Wextra -ansi -pedant set(CMAKE_CXX_FLAGS_RELEASE "-Wunknown-pragmas -O2" CACHE STRING "" FORCE) if(SMP) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -pthread" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -pthread" CACHE STRING "" FORCE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -pthread" CACHE STRING "" FORCE) add_definitions(-D_GLIBCXX_USE_NANOSLEEP) diff --git a/smp/src/island.h b/smp/src/island.h index 9e8e30edd..752b671ef 100644 --- a/smp/src/island.h +++ b/smp/src/island.h @@ -132,7 +132,7 @@ public: */ virtual void receive(void); - AIsland clone() const; + //AIsland clone() const; protected: From effaa56cfd1de9a799a38d54e6b6b22af4f5bbbc Mon Sep 17 00:00:00 2001 From: liefooga Date: Fri, 31 May 2013 16:13:45 +0200 Subject: [PATCH 06/21] special two-objective case of dominance depth ranking in O(n log n) --- .../moeoDominanceDepthFitnessAssignment.h | 350 +++++++++++------- 1 file changed, 209 insertions(+), 141 deletions(-) diff --git a/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h b/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h index 345048c2c..b07b6b7a1 100644 --- a/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h +++ b/moeo/src/fitness/moeoDominanceDepthFitnessAssignment.h @@ -1,38 +1,38 @@ /* -* -* Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2008 -* (C) OPAC Team, LIFL, 2002-2008 -* -* Arnaud Liefooghe -* -* This software is governed by the CeCILL license under French law and -* abiding by the rules of distribution of free software. You can use, -* modify and/ or redistribute the software under the terms of the CeCILL -* license as circulated by CEA, CNRS and INRIA at the following URL -* "http://www.cecill.info". -* -* As a counterpart to the access to the source code and rights to copy, -* modify and redistribute granted by the license, users are provided only -* with a limited warranty and the software's author, the holder of the -* economic rights, and the successive licensors have only limited liability. -* -* In this respect, the user's attention is drawn to the risks associated -* with loading, using, modifying and/or developing or reproducing the -* software by the user in light of its specific status of free software, -* that may mean that it is complicated to manipulate, and that also -* therefore means that it is reserved for developers and experienced -* professionals having in-depth computer knowledge. Users are therefore -* encouraged to load and test the software's suitability as regards their -* requirements in conditions enabling the security of their systems and/or -* data to be ensured and, more generally, to use and operate it in the -* same conditions as regards security. -* The fact that you are presently reading this means that you have had -* knowledge of the CeCILL license and that you accept its terms. -* -* ParadisEO WebSite : http://paradiseo.gforge.inria.fr -* Contact: paradiseo-help@lists.gforge.inria.fr -* -*/ + * + * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2008 + * (C) OPAC Team, LIFL, 2002-2008 + * + * Arnaud Liefooghe + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + * ParadisEO WebSite : http://paradiseo.gforge.inria.fr + * Contact: paradiseo-help@lists.gforge.inria.fr + * + */ //----------------------------------------------------------------------------- #ifndef MOEODOMINANCEDEPTHFITNESSASSIGNMENT_H_ @@ -44,7 +44,7 @@ #include #include #include - +#include /** * Fitness assignment sheme based on Pareto-dominance count proposed in: @@ -55,69 +55,69 @@ */ template < class MOEOT > class moeoDominanceDepthFitnessAssignment : public moeoDominanceBasedFitnessAssignment < MOEOT > - { - public: - +{ +public: + /** the objective vector type of the solutions */ typedef typename MOEOT::ObjectiveVector ObjectiveVector; - - + + /** * Default ctor */ - moeoDominanceDepthFitnessAssignment() : comparator(paretoComparator) + moeoDominanceDepthFitnessAssignment(bool _rm_equiv_flag_in_2D = false) : comparator(paretoComparator), rm_equiv_flag_in_2D(_rm_equiv_flag_in_2D) {} - - + + /** * Ctor where you can choose your own way to compare objective vectors * @param _comparator the functor used to compare objective vectors */ - moeoDominanceDepthFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator) : comparator(_comparator) + moeoDominanceDepthFitnessAssignment(moeoObjectiveVectorComparator < ObjectiveVector > & _comparator, bool _rm_equiv_flag_in_2D = true) : comparator(_comparator), rm_equiv_flag_in_2D(_rm_equiv_flag_in_2D) {} - - + + /** * Sets the fitness values for every solution contained in the population _pop * @param _pop the population */ void operator()(eoPop < MOEOT > & _pop) { - // number of objectives for the problem under consideration - unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives(); - if (nObjectives == 1) + // number of objectives for the problem under consideration + unsigned int nObjectives = MOEOT::ObjectiveVector::nObjectives(); + if (nObjectives == 1) { - // one objective - oneObjective(_pop); + // one objective + oneObjective(_pop); } - else if (nObjectives == 2) + else if (nObjectives == 2) { - // two objectives (the two objectives function is still to implement) - mObjectives(_pop); + // two objectives + twoObjectives(_pop); } - else if (nObjectives > 2) + else if (nObjectives > 2) { - // more than two objectives - mObjectives(_pop); + // more than two objectives + mObjectives(_pop); } - else + else { - // problem with the number of objectives - throw std::runtime_error("Problem with the number of objectives in moeoDominanceDepthFitnessAssignment"); + // problem with the number of objectives + throw std::runtime_error("Problem with the number of objectives in moeoDominanceDepthFitnessAssignment"); } - // a higher fitness is better, so the values need to be inverted - double max = _pop[0].fitness(); - for (unsigned int i=1 ; i<_pop.size() ; i++) + // a higher fitness is better, so the values need to be inverted + double max = _pop[0].fitness(); + for (unsigned int i=1 ; i<_pop.size() ; i++) { - max = std::max(max, _pop[i].fitness()); + max = std::max(max, _pop[i].fitness()); } - for (unsigned int i=0 ; i<_pop.size() ; i++) + for (unsigned int i=0 ; i<_pop.size() ; i++) { - _pop[i].fitness(max - _pop[i].fitness()); + _pop[i].fitness(max - _pop[i].fitness()); } } - - + + /** * Updates the fitness values of the whole population _pop by taking the deletion of the objective vector _objVec into account. * @param _pop the population @@ -125,141 +125,209 @@ class moeoDominanceDepthFitnessAssignment : public moeoDominanceBasedFitnessAssi */ void updateByDeleting(eoPop < MOEOT > & _pop, ObjectiveVector & _objVec) { - for (unsigned int i=0; i<_pop.size(); i++) + for (unsigned int i=0; i<_pop.size(); i++) { - // if _pop[i] is dominated by _objVec - if ( comparator(_pop[i].objectiveVector(), _objVec) ) + // if _pop[i] is dominated by _objVec + if ( comparator(_pop[i].objectiveVector(), _objVec) ) { - _pop[i].fitness(_pop[i].fitness()+1); + _pop[i].fitness(_pop[i].fitness()+1); } } } - - - private: - + + +private: + /** Functor to compare two objective vectors */ moeoObjectiveVectorComparator < ObjectiveVector > & comparator; /** Functor to compare two objective vectors according to Pareto dominance relation */ moeoParetoObjectiveVectorComparator < ObjectiveVector > paretoComparator; + /** flag to remove equivament solutions */ + bool rm_equiv_flag_in_2D; /** Functor allowing to compare two solutions according to their first objective value, then their second, and so on. */ - class ObjectiveComparator : public moeoComparator < MOEOT > - { - public: + class ObjectiveComparator : public moeoComparator < MOEOT > + { + public: /** - * Returns true if _moeo1 < _moeo2 on the first objective, then on the second, and so on + * Returns true if _moeo1 > _moeo2 on the first objective, then on the second, and so on * @param _moeo1 the first solution * @param _moeo2 the second solution */ bool operator()(const MOEOT & _moeo1, const MOEOT & _moeo2) { - return cmp(_moeo1.objectiveVector(), _moeo2.objectiveVector()); + return cmp(_moeo2.objectiveVector(), _moeo1.objectiveVector()); } - private: + private: /** the corresponding comparator for objective vectors */ moeoObjectiveObjectiveVectorComparator < ObjectiveVector > cmp; - } + } objComparator; - - + + /** * Sets the fitness values for mono-objective problems * @param _pop the population */ void oneObjective (eoPop < MOEOT > & _pop) { - // sorts the population in the ascending order - std::sort(_pop.begin(), _pop.end(), objComparator); - // assign fitness values - unsigned int rank = 1; - _pop[_pop.size()-1].fitness(rank); - for (int i=_pop.size()-2; i>=0; i--) + // sorts the population in the ascending order + std::sort(_pop.begin(), _pop.end(), objComparator); + // assign fitness values + unsigned int rank = 1; + _pop[0].fitness(rank); + for (unsigned int i=1; i<_pop.size(); i++) { - if (_pop[i].objectiveVector() != _pop[i+1].objectiveVector()) + if (_pop[i].objectiveVector() != _pop[i-1].objectiveVector()) { - rank++; + rank++; } - _pop[i].fitness(rank); + _pop[i].fitness(rank); } } - - + + /** * Sets the fitness values for bi-objective problems with a complexity of O(n log n), where n stands for the population size * @param _pop the population */ void twoObjectives (eoPop < MOEOT > & _pop) { - //... TO DO ! + double value_obj1; + unsigned int front; + unsigned int last_front = 0; + bool equiv_flag; + + // sort pointers to pop's individuals with respect to the first objective (0) in the reverse order + std::vector sortedptrpop; + sortedptrpop.resize(_pop.size()); + for(unsigned int i=0; i<_pop.size(); i++) + { + sortedptrpop[i] = & (_pop[i]); + } + moeoPtrComparator cmp(objComparator); + std::sort(sortedptrpop.begin(), sortedptrpop.end(), cmp); + + // compute an upper bound on the second objective (1) + double max_obj1 = std::numeric_limits::min(); + for(unsigned int i=0; i<_pop.size(); i++) + { + max_obj1 = std::max(max_obj1, _pop[i].objectiveVector()[1]); + } + max_obj1 += 1.0; + + // initialize a vector with the max_obj1 value everywhere + std::vector d(_pop.size(), max_obj1); + // initialize fronts + std::vector > fronts(_pop.size()); + // compute rank for each individual + for(unsigned int i=0; i0) + { + if ( (rm_equiv_flag_in_2D) && (sortedptrpop[i]->objectiveVector() == sortedptrpop[i-1]->objectiveVector()) ) + { + equiv_flag = true; + fronts.back().push_back(i); + } + } + if (!equiv_flag) + { + // the value of the second objective for the current solutions + value_obj1 = sortedptrpop[i]->objectiveVector()[1]; + // if we maximize, take the opposite value + if (MOEOT::ObjectiveVector::maximizing(1)) + value_obj1 = max_obj1 - value_obj1; + // perform binary search (log n) + std::vector::iterator it = std::upper_bound(d.begin(), d.begin() + last_front, value_obj1); + // retrieve the corresponding front + front = (unsigned int)(it - d.begin()); + if (front == last_front) + last_front++; + // update + *it = value_obj1; + // add the solution to the corresponding front + fronts[front].push_back(i); + } + } + // assign the fitness value (rank) to each individual + for (unsigned int i=0; ifitness(i+1); + } + } } - - + + /** * Sets the fitness values for problems with more than two objectives with a complexity of O(n² log n), where n stands for the population size * @param _pop the population */ void mObjectives (eoPop < MOEOT > & _pop) { - // S[i] = indexes of the individuals dominated by _pop[i] - std::vector < std::vector > S(_pop.size()); - // n[i] = number of individuals that dominate the individual _pop[i] - std::vector < unsigned int > n(_pop.size(), 0); - // fronts: F[i] = indexes of the individuals contained in the ith front - std::vector < std::vector > F(_pop.size()+2); - // used to store the number of the first front - F[1].reserve(_pop.size()); - for (unsigned int p=0; p<_pop.size(); p++) + // S[i] = indexes of the individuals dominated by _pop[i] + std::vector < std::vector > S(_pop.size()); + // n[i] = number of individuals that dominate the individual _pop[i] + std::vector < unsigned int > n(_pop.size(), 0); + // fronts: F[i] = indexes of the individuals contained in the ith front + std::vector < std::vector > F(_pop.size()+2); + // used to store the number of the first front + F[1].reserve(_pop.size()); + for (unsigned int p=0; p<_pop.size(); p++) { - for (unsigned int q=0; q<_pop.size(); q++) + for (unsigned int q=0; q<_pop.size(); q++) { - // if q is dominated by p - if ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) ) + // if q is dominated by p + if ( comparator(_pop[q].objectiveVector(), _pop[p].objectiveVector()) ) { - // add q to the set of solutions dominated by p - S[p].push_back(q); + // add q to the set of solutions dominated by p + S[p].push_back(q); } - // if p is dominated by q - else if ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) ) + // if p is dominated by q + else if ( comparator(_pop[p].objectiveVector(), _pop[q].objectiveVector()) ) { - // increment the domination counter of p - n[p]++; + // increment the domination counter of p + n[p]++; } } - // if no individual dominates p - if (n[p] == 0) + // if no individual dominates p + if (n[p] == 0) { - // p belongs to the first front - _pop[p].fitness(1); - F[1].push_back(p); + // p belongs to the first front + _pop[p].fitness(1); + F[1].push_back(p); } } - // front counter - unsigned int counter=1; - unsigned int p,q; - while (! F[counter].empty()) + // front counter + unsigned int counter=1; + unsigned int p,q; + while (! F[counter].empty()) { - // used to store the number of the next front - F[counter+1].reserve(_pop.size()); - for (unsigned int i=0; i Date: Thu, 6 Jun 2013 11:43:34 +0200 Subject: [PATCH 07/21] bugfix: do not allow null interval in hypervolume diff metric --- eo/src/utils/eoRealBounds.h | 2 +- .../metric/moeoHyperVolumeDifferenceMetric.h | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/eo/src/utils/eoRealBounds.h b/eo/src/utils/eoRealBounds.h index 9d046be1a..8d55d793a 100644 --- a/eo/src/utils/eoRealBounds.h +++ b/eo/src/utils/eoRealBounds.h @@ -234,7 +234,7 @@ public : assert( repRange >= 0 ); #ifndef NDEBUG if( repRange == 0 ) { - eo::log << eo::warnings << "Null range in eoRealBounds (min=" << _min << ", max=" << _max << ")" << std::endl; + eo::log << eo::warnings << "Warning: null range in eoRealBounds (min=" << _min << ", max=" << _max << ")" << std::endl; } #endif } diff --git a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h index 906923b98..533d29296 100644 --- a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h +++ b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h @@ -163,12 +163,26 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < min = std::min(min, _set2[j][i]); max = std::max(max, _set2[j][i]); } - bounds[i] = eoRealInterval(min, max); + if( min == max ) { + bounds[i] = eoRealInterval(min-tiny(), max+tiny()); + } else { + bounds[i] = eoRealInterval(min, max); + } } } } - private: + protected: + + /** + * Returns a very small value that can be used to avoid extreme cases (where the min bound == the max bound) + */ + static double tiny() + { + return 1e-6; + } + + private: /*boolean indicates if data must be normalized or not*/ bool normalize; From 9aec7780dcf52033a4101e16516403bc3730d2b3 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 11:21:02 +0200 Subject: [PATCH 08/21] Add moeoScalarObjectiveVector, a generic OV with templatized atomic type Because sometime, we may want to use something else than a double (for example an eoDualFitness, a complex or whatever). --- moeo/src/core/moeoScalarObjectiveVector.h | 179 ++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 moeo/src/core/moeoScalarObjectiveVector.h diff --git a/moeo/src/core/moeoScalarObjectiveVector.h b/moeo/src/core/moeoScalarObjectiveVector.h new file mode 100644 index 000000000..0f33812c3 --- /dev/null +++ b/moeo/src/core/moeoScalarObjectiveVector.h @@ -0,0 +1,179 @@ +/* + +(c) 2010 Thales group + + 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; version 2 + of the License. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Contact: http://eodev.sourceforge.net + +Authors: + Johann Dréo + +*/ + + +#ifndef MOEOSCALAROBJECTIVEVECTOR_H_ +#define MOEOSCALAROBJECTIVEVECTOR_H_ + +#include +#include +#include +#include +#include + +/** + * This class allows to represent a solution in the objective space (phenotypic representation) by a std::vector of typed values, + * i.e. that an objective value is represented using a T, and this for any objective. + */ +template < class ObjectiveVectorTraits, class T > +class moeoScalarObjectiveVector : public moeoObjectiveVector < ObjectiveVectorTraits, T > +{ + public: + + using moeoObjectiveVector < ObjectiveVectorTraits, T >::size; + using moeoObjectiveVector < ObjectiveVectorTraits, T >::operator[]; + + /** + * Ctor + */ + moeoScalarObjectiveVector(T _value = 0.0) : moeoObjectiveVector < ObjectiveVectorTraits, T > (_value) + {} + + + /** + * Ctor from a vector of Ts + * @param _v the std::vector < T > + */ + moeoScalarObjectiveVector(std::vector < T > & _v) : moeoObjectiveVector < ObjectiveVectorTraits, T > (_v) + {} + + + /** + * Returns true if the current objective vector dominates _other according to the Pareto dominance relation + * (but it's better to use a moeoObjectiveVectorComparator object to compare solutions) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool dominates(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + moeoParetoObjectiveVectorComparator < moeoScalarObjectiveVector > comparator; + return comparator(_other, *this); + } + + + /** + * Returns true if the current objective vector is equal to _other (according to a tolerance value) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool operator==(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + for (unsigned int i=0; i < size(); i++) + { + if ( fabs(operator[](i) - _other[i]) > ObjectiveVectorTraits::tolerance() ) + { + return false; + } + } + return true; + } + + + /** + * Returns true if the current objective vector is different than _other (according to a tolerance value) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool operator!=(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + return ! operator==(_other); + } + + + /** + * Returns true if the current objective vector is smaller than _other on the first objective, then on the second, and so on + * (can be usefull for sorting/printing) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool operator<(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + moeoObjectiveObjectiveVectorComparator < moeoScalarObjectiveVector < ObjectiveVectorTraits, T > > cmp; + return cmp(*this, _other); + } + + + /** + * Returns true if the current objective vector is greater than _other on the first objective, then on the second, and so on + * (can be usefull for sorting/printing) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool operator>(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + return _other < *this; + } + + + /** + * Returns true if the current objective vector is smaller than or equal to _other on the first objective, then on the second, and so on + * (can be usefull for sorting/printing) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool operator<=(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + return operator==(_other) || operator<(_other); + } + + + /** + * Returns true if the current objective vector is greater than or equal to _other on the first objective, then on the second, and so on + * (can be usefull for sorting/printing) + * @param _other the other moeoScalarObjectiveVector object to compare with + */ + bool operator>=(const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _other) const + { + return operator==(_other) || operator>(_other); + } + +}; + + +/** + * Output for a moeoScalarObjectiveVector object + * @param _os output stream + * @param _objectiveVector the objective vector to write + */ +template < class ObjectiveVectorTraits > +std::ostream & operator<<(std::ostream & _os, const moeoScalarObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +{ + for (unsigned int i=0; i<_objectiveVector.size()-1; i++) + _os << _objectiveVector[i] << " "; + _os << _objectiveVector[_objectiveVector.size()-1]; + return _os; +} + +/** + * Input for a moeoScalarObjectiveVector object + * @param _is input stream + * @param _objectiveVector the objective vector to read + */ +template < class ObjectiveVectorTraits > +std::istream & operator>>(std::istream & _is, moeoScalarObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +{ + _objectiveVector = moeoScalarObjectiveVector < ObjectiveVectorTraits > (); + for (unsigned int i=0; i<_objectiveVector.size(); i++) + { + _is >> _objectiveVector[i]; + } + return _is; +} + +#endif /*MOEOSCALAROBJECTIVEVECTOR_H_*/ From 54e181d4603274f8b61e11c4d51c9183993504b2 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 11:22:26 +0200 Subject: [PATCH 09/21] Use generic objective vector atomic type in HV continuator One should not use specific OV types in continuators, but get it from ObjectiveVector::Type instead. --- moeo/src/continue/moeoHypContinue.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/moeo/src/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index 4e656bf69..9ecc5424e 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -56,15 +56,16 @@ class moeoHypContinue: public eoContinue public: typedef typename MOEOT::ObjectiveVector ObjectiveVector; + typedef typename ObjectiveVector::Type AtomType; /// Ctor - moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1) + moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, AtomType _rho=1.1) : eoContinue(), arch(_archive), metric(_normalize,_rho) { vectorToParetoSet(_OptimVec); } - moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL) + moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL) : eoContinue (), arch(_archive), metric(_normalize,_ref_point) { vectorToParetoSet(_OptimVec); @@ -79,7 +80,7 @@ public: bestCurrentParetoSet.push_back(arch[i].objectiveVector()); } - double hypervolume= metric(bestCurrentParetoSet,OptimSet ); + AtomType hypervolume= metric(bestCurrentParetoSet,OptimSet ); if (hypervolume==0) { eo::log << eo::logging << "STOP in moeoHypContinue: Best ParetoSet has been reached " @@ -90,7 +91,7 @@ public: } /** Translate a vector given as param to the ParetoSet that should be reached. */ - void vectorToParetoSet(const std::vector & _OptimVec) + void vectorToParetoSet(const std::vector & _OptimVec) { unsigned dim = (unsigned)(_OptimVec.size()/ObjectiveVector::Traits::nObjectives()); OptimSet.resize(dim); From 3adff8518f18ed2453e2d24aa08114ccba7b26ed Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 11:26:49 +0200 Subject: [PATCH 10/21] Add moeoDualRealObjectiveVector, to implement OV with feasability --- moeo/src/core/moeoDualRealObjectiveVector.h | 114 ++++++++++++++++++++ moeo/src/moeo | 2 + 2 files changed, 116 insertions(+) create mode 100644 moeo/src/core/moeoDualRealObjectiveVector.h diff --git a/moeo/src/core/moeoDualRealObjectiveVector.h b/moeo/src/core/moeoDualRealObjectiveVector.h new file mode 100644 index 000000000..9be12d8f7 --- /dev/null +++ b/moeo/src/core/moeoDualRealObjectiveVector.h @@ -0,0 +1,114 @@ +/* + +(c) 2010 Thales group + + 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; version 2 + of the License. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Contact: http://eodev.sourceforge.net + +Authors: + Johann Dréo + +*/ + +#ifndef _DUALREALOBJECTIVEVECTOR_H_ +#define _DUALREALOBJECTIVEVECTOR_H_ + +#include +#include + +#include + +#include +#include +#include + +template < class ObjectiveVectorTraits > +class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector +{ + protected: + bool _is_feasible; + + public: + + moeoDualRealObjectiveVector(double value=0.0) : moeoScalarObjectiveVector(value, false) {} + + bool is_feasible() const + { +#ifndef NDEBUG + // if the feasibility is correctly assigned, + // every scalar's feasibility should be equal to the objective vector + for( typename moeoDualRealObjectiveVector::const_iterator it = this->begin(), end = this->end(); it != end; ++it ) { + assert( it->is_feasible() == _is_feasible ); + } +#endif + return _is_feasible; + } + + //! One should ensure that feasabilities of scalars are all the same + void is_feasible( bool value ) + { +#ifndef NDEBUG + for( typename moeoDualRealObjectiveVector::const_iterator it = this->begin(), end = this->end(); it != end; ++it ) { + assert( it->is_feasible() == value ); + } +#endif + _is_feasible = value; + } + + bool dominates(const moeoRealObjectiveVector < ObjectiveVectorTraits > & other) const + { + // am I better than the other ? + + // if I'm feasible and the other is not + if( this->is_feasible() && !other.is_feasible() ) { + // no, the other has a better objective + return true; + + } else if( !this->is_feasible() && other.is_feasible() ) { + // yes, a feasible objective is always better than an unfeasible one + return false; + + } else { + // the two objective are of the same type + // lets rely on the comparator + moeoParetoObjectiveVectorComparator< moeoDualRealObjectiveVector > comparator; + return comparator(other, *this); + } + } + + //! Use when maximizing an + bool operator<(const moeoDualRealObjectiveVector < ObjectiveVectorTraits > & other) const + { + // am I better than the other ? + + // if I'm feasible and the other is not + if( this->is_feasible() && !other.is_feasible() ) { + // no, the other has a better objective + return true; + + } else if( !this->is_feasible() && other.is_feasible() ) { + // yes, a feasible objective is always better than an unfeasible one + return false; + + } else { + moeoObjectiveObjectiveVectorComparator < moeoDualRealObjectiveVector < ObjectiveVectorTraits > > cmp; + return cmp(*this, other); + } + } +}; + + +#endif /*_DUALREALOBJECTIVEVECTOR_H_*/ diff --git a/moeo/src/moeo b/moeo/src/moeo index 9ac18c050..b2e7b4db1 100644 --- a/moeo/src/moeo +++ b/moeo/src/moeo @@ -88,7 +88,9 @@ #include #include #include +#include #include +#include #include #include From 818425565deb0e2964a6962b95bd55951dda6613 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 11:52:50 +0200 Subject: [PATCH 11/21] Correct templatized types across ObjectiveVector-dependant code --- moeo/src/continue/moeoHypContinue.h | 2 +- moeo/src/core/moeoDualRealObjectiveVector.h | 10 ++++++---- moeo/src/core/moeoScalarObjectiveVector.h | 10 +++++----- .../moeoExpBinaryIndicatorBasedFitnessAssignment.h | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/moeo/src/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index 9ecc5424e..5fd5c47ad 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -59,7 +59,7 @@ public: typedef typename ObjectiveVector::Type AtomType; /// Ctor - moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, AtomType _rho=1.1) + moeoHypContinue( const std::vector & _OptimVec, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1) : eoContinue(), arch(_archive), metric(_normalize,_rho) { vectorToParetoSet(_OptimVec); diff --git a/moeo/src/core/moeoDualRealObjectiveVector.h b/moeo/src/core/moeoDualRealObjectiveVector.h index 9be12d8f7..dbba265c0 100644 --- a/moeo/src/core/moeoDualRealObjectiveVector.h +++ b/moeo/src/core/moeoDualRealObjectiveVector.h @@ -33,17 +33,19 @@ Authors: #include #include -#include +#include -template < class ObjectiveVectorTraits > -class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector +template < class ObjectiveVectorTraits, class T = eoMinimizingDualFitness /* can be an eoMaximizingDualFitness */> +class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector { protected: bool _is_feasible; public: - moeoDualRealObjectiveVector(double value=0.0) : moeoScalarObjectiveVector(value, false) {} + moeoDualRealObjectiveVector(double value=0.0) + : moeoScalarObjectiveVector + ( T(value, false) ) {} bool is_feasible() const { diff --git a/moeo/src/core/moeoScalarObjectiveVector.h b/moeo/src/core/moeoScalarObjectiveVector.h index 0f33812c3..9d1183ad7 100644 --- a/moeo/src/core/moeoScalarObjectiveVector.h +++ b/moeo/src/core/moeoScalarObjectiveVector.h @@ -151,8 +151,8 @@ class moeoScalarObjectiveVector : public moeoObjectiveVector < ObjectiveVectorTr * @param _os output stream * @param _objectiveVector the objective vector to write */ -template < class ObjectiveVectorTraits > -std::ostream & operator<<(std::ostream & _os, const moeoScalarObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +template < class ObjectiveVectorTraits, class T > +std::ostream & operator<<(std::ostream & _os, const moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _objectiveVector) { for (unsigned int i=0; i<_objectiveVector.size()-1; i++) _os << _objectiveVector[i] << " "; @@ -165,10 +165,10 @@ std::ostream & operator<<(std::ostream & _os, const moeoScalarObjectiveVector < * @param _is input stream * @param _objectiveVector the objective vector to read */ -template < class ObjectiveVectorTraits > -std::istream & operator>>(std::istream & _is, moeoScalarObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +template < class ObjectiveVectorTraits, class T > +std::istream & operator>>(std::istream & _is, moeoScalarObjectiveVector < ObjectiveVectorTraits, T > & _objectiveVector) { - _objectiveVector = moeoScalarObjectiveVector < ObjectiveVectorTraits > (); + _objectiveVector = moeoScalarObjectiveVector < ObjectiveVectorTraits, T > (); for (unsigned int i=0; i<_objectiveVector.size(); i++) { _is >> _objectiveVector[i]; diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h index a25382f41..3159c2840 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h @@ -154,7 +154,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB */ void setup(const eoPop < MOEOT > & _pop) { - double min, max; + typename MOEOT::ObjectiveVector::Type min, max; for (unsigned int i=0; i Date: Fri, 7 Jun 2013 12:42:27 +0200 Subject: [PATCH 12/21] Add missing arithmetic operators to eoDualFitness --- eo/src/eoDualFitness.h | 52 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index 674fe075c..7bf88ed47 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -108,12 +108,11 @@ public: * type, if needed. For example, this is possible: * eoDualFitness > fit; * double val = 1.0; - * fit = val; * val = fit; */ - operator BaseType(void) const { return _value; } + operator BaseType(void) const { return _value; } + - inline bool is_feasible() const { return _is_feasible; @@ -143,6 +142,14 @@ public: return *this; } + //! Copy operator from a std::pair + template + eoDualFitness& operator=(const T v) + { + _value = v; + return *this; + } + //! Comparison that separate feasible individuals from unfeasible ones. Feasible are always better /*! * Use less as a default comparison operator @@ -183,6 +190,11 @@ public: public: + /* FIXME it would be better to raise errors (or warnings) if one try to apply arithmetics operators between feasible + * and unfeasible fitnesses. This necessitates to add wrappers for operators that aggregates sets of dual fitnesses + * (like eoStat), both for separating feasibility and for aggregating them. + */ + //! Add a given fitness to the current one template friend @@ -209,6 +221,31 @@ public: return from; } + + //! Add a given fitness to the current one + template + friend + eoDualFitness & operator/=( eoDualFitness & from, const eoDualFitness & that ) + { + from._value /= that._value; + + // true only if the two are feasible, else false + from._is_feasible = from._is_feasible && that._is_feasible; + + return from; + } + + + //! Add a given fitness to the current one + template + friend + eoDualFitness & operator/=( eoDualFitness & from, T that ) + { + from._value /= that; + + return from; + } + // Add this fitness's value to that other, and return a _new_ instance with the result. template eoDualFitness operator+(const eoDualFitness & that) @@ -225,6 +262,15 @@ public: return from -= that; } + + // Add this fitness's value to that other, and return a _new_ instance with the result. + template + eoDualFitness operator/(const eoDualFitness & that) + { + eoDualFitness from( *this ); + return from /= that; + } + //! Print an eoDualFitness instance as a pair of numbers, separated by a space template friend From 9787d4d89c44ac97d100f33b26a578268a9483d4 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 12:43:09 +0200 Subject: [PATCH 13/21] Generic ObjectiveVector types --- moeo/src/continue/moeoHypContinue.h | 2 +- moeo/src/core/moeoDualRealObjectiveVector.h | 36 +++++++++++++++++-- .../metric/moeoHyperVolumeDifferenceMetric.h | 6 ++-- moeo/src/metric/moeoHyperVolumeMetric.h | 2 +- .../metric/moeoVecVsVecEpsilonBinaryMetric.h | 2 +- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/moeo/src/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index 5fd5c47ad..85be8281e 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -80,7 +80,7 @@ public: bestCurrentParetoSet.push_back(arch[i].objectiveVector()); } - AtomType hypervolume= metric(bestCurrentParetoSet,OptimSet ); + double hypervolume= metric(bestCurrentParetoSet,OptimSet ); if (hypervolume==0) { eo::log << eo::logging << "STOP in moeoHypContinue: Best ParetoSet has been reached " diff --git a/moeo/src/core/moeoDualRealObjectiveVector.h b/moeo/src/core/moeoDualRealObjectiveVector.h index dbba265c0..ce66ed329 100644 --- a/moeo/src/core/moeoDualRealObjectiveVector.h +++ b/moeo/src/core/moeoDualRealObjectiveVector.h @@ -43,9 +43,9 @@ class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector - ( T(value, false) ) {} + ( T(value, feasible) ) {} bool is_feasible() const { @@ -113,4 +113,36 @@ class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector +std::ostream & operator<<(std::ostream & _os, const moeoDualRealObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +{ + for (unsigned int i=0; i<_objectiveVector.size()-1; i++) + _os << _objectiveVector[i] << " "; + _os << _objectiveVector[_objectiveVector.size()-1]; + return _os; +} + +/** + * Input for a moeoDualRealObjectiveVector object + * @param _is input stream + * @param _objectiveVector the objective vector to read + */ +template < class ObjectiveVectorTraits > +std::istream & operator>>(std::istream & _is, moeoDualRealObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +{ + _objectiveVector = moeoDualRealObjectiveVector < ObjectiveVectorTraits > (); + for (unsigned int i=0; i<_objectiveVector.size(); i++) + { + _is >> _objectiveVector[i]; + } + return _is; +} + + #endif /*_DUALREALOBJECTIVEVECTOR_H_*/ diff --git a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h index 906923b98..296da1733 100644 --- a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h +++ b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h @@ -56,7 +56,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < * @param _normalize allow to normalize data (default true) * @param _rho coefficient to determine the reference point. */ - moeoHyperVolumeDifferenceMetric(bool _normalize=true, double _rho=1.1): normalize(_normalize), rho(_rho), ref_point(NULL){ + moeoHyperVolumeDifferenceMetric(bool _normalize=true, double _rho=1.1): normalize(_normalize), rho(_rho), ref_point(/*NULL*/){ bounds.resize(ObjectiveVector::Traits::nObjectives()); // initialize bounds in case someone does not want to use them for (unsigned int i=0; i argument1: vector size must be greater than 0"); else{ - double min, max; + typename ObjectiveVector::Type min, max; unsigned int nbObj=ObjectiveVector::Traits::nObjectives(); bounds.resize(nbObj); for (unsigned int i=0; i & _set1, const std::vector < ObjectiveVector > & _set2){ - double min, max; + typename ObjectiveVector::Type min, max; unsigned int nbObj=ObjectiveVector::Traits::nObjectives(); bounds.resize(nbObj); for (unsigned int i=0; i Date: Fri, 7 Jun 2013 17:32:30 +0200 Subject: [PATCH 14/21] More generic eoDualFitness Allow an imitialization on a double only, BUT an assert fails if it is not 0.0 Remove friendship on operators, because there is two differerent templated classes declared later. More operators with base types. --- eo/src/eoDualFitness.h | 94 ++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index 7bf88ed47..f51ebb9a6 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -81,10 +81,23 @@ public: * Unfeasible by default */ eoDualFitness() : - _value(), + _value(0.0), _is_feasible(false) {} + //! Empty initialization + /*! + * Unfeasible by default + */ + template + eoDualFitness( T value ) : + _value(value), + _is_feasible(false) + { + assert( _value == 0 ); + } + + //! Copy constructor eoDualFitness(const eoDualFitness& other) : _value(other._value), @@ -126,8 +139,8 @@ public: //! Copy operator from a std::pair eoDualFitness& operator=(const std::pair& v) { - _value = v.first; - _is_feasible = v.second; + this->_value = v.first; + this->_is_feasible = v.second; return *this; } @@ -142,13 +155,16 @@ public: return *this; } - //! Copy operator from a std::pair + /* + //! Copy operator from a scalar template eoDualFitness& operator=(const T v) { - _value = v; + this->_value = v; + this->_is_feasible = false; return *this; } + */ //! Comparison that separate feasible individuals from unfeasible ones. Feasible are always better /*! @@ -195,55 +211,74 @@ public: * (like eoStat), both for separating feasibility and for aggregating them. */ + // NOTE: we cannot declare this set of operator classes as friend, because there is two differerent templated classes declared later + // (for minimizing and maximizing) + //! Add a given fitness to the current one template - friend - eoDualFitness & operator+=( eoDualFitness & from, const eoDualFitness & that ) + // friend + eoDualFitness & operator+=( /*eoDualFitness & from,*/ const eoDualFitness & that ) { - from._value += that._value; + // from._value += that._value; + this->_value += that._value; // true only if the two are feasible, else false - from._is_feasible = from._is_feasible && that._is_feasible; + // from._is_feasible = from._is_feasible && that._is_feasible; + this->_is_feasible = this->_is_feasible && that._is_feasible; - return from; + return *this; } //! Substract a given fitness to the current one template - friend - eoDualFitness & operator-=( eoDualFitness & from, const eoDualFitness & that ) + eoDualFitness & operator-=( const eoDualFitness & that ) { - from._value -= that._value; + this->_value -= that._value; // true only if the two are feasible, else false - from._is_feasible = from._is_feasible && that._is_feasible; + this->_is_feasible = this->_is_feasible && that._is_feasible; - return from; + return *this; } + //! Add a given fitness to the current one + template + eoDualFitness & operator+=( const T that ) + { + this->_value += that; + return *this; + } + + //! Substract a given fitness to the current one + template + eoDualFitness & operator-=( const T that ) + { + this->_value -= that; + return *this; + } + + //! Add a given fitness to the current one template - friend - eoDualFitness & operator/=( eoDualFitness & from, const eoDualFitness & that ) + eoDualFitness & operator/=( const eoDualFitness & that ) { - from._value /= that._value; + this->_value /= that._value; // true only if the two are feasible, else false - from._is_feasible = from._is_feasible && that._is_feasible; + this->_is_feasible = this->_is_feasible && that._is_feasible; - return from; + return *this; } //! Add a given fitness to the current one template - friend - eoDualFitness & operator/=( eoDualFitness & from, T that ) + eoDualFitness & operator/=( T that ) { - from._value /= that; + this->_value /= that; - return from; + return *this; } // Add this fitness's value to that other, and return a _new_ instance with the result. @@ -273,17 +308,15 @@ public: //! Print an eoDualFitness instance as a pair of numbers, separated by a space template - friend - std::ostream& operator<<(std::ostream& os, const eoDualFitness& f) + std::ostream& operator<<(std::ostream& os) { - os << f._value << " " << f._is_feasible; + os << this->_value << " " << this->_is_feasible; return os; } //! Read an eoDualFitness instance as a pair of numbers, separated by a space template - friend - std::istream& operator>>(std::istream& is, eoDualFitness& f) + std::istream& operator>>(std::istream& is) { F value; is >> value; @@ -291,7 +324,8 @@ public: bool feasible; is >> feasible; - f = std::make_pair( value, feasible ); + this->_value = value; + this->_is_feasible = feasible; return is; } }; From 89374247a4c3c82674fadfdfa970dac21b8656f9 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 17:34:59 +0200 Subject: [PATCH 15/21] Add constructors with explicit fitness assignement to IBEA --- moeo/src/algo/moeoIBEA.h | 59 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/moeo/src/algo/moeoIBEA.h b/moeo/src/algo/moeoIBEA.h index b0c1d0207..928e8f5a0 100644 --- a/moeo/src/algo/moeoIBEA.h +++ b/moeo/src/algo/moeoIBEA.h @@ -80,7 +80,20 @@ public: * @param _kappa scaling factor kappa */ moeoIBEA (unsigned int _maxGen, eoEvalFunc < MOEOT > & _eval, eoQuadOp < MOEOT > & _crossover, double _pCross, eoMonOp < MOEOT > & _mutation, double _pMut, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) : - defaultGenContinuator(_maxGen), continuator(defaultGenContinuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), select (2), selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(_crossover, _pCross, _mutation, _pMut), genBreed (select, defaultSGAGenOp), breed (genBreed), fitnessAssignment(_metric, _kappa), replace (fitnessAssignment, diversityAssignment) + defaultGenContinuator(_maxGen), + continuator(defaultGenContinuator), + eval(_eval), + defaultPopEval(_eval), + popEval(defaultPopEval), + select (2), + selectMany(select,0.0), + selectTransform(defaultSelect, defaultTransform), + defaultSGAGenOp(_crossover, _pCross, _mutation, _pMut), + genBreed (select, defaultSGAGenOp), + breed (genBreed), + default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment(_metric, _kappa) ), + fitnessAssignment(*default_fitnessAssignment), + replace(fitnessAssignment, diversityAssignment) {} @@ -94,7 +107,7 @@ public: */ moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoGenOp < MOEOT > & _op, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) : defaultGenContinuator(0), continuator(_continuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), select(2), - selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), fitnessAssignment(_metric, _kappa), replace (fitnessAssignment, diversityAssignment) + selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace (fitnessAssignment, diversityAssignment) {} @@ -108,7 +121,7 @@ public: */ moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) : defaultGenContinuator(0), continuator(_continuator), eval(defaultEval), defaultPopEval(eval), popEval(_popEval), select(2), - selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), fitnessAssignment(_metric, _kappa), replace (fitnessAssignment, diversityAssignment) + selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace (fitnessAssignment, diversityAssignment) {} @@ -122,7 +135,7 @@ public: */ moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoTransform < MOEOT > & _transform, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) : defaultGenContinuator(0), continuator(_continuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), - select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), fitnessAssignment(_metric, _kappa), replace(fitnessAssignment, diversityAssignment) + select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace(fitnessAssignment, diversityAssignment) {} @@ -136,10 +149,43 @@ public: */ moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoTransform < MOEOT > & _transform, moeoNormalizedSolutionVsSolutionBinaryMetric < ObjectiveVector, double > & _metric, const double _kappa=0.05) : defaultGenContinuator(0), continuator(_continuator), eval(defaultEval), defaultPopEval(eval), popEval(_popEval), - select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), fitnessAssignment(_metric, _kappa), replace(fitnessAssignment, diversityAssignment) + select(2), selectMany(select, 1.0), selectTransform(selectMany, _transform), defaultSGAGenOp(defaultQuadOp, 0.0, defaultMonOp, 0.0), genBreed(select, defaultSGAGenOp), breed(selectTransform), default_fitnessAssignment( new moeoExpBinaryIndicatorBasedFitnessAssignment(_metric, _kappa)), fitnessAssignment(*default_fitnessAssignment), replace(fitnessAssignment, diversityAssignment) {} + /** + * Ctor with a eoContinue, a eoPopEval, a eoGenOp and an explicit fitnessAssignment + * @param _continuator stopping criteria + * @param _popEval population evaluation function + * @param _op variation operators + * @param _fitnessAssignment fitness assignment + */ + moeoIBEA (eoContinue < MOEOT > & _continuator, eoPopEvalFunc < MOEOT > & _popEval, eoGenOp < MOEOT > & _op, moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& _fitnessAssignment) : + defaultGenContinuator(0), continuator(_continuator), eval(defaultEval), defaultPopEval(eval), popEval(_popEval), select(2), + selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment(NULL), fitnessAssignment(_fitnessAssignment), replace(fitnessAssignment, diversityAssignment) + {} + + + /** + * Ctor with a eoContinue, a eoGenOp and an explicit fitnessAssignment + * @param _continuator stopping criteria + * @param _eval evaluation function + * @param _op variation operators + * @param _fitnessAssignment fitness assignment + */ + moeoIBEA (eoContinue < MOEOT > & _continuator, eoEvalFunc < MOEOT > & _eval, eoGenOp < MOEOT > & _op, moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& _fitnessAssignment) : + defaultGenContinuator(0), continuator(_continuator), eval(_eval), defaultPopEval(_eval), popEval(defaultPopEval), select(2), + selectMany(select,0.0), selectTransform(defaultSelect, defaultTransform), defaultSGAGenOp(defaultQuadOp, 1.0, defaultMonOp, 1.0), genBreed(select, _op), breed(genBreed), default_fitnessAssignment(NULL), fitnessAssignment(_fitnessAssignment), replace(fitnessAssignment, diversityAssignment) + {} + + + ~moeoIBEA() + { + if( default_fitnessAssignment != NULL ) { + delete default_fitnessAssignment; + } + } + /** * Apply the algorithm to the population _pop until the stopping criteria is satified. * @param _pop the population @@ -214,7 +260,8 @@ protected: /** breeder */ eoBreed < MOEOT > & breed; /** fitness assignment used in IBEA */ - moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT > fitnessAssignment; + moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >& fitnessAssignment; + moeoExpBinaryIndicatorBasedFitnessAssignment < MOEOT >* default_fitnessAssignment; /** dummy diversity assignment */ moeoDummyDiversityAssignment < MOEOT > diversityAssignment; /** environmental replacement */ From 45123abbf3313e95077a0be3664d5e404ed968f4 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 17:50:04 +0200 Subject: [PATCH 16/21] Add the DUAL fitness assignment class Change a bit the machinery of moeoExpBinaryIndicatorBasedFitnessAssignment to allow subclassing. --- ...inaryIndicatorBasedDualFitnessAssignment.h | 67 +++++++++++++++++++ ...ExpBinaryIndicatorBasedFitnessAssignment.h | 14 ++-- moeo/src/moeo | 1 + 3 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h new file mode 100644 index 000000000..d0a0e1317 --- /dev/null +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h @@ -0,0 +1,67 @@ + +#include + +template +class moeoExpBinaryIndicatorBasedDualFitnessAssignment : public moeoExpBinaryIndicatorBasedFitnessAssignment +{ +protected: + eoPop _feasible_pop; + eoPop _unfeasible_pop; + +public: + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + + moeoExpBinaryIndicatorBasedDualFitnessAssignment( + moeoNormalizedSolutionVsSolutionBinaryMetric & metric, + const double kappa = 0.05 + ) : moeoExpBinaryIndicatorBasedFitnessAssignment( metric, kappa ) {} + + //! Split up the population in two: in one pop the feasible individual, in the other the feasible ones + virtual void split( eoPop & pop ) + { + _feasible_pop.reserve(pop.size()); + _unfeasible_pop.reserve(pop.size()); + + for( typename eoPop::iterator it=pop.begin(), end=pop.end(); it != end; ++it ) { + // The ObjectiveVector should implement "is_feasible" + if( it->objectiveVector().is_feasible() ) { + _feasible_pop.push_back( *it ); + } else { + _unfeasible_pop.push_back( *it ); + } + } + } + + /*! If the population is homogeneous (only composed of feasible individuals or unfeasible ones), + * then apply the operators on the whole population. + * But, if there is at least one feasible individual, then apply them only on the feasible individuals. + */ + virtual void operator()(eoPop < MOEOT > & pop) + { + // separate the pop in the members + split( pop ); + + eoPop* ppop; + // if there is at least one feasible individual, it will supersede all the unfeasible ones + if( _feasible_pop.size() == 0 ) { + ppop = & _unfeasible_pop; + } else { + ppop = & _feasible_pop; + } + + this->setup(*ppop); + this->computeValues(*ppop); + this->setFitnesses(*ppop); + } + + virtual void setFitnesses(eoPop < MOEOT > & pop) + { + for (unsigned int i=0; icomputeFitness(i), pop[i].is_feasible() ); + } + } + + +}; + diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h index 3159c2840..7d8bb63b8 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h @@ -58,6 +58,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB /** The type of objective vector */ typedef typename MOEOT::ObjectiveVector ObjectiveVector; + typedef typename ObjectiveVector::Type Type; /** * Ctor. @@ -72,7 +73,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB * Sets the fitness values for every solution contained in the population _pop * @param _pop the population */ - void operator()(eoPop < MOEOT > & _pop) + virtual void operator()(eoPop < MOEOT > & _pop) { // 1 - setting of the bounds setup(_pop); @@ -145,7 +146,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB /** the scaling factor */ double kappa; /** the computed indicator values */ - std::vector < std::vector > values; + std::vector < std::vector > values; /** @@ -181,6 +182,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB for (unsigned int i=0; i<_pop.size(); i++) { values[i].resize(_pop.size()); + // the metric may not be symetric, thus neither is the matrix for (unsigned int j=0; j<_pop.size(); j++) { if (i != j) @@ -193,10 +195,10 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB /** - * Sets the fitness value of the whple population + * Sets the fitness value of the whole population * @param _pop the population */ - void setFitnesses(eoPop < MOEOT > & _pop) + virtual void setFitnesses(eoPop < MOEOT > & _pop) { for (unsigned int i=0; i<_pop.size(); i++) { @@ -209,9 +211,9 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB * Returns the fitness value of the _idx th individual of the population * @param _idx the index */ - double computeFitness(const unsigned int _idx) + Type computeFitness(const unsigned int _idx) { - double result = 0; + Type result(0.0); for (unsigned int i=0; i #include #include +#include #include #include #include From ac61b782c36b78395f493a61eca57dc1d793830f Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 7 Jun 2013 17:51:01 +0200 Subject: [PATCH 17/21] Use the objective type instead of double in metrics --- .../src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h b/moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h index 95a4e54ab..6a6368f1d 100644 --- a/moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h +++ b/moeo/src/metric/moeoNormalizedSolutionVsSolutionBinaryMetric.h @@ -52,6 +52,8 @@ class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSoluti { public: + typedef typename ObjectiveVector::Type Type; + /** * Default ctr for any moeoNormalizedSolutionVsSolutionBinaryMetric object */ @@ -72,7 +74,7 @@ class moeoNormalizedSolutionVsSolutionBinaryMetric : public moeoSolutionVsSoluti * @param _max upper bound * @param _obj the objective index */ - void setup(double _min, double _max, unsigned int _obj) + void setup( Type _min, Type _max, unsigned int _obj) { if (_min == _max) { From 55a1783605f452261af0ac89b3602708564e7c2a Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 11 Jun 2013 09:23:16 +0200 Subject: [PATCH 18/21] Use member arithmetic operators and friend stream operators in dual fitness --- eo/src/eoDualFitness.h | 103 +++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index f51ebb9a6..4d8831799 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -146,7 +146,7 @@ public: //! Copy operator from another eoDualFitness template - eoDualFitness & operator=(const eoDualFitness& other ) + eoDualFitness & operator=(const eoDualFitness& other ) { if (this != &other) { this->_value = other._value; @@ -215,9 +215,15 @@ public: // (for minimizing and maximizing) //! Add a given fitness to the current one - template - // friend - eoDualFitness & operator+=( /*eoDualFitness & from,*/ const eoDualFitness & that ) + template + eoDualFitness & operator+=( const T that ) + { + this->_value += that; + return *this; + } + + //! Add a given fitness to the current one + eoDualFitness & operator+=( const eoDualFitness & that ) { // from._value += that._value; this->_value += that._value; @@ -230,8 +236,15 @@ public: } //! Substract a given fitness to the current one - template - eoDualFitness & operator-=( const eoDualFitness & that ) + template + eoDualFitness & operator-=( const T that ) + { + this->_value -= that; + return *this; + } + + //! Substract a given fitness to the current one + eoDualFitness & operator-=( const eoDualFitness & that ) { this->_value -= that._value; @@ -241,27 +254,17 @@ public: return *this; } + //! Add a given fitness to the current one - template - eoDualFitness & operator+=( const T that ) + template + eoDualFitness & operator/=( T that ) { - this->_value += that; + this->_value /= that; return *this; } - //! Substract a given fitness to the current one - template - eoDualFitness & operator-=( const T that ) - { - this->_value -= that; - return *this; - } - - - //! Add a given fitness to the current one - template - eoDualFitness & operator/=( const eoDualFitness & that ) + eoDualFitness & operator/=( const eoDualFitness & that ) { this->_value /= that._value; @@ -271,61 +274,69 @@ public: return *this; } - - //! Add a given fitness to the current one - template - eoDualFitness & operator/=( T that ) + template + eoDualFitness operator+( T that ) { - this->_value /= that; - + this->_value += that; return *this; } // Add this fitness's value to that other, and return a _new_ instance with the result. - template - eoDualFitness operator+(const eoDualFitness & that) + eoDualFitness operator+( const eoDualFitness & that ) { - eoDualFitness from( *this ); + eoDualFitness from( *this ); return from += that; } - // Add this fitness's value to that other, and return a _new_ instance with the result. - template - eoDualFitness operator-(const eoDualFitness & that) + template + eoDualFitness operator-( T that ) { - eoDualFitness from( *this ); + this->_value -= that; + return *this; + } + + // Add this fitness's value to that other, and return a _new_ instance with the result. + eoDualFitness operator-( const eoDualFitness & that ) + { + eoDualFitness from( *this ); return from -= that; } - // Add this fitness's value to that other, and return a _new_ instance with the result. - template - eoDualFitness operator/(const eoDualFitness & that) + template + eoDualFitness operator/( T that ) { - eoDualFitness from( *this ); + this->_value /= that; + return *this; + } + + // Add this fitness's value to that other, and return a _new_ instance with the result. + eoDualFitness operator/( const eoDualFitness & that ) + { + eoDualFitness from( *this ); return from /= that; } //! Print an eoDualFitness instance as a pair of numbers, separated by a space - template - std::ostream& operator<<(std::ostream& os) + friend + std::ostream& operator<<( std::ostream& os, const eoDualFitness & fitness ) { - os << this->_value << " " << this->_is_feasible; + os << fitness._value << " " << fitness._is_feasible; return os; } //! Read an eoDualFitness instance as a pair of numbers, separated by a space - template - std::istream& operator>>(std::istream& is) + friend + std::istream& operator>>( std::istream& is, eoDualFitness & fitness ) { - F value; + BaseType value; is >> value; bool feasible; is >> feasible; - this->_value = value; - this->_is_feasible = feasible; + fitness._value = value; + fitness._is_feasible = feasible; return is; } }; From 97156dd69ad6b90584a3e72c5988852c9b11f5f3 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 11 Jun 2013 09:24:11 +0200 Subject: [PATCH 19/21] Fix the templates of moeoDualRealObjectiveVector --- moeo/src/core/moeoDualRealObjectiveVector.h | 35 +++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/moeo/src/core/moeoDualRealObjectiveVector.h b/moeo/src/core/moeoDualRealObjectiveVector.h index ce66ed329..1ed62a8ff 100644 --- a/moeo/src/core/moeoDualRealObjectiveVector.h +++ b/moeo/src/core/moeoDualRealObjectiveVector.h @@ -35,7 +35,7 @@ Authors: #include #include -template < class ObjectiveVectorTraits, class T = eoMinimizingDualFitness /* can be an eoMaximizingDualFitness */> +template < class ObjectiveVectorTraits, class T = eoMaximizingDualFitness /* can be an eoMinimizingDualFitness */> class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector { protected: @@ -43,14 +43,17 @@ class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector::size; + using moeoScalarObjectiveVector < ObjectiveVectorTraits, T >::operator[]; + moeoDualRealObjectiveVector(double value=0.0, bool feasible = false) - : moeoScalarObjectiveVector + : moeoScalarObjectiveVector ( T(value, feasible) ) {} bool is_feasible() const { #ifndef NDEBUG - // if the feasibility is correctly assigned, + // if the feasibility is correctly assigned, // every scalar's feasibility should be equal to the objective vector for( typename moeoDualRealObjectiveVector::const_iterator it = this->begin(), end = this->end(); it != end; ++it ) { assert( it->is_feasible() == _is_feasible ); @@ -119,13 +122,14 @@ class moeoDualRealObjectiveVector : public moeoScalarObjectiveVector -std::ostream & operator<<(std::ostream & _os, const moeoDualRealObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +template +std::ostream & operator<<( std::ostream & _os, const moeoDualRealObjectiveVector & _objectiveVector ) { - for (unsigned int i=0; i<_objectiveVector.size()-1; i++) - _os << _objectiveVector[i] << " "; - _os << _objectiveVector[_objectiveVector.size()-1]; - return _os; + for( unsigned int i=0; i<_objectiveVector.size()-1; i++ ) { + _os << _objectiveVector[i] << " "; + } + _os << _objectiveVector[_objectiveVector.size()-1]; + return _os; } /** @@ -133,15 +137,14 @@ std::ostream & operator<<(std::ostream & _os, const moeoDualRealObjectiveVector * @param _is input stream * @param _objectiveVector the objective vector to read */ -template < class ObjectiveVectorTraits > -std::istream & operator>>(std::istream & _is, moeoDualRealObjectiveVector < ObjectiveVectorTraits > & _objectiveVector) +template +std::istream & operator>>( std::istream & _is, moeoDualRealObjectiveVector & _objectiveVector ) { - _objectiveVector = moeoDualRealObjectiveVector < ObjectiveVectorTraits > (); - for (unsigned int i=0; i<_objectiveVector.size(); i++) - { - _is >> _objectiveVector[i]; + _objectiveVector = moeoDualRealObjectiveVector (); + for( unsigned int i=0; i<_objectiveVector.size(); i++ ) { + _is >> _objectiveVector[i]; } - return _is; + return _is; } From 82ce471aef216978ec83c292e55965dcea3234a8 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 11 Jun 2013 13:28:51 +0200 Subject: [PATCH 20/21] Add a warning in eoDualFitness comments --- eo/src/eoDualFitness.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/eo/src/eoDualFitness.h b/eo/src/eoDualFitness.h index 4d8831799..59d6f6d05 100644 --- a/eo/src/eoDualFitness.h +++ b/eo/src/eoDualFitness.h @@ -85,8 +85,9 @@ public: _is_feasible(false) {} - //! Empty initialization + //! Initialization with only the value, the fitness will be unfeasible. /*! + * WARNING: this is what is used when you initialize a new fitness from a double. * Unfeasible by default */ template @@ -137,7 +138,7 @@ public: } //! Copy operator from a std::pair - eoDualFitness& operator=(const std::pair& v) + eoDualFitness& operator=( const std::pair& v ) { this->_value = v.first; this->_is_feasible = v.second; @@ -146,7 +147,7 @@ public: //! Copy operator from another eoDualFitness template - eoDualFitness & operator=(const eoDualFitness& other ) + eoDualFitness & operator=( const eoDualFitness& other ) { if (this != &other) { this->_value = other._value; From 75340a5c91468a2d98ecb356914ee9b725f4f675 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Tue, 11 Jun 2013 13:29:57 +0200 Subject: [PATCH 21/21] Add hyper volume continuators & metrics handling feasibility constraint on objectives --- moeo/src/continue/moeoHypContinue.h | 119 +++++++++++++- ...inaryIndicatorBasedDualFitnessAssignment.h | 27 +++- ...ExpBinaryIndicatorBasedFitnessAssignment.h | 2 +- .../metric/moeoHyperVolumeDifferenceMetric.h | 153 ++++++++++++++---- 4 files changed, 258 insertions(+), 43 deletions(-) diff --git a/moeo/src/continue/moeoHypContinue.h b/moeo/src/continue/moeoHypContinue.h index 85be8281e..f6fbac34a 100644 --- a/moeo/src/continue/moeoHypContinue.h +++ b/moeo/src/continue/moeoHypContinue.h @@ -46,11 +46,11 @@ #include /** - Continues until the optimum ParetoSet level is reached. + Continues until the given ParetoSet level is reached. @ingroup Continuators */ -template< class MOEOT> +template< class MOEOT, class MetricT = moeoHyperVolumeDifferenceMetric > class moeoHypContinue: public eoContinue { public: @@ -71,8 +71,20 @@ public: vectorToParetoSet(_OptimVec); } + /** Returns false when a ParetoSet is reached. */ virtual bool operator() ( const eoPop& _pop ) + { + std::vector bestCurrentParetoSet = pareto( arch ); + + return is_null_hypervolume( bestCurrentParetoSet ); + } + + virtual std::string className(void) const { return "moeoHypContinue"; } + +protected: + + std::vector pareto( moeoArchive & _archive ) { std::vector < ObjectiveVector > bestCurrentParetoSet; @@ -80,7 +92,12 @@ public: bestCurrentParetoSet.push_back(arch[i].objectiveVector()); } - double hypervolume= metric(bestCurrentParetoSet,OptimSet ); + return bestCurrentParetoSet; + } + + bool is_null_hypervolume( std::vector& bestCurrentParetoSet ) + { + double hypervolume= metric( bestCurrentParetoSet, OptimSet ); if (hypervolume==0) { eo::log << eo::logging << "STOP in moeoHypContinue: Best ParetoSet has been reached " @@ -91,7 +108,7 @@ public: } /** Translate a vector given as param to the ParetoSet that should be reached. */ - void vectorToParetoSet(const std::vector & _OptimVec) + virtual void vectorToParetoSet(const std::vector & _OptimVec) { unsigned dim = (unsigned)(_OptimVec.size()/ObjectiveVector::Traits::nObjectives()); OptimSet.resize(dim); @@ -104,12 +121,98 @@ public: } } - virtual std::string className(void) const { return "moeoHypContinue"; } - -private: +protected: moeoArchive & arch; - moeoHyperVolumeDifferenceMetric metric; + MetricT metric; std::vector OptimSet; }; + +/** + Continues until the (feasible or unfeasible) given Pareto set is reached. + + + @ingroup Continuators + */ +template< class MOEOT, class MetricT = moeoDualHyperVolumeDifferenceMetric > +class moeoDualHypContinue: public moeoHypContinue +{ +protected: + bool is_feasible; + + using moeoHypContinue::arch; + using moeoHypContinue::OptimSet; + +public: + typedef typename MOEOT::ObjectiveVector ObjectiveVector; + typedef typename ObjectiveVector::Type AtomType; + + /** A continuator that stops once a given Pareto front has been reached + * + * You should specify the feasibility of the targeted front. + * NOTE: the MOEOT::ObjectiveVector is supposed to implement the moeoDualRealObjectiveVector interface. + * + */ + moeoDualHypContinue( const std::vector & _OptimVec, bool _is_feasible, moeoArchive < MOEOT > & _archive, bool _normalize=true, double _rho=1.1 ) + : moeoHypContinue( _OptimVec, _archive, _normalize, _rho ), is_feasible(_is_feasible) + { + assert( _OptimVec.size() > 0); + vectorToParetoSet(_OptimVec); + } + + /** A continuator that stops once a given Pareto front has been reached + * + * You should specify the feasibility of the targeted front. + * NOTE: the MOEOT::ObjectiveVector is supposed to implement the moeoDualRealObjectiveVector interface. + * + */ + moeoDualHypContinue( const std::vector & _OptimVec, bool _is_feasible, moeoArchive < MOEOT > & _archive, bool _normalize=true, ObjectiveVector& _ref_point=NULL ) + : moeoHypContinue( _OptimVec, _archive, _normalize, _ref_point ), is_feasible(_is_feasible) + { + assert( _OptimVec.size() > 0); + vectorToParetoSet(_OptimVec); + } + + /** Returns false when a ParetoSet is reached. */ + virtual bool operator() ( const eoPop& _pop ) + { + std::vector bestCurrentParetoSet = pareto( arch ); + +#ifndef NDEBUG + assert( bestCurrentParetoSet.size() > 0 ); + for( unsigned int i=1; i::pareto; + using moeoHypContinue::is_null_hypervolume; + + /** Translate a vector given as param to the ParetoSet that should be reached. */ + virtual void vectorToParetoSet(const std::vector & _OptimVec) + { + unsigned dim = (unsigned)(_OptimVec.size()/ObjectiveVector::Traits::nObjectives()); + OptimSet.resize(dim); + + unsigned k=0; + for(size_t i=0; i < dim; i++) { + for (size_t j=0; j < ObjectiveVector::Traits::nObjectives(); j++) { + // Use the feasibility declaration of an eoDualFitness + OptimSet[i][j] = AtomType(_OptimVec[k++], is_feasible); + } + } + } +}; + #endif diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h index d0a0e1317..bff35769c 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedDualFitnessAssignment.h @@ -10,6 +10,9 @@ protected: public: typedef typename MOEOT::ObjectiveVector ObjectiveVector; + typedef typename ObjectiveVector::Type Type; + + using moeoExpBinaryIndicatorBasedFitnessAssignment::values; moeoExpBinaryIndicatorBasedDualFitnessAssignment( moeoNormalizedSolutionVsSolutionBinaryMetric & metric, @@ -54,11 +57,33 @@ public: this->setFitnesses(*ppop); } + /** + * Compute every indicator value in values (values[i] = I(_v[i], _o)) + * @param _pop the population + */ + void computeValues(const eoPop < MOEOT > & _pop) + { + values.clear(); + values.resize(_pop.size()); + for (unsigned int i=0; i<_pop.size(); i++) + { + values[i].resize(_pop.size()); + // the metric may not be symetric, thus neither is the matrix + for (unsigned int j=0; j<_pop.size(); j++) + { + if (i != j) + { + values[i][j] = Type( metric(_pop[i].objectiveVector(), _pop[j].objectiveVector()), _pop[i].objectiveVector().is_feasible() ); + } + } + } + } + virtual void setFitnesses(eoPop < MOEOT > & pop) { for (unsigned int i=0; icomputeFitness(i), pop[i].is_feasible() ); + pop[i].fitness( this->computeFitness(i), pop[i].fitness().is_feasible() ); } } diff --git a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h index 7d8bb63b8..d84b052e9 100644 --- a/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h +++ b/moeo/src/fitness/moeoExpBinaryIndicatorBasedFitnessAssignment.h @@ -187,7 +187,7 @@ class moeoExpBinaryIndicatorBasedFitnessAssignment : public moeoBinaryIndicatorB { if (i != j) { - values[i][j] = metric(_pop[i].objectiveVector(), _pop[j].objectiveVector()); + values[i][j] = Type( metric(_pop[i].objectiveVector(), _pop[j].objectiveVector()) ); } } } diff --git a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h index 9d3a1c4b9..aaa899827 100644 --- a/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h +++ b/moeo/src/metric/moeoHyperVolumeDifferenceMetric.h @@ -86,41 +86,42 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < */ double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) { - double hypervolume_set1; - double hypervolume_set2; - if(rho >= 1.0){ - //determine bounds - setup(_set1, _set2); - //determine reference point - for (unsigned int i=0; i= 1.0){ + //determine bounds + setup(_set1, _set2); + //determine reference point + for (unsigned int i=0; i unaryMetric(ref_point, bounds); - hypervolume_set1 = unaryMetric(_set1); - hypervolume_set2 = unaryMetric(_set2); + } + else if(normalize) + setup(_set1, _set2); - return hypervolume_set1 - hypervolume_set2; + moeoHyperVolumeMetric unaryMetric(ref_point, bounds); + hypervolume_set1 = unaryMetric(_set1); + hypervolume_set2 = unaryMetric(_set2); + + return hypervolume_set1 - hypervolume_set2; } /** @@ -132,7 +133,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < } /** - * method caclulate bounds for the normalization + * method calculate bounds for the normalization * @param _set1 the vector contains all objective Vector of the first pareto front * @param _set2 the vector contains all objective Vector of the second pareto front */ @@ -182,7 +183,7 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < return 1e-6; } - private: + protected: /*boolean indicates if data must be normalized or not*/ bool normalize; @@ -196,4 +197,90 @@ class moeoHyperVolumeDifferenceMetric : public moeoVectorVsVectorBinaryMetric < }; + +template +class moeoDualHyperVolumeDifferenceMetric : public moeoHyperVolumeDifferenceMetric +{ +protected: + using moeoHyperVolumeDifferenceMetric::rho; + using moeoHyperVolumeDifferenceMetric::normalize; + using moeoHyperVolumeDifferenceMetric::ref_point; + using moeoHyperVolumeDifferenceMetric::bounds; + +public: + + typedef typename ObjectiveVector::Type Type; + + moeoDualHyperVolumeDifferenceMetric( bool _normalize=true, double _rho=1.1) + : moeoHyperVolumeDifferenceMetric(_normalize, _rho) + { + + } + + moeoDualHyperVolumeDifferenceMetric( bool _normalize/*=true*/, ObjectiveVector& _ref_point/*=NULL*/ ) + : moeoHyperVolumeDifferenceMetric( _normalize, _ref_point ) + { + + } + + /** + * calculates and returns the HyperVolume value of a pareto front + * @param _set1 the vector contains all objective Vector of the first pareto front + * @param _set2 the vector contains all objective Vector of the second pareto front + */ + double operator()(const std::vector < ObjectiveVector > & _set1, const std::vector < ObjectiveVector > & _set2) + { +#ifndef NDEBUG + // the two sets must be homogeneous in feasibility + assert( _set1.size() > 0 ); + for( unsigned int i=1; i<_set1.size(); ++i ) { + assert( _set1[i].is_feasible() == _set1[0].is_feasible() ); + } + assert( _set2.size() > 0 ); + for( unsigned int i=1; i<_set2.size(); ++i ) { + assert( _set2[i].is_feasible() == _set2[0].is_feasible() ); + } + // and they must have the same feasibility + assert( _set1[0].is_feasible() == _set2[0].is_feasible() ); +#endif + bool feasible = _set1[0].is_feasible(); + + double hypervolume_set1; + double hypervolume_set2; + + if(rho >= 1.0){ + //determine bounds + setup(_set1, _set2); + //determine reference point + for (unsigned int i=0; i unaryMetric(ref_point, bounds); + hypervolume_set1 = unaryMetric(_set1); + hypervolume_set2 = unaryMetric(_set2); + + return hypervolume_set1 - hypervolume_set2; + } +}; + #endif /*MOEOHYPERVOLUMEMETRIC_H_*/