diff --git a/CMakeLists.txt b/CMakeLists.txt index da1e0541b..4dc2013c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ enable_language(CXX) ## Test the presence of a compiler if("${CMAKE_CXX_COMPILER}" STREQUAL "" OR "${CMAKE_C_COMPILER}" STREQUAL "") - message(FATAL_ERROR "No compiler found !") + message(FATAL_ERROR "No compiler found!") endif() ## Versioning @@ -35,6 +35,7 @@ SET(GLOBAL_VERSION "${VERSION}") ###################################################################################### ## Optional +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/module" CACHE INTERNAL "Cmake module" FORCE) include(FindDoxygen OPTIONAL) ###################################################################################### diff --git a/cmake/module/FindEigen3.cmake b/cmake/module/FindEigen3.cmake new file mode 100644 index 000000000..dda45e662 --- /dev/null +++ b/cmake/module/FindEigen3.cmake @@ -0,0 +1,39 @@ +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + set(EIGEN3_VERSION_OK TRUE) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + _eigen3_check_version( ) + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + ${PROJECT_SOURCE_DIR}/External + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version( ) + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/cmake/module/FindParadiseo.cmake b/cmake/module/FindParadiseo.cmake index 0f476e092..59b85a864 100644 --- a/cmake/module/FindParadiseo.cmake +++ b/cmake/module/FindParadiseo.cmake @@ -38,7 +38,7 @@ endif() # enabled components if ("${Paradiseo_FIND_COMPONENTS}" STREQUAL "") - set(PARADISEO_LIBRARIES_TO_FIND eo eoutils edoutils cma es flowshop ga moeo) + set(PARADISEO_LIBRARIES_TO_FIND eo eoutils cma es flowshop ga moeo) else() set(PARADISEO_LIBRARIES_TO_FIND ${Paradiseo_FIND_COMPONENTS}) endif() @@ -64,10 +64,6 @@ find_path(EO_INCLUDE_DIR eo PATH_SUFFIXES include${INSTALL_SUB_DIR}/eo eo/src PATHS ${PARADISEO_SRC_PATHS}) -find_path(EDO_INCLUDE_DIR edo - PATH_SUFFIXES include${INSTALL_SUB_DIR}/edo edo/src - PATHS ${PARADISEO_SRC_PATHS}) - find_path(MO_INCLUDE_DIR mo PATH_SUFFIXES include${INSTALL_SUB_DIR}/mo mo/src PATHS ${PARADISEO_SRC_PATHS}) @@ -85,7 +81,12 @@ foreach(COMP ${PARADISEO_LIBRARIES_TO_FIND}) PATHS ${PARADISEO_SRC_PATHS}) elseif(${COMP} STREQUAL "peo") set(PEO_FOUND true) - find_path(PEO_INCLUDE_DIR peo + find_path(EDO_INCLUDE_DIR edo + PATH_SUFFIXES include${INSTALL_SUB_DIR}/edo edo/src + PATHS ${PARADISEO_SRC_PATHS}) + elseif(${COMP} STREQUAL "edo") + set(EDO_FOUND true) + find_path(EDO_INCLUDE_DIR peo PATH_SUFFIXES include${INSTALL_SUB_DIR}/peo peo/src PATHS ${PARADISEO_SRC_PATHS}) endif() diff --git a/edo/CMakeLists.txt b/edo/CMakeLists.txt index 8bb80abc8..41a6b476e 100644 --- a/edo/CMakeLists.txt +++ b/edo/CMakeLists.txt @@ -1,33 +1,25 @@ -IF(EDO_USE_LIB STREQUAL "uBLAS") - FIND_PACKAGE(Boost ) - IF( Boost_FOUND ) - INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ) - ADD_DEFINITIONS( -DWITH_BOOST ) - ELSE() - MESSAGE( "ERROR: You asked for Boost::uBLAS but it has not been found." ) - SET(IS_FATAL 1) - ENDIF() -ELSEIF( EDO_USE_LIB STREQUAL "Eigen3" ) - # FIXME FindEigen3.cmake does not work - #find_package(Eigen3) - #include_directories(EIGEN3_INCLUDE_DIR) - SET( EIGEN3_FOUND 1) - SET( EIGEN3_INCLUDE_DIR "/usr/include/eigen3/" ) +if(EDO_USE_LIB STREQUAL "uBLAS") + find_package(Boost) + if(Boost_FOUND) + include_directories( ${Boost_INCLUDE_DIRS} ) + add_definitions( -DWITH_BOOST ) + else() + message(FATAL_ERROR "\n\nERROR: You asked for Boost::uBLAS but it has not been found.\n" ) + endif() +elseif(EDO_USE_LIB STREQUAL "Eigen3") + find_package(Eigen3) + if(EIGEN3_FOUND) + include_directories(EIGEN3_INCLUDE_DIR) + add_definitions( -DWITH_EIGEN ) + else() + message(FATAL_ERROR "\n\nERROR: You asked for Eigen3 but it has not been found.\n" ) + endif() - IF( EIGEN3_FOUND ) - INCLUDE_DIRECTORIES( ${EIGEN3_INCLUDE_DIR} ) - ADD_DEFINITIONS( -DWITH_EIGEN ) - ELSE() - MESSAGE( "ERROR: You asked for Eigen3 but it has not been found." ) - SET(IS_FATAL 1) - ENDIF() - -ELSE() +else() # FIXME ideally, we would have a minimal implementation with STL vectors… - MESSAGE( "You must set EDO_USE_LIB to either 'uBLAS' or 'Eigen3'." ) - SET(IS_FATAL 1) -ENDIF() + message(FATAL_ERROR "\n\nYou must set EDO_USE_LIB to either 'uBLAS' or 'Eigen3'.\n" ) +endif() ###################################################################################### @@ -37,14 +29,14 @@ ENDIF() add_subdirectory(doc) add_subdirectory(src) -if(ENABLE_CMAKE_TESTING) +if(ENABLE_CMAKE_TESTING AND EIGEN3_FOUND) # see edoNormalAdaptive add_subdirectory(test) -endif(ENABLE_CMAKE_TESTING) +endif() if(ENABLE_CMAKE_EXAMPLE) if(${CMAKE_VERBOSE_MAKEFILE}) message("EDO examples:") endif(${CMAKE_VERBOSE_MAKEFILE}) add_subdirectory(application) -endif(ENABLE_CMAKE_EXAMPLE) +endif() diff --git a/edo/application/CMakeLists.txt b/edo/application/CMakeLists.txt index 88462c0a7..4b871f042 100644 --- a/edo/application/CMakeLists.txt +++ b/edo/application/CMakeLists.txt @@ -2,13 +2,18 @@ ### 1) Where do we go now ?!? ###################################################################################### -INCLUDE_DIRECTORIES( +include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/common ) -ADD_SUBDIRECTORY(common) # Rosenbrock and Sphere -#ADD_SUBDIRECTORY(eda_sa) -ADD_SUBDIRECTORY(eda) -ADD_SUBDIRECTORY(cmaes) +include_directories(${EIGEN3_INCLUDE_DIR}) + +add_subdirectory(common) # Rosenbrock and Sphere +#add_subdirectory(eda_sa) + +if(EIGEN3_FOUND) # see edoNormalAdaptive + add_subdirectory(eda) + add_subdirectory(cmaes) +endif() ###################################################################################### diff --git a/edo/application/eda/CMakeLists.txt b/edo/application/eda/CMakeLists.txt index 9966cb6f8..fe1ee606f 100644 --- a/edo/application/eda/CMakeLists.txt +++ b/edo/application/eda/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) include_directories(${EO_SRC_DIR}/src) -include_directories(${EDO_SRC_DIR}/src) link_directories(${EO_BIN_DIR}/${LIB}) +include_directories(${EDO_SRC_DIR}/src) link_directories(${EDO_BIN_DIR}/${LIB}) set(RESOURCES diff --git a/edo/test/CMakeLists.txt b/edo/test/CMakeLists.txt index 0d98852fe..5ab7eb21b 100644 --- a/edo/test/CMakeLists.txt +++ b/edo/test/CMakeLists.txt @@ -23,17 +23,13 @@ ### 3) Define your targets and link the librairies ###################################################################################### -find_package(Boost 1.33.0) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - -include_directories(${Boost_INCLUDE_DIRS}) -link_directories(${Boost_LIBRARY_DIRS}) - include_directories(${CMAKE_SOURCE_DIR}/application/common) include_directories(${EO_SRC_DIR}/src) include_directories(${EDO_SRC_DIR}/src) +include_directories(${EIGEN3_INCLUDE_DIR}) + set(SOURCES #t-cholesky t-variance @@ -42,14 +38,14 @@ set(SOURCES t-bounderno t-uniform t-continue - t-dispatcher-round +# t-dispatcher-round t-repairer-modulo ) foreach(current ${SOURCES}) add_executable(${current} ${current}.cpp) add_test(${current} ${current}) - target_link_libraries(${current} eo eoutils edoutils ${Boost_LIBRARIES}) + target_link_libraries(${current} eo eoutils edoutils) install(TARGETS ${current} RUNTIME DESTINATION share/edo/test COMPONENT test) endforeach() diff --git a/eo/src/eo b/eo/src/eo index b87ca57f1..8196e2b14 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -78,7 +78,6 @@ #include #include #include -#include // Continuators - all include eoContinue.h #include @@ -103,7 +102,6 @@ #include // Embedding truncation selection #include -#include // the batch selection - from an eoSelectOne #include @@ -115,6 +113,7 @@ // DetSelect can also be obtained as eoSequentialSelect, an eoSelectOne // (using setup and an index) #include +#include // Breeders #include // applies one eoGenOp, stop on offspring count @@ -143,9 +142,6 @@ #include // includes eoRealBounds.h #include // no eoIntVectorBounds -// Serialization stuff -#include - // aliens #include #include diff --git a/eo/src/eoEasyEA.h b/eo/src/eoEasyEA.h index 4d9c7b6da..2c7c5474c 100644 --- a/eo/src/eoEasyEA.h +++ b/eo/src/eoEasyEA.h @@ -37,6 +37,8 @@ #include #include + + template class eoIslandsEasyEA ; template class eoDistEvalEasyEA ; @@ -100,33 +102,6 @@ template class eoEasyEA: public eoAlgo offspring.reserve(_offspringSize); // This line avoids an incremental resize of offsprings. } - /** - * @brief Ctor allowing to specify which pop eval function we're going to use. - * - * Ctor taking a breed and merge, an overload of ctor to define an offspring size, and - * the pop eval function used. This allows to precise if we would like to use the - * parallel evaluation, for instance. - */ - eoEasyEA( - eoContinue& _continuator, - eoEvalFunc& _eval, - eoPopEvalFunc& _pop_eval, - eoBreed& _breed, - eoReplacement& _replace, - unsigned _offspringSize - ) : continuator(_continuator), - eval (_eval), - loopEval(_eval), - popEval(_pop_eval), - selectTransform(dummySelect, dummyTransform), - breed(_breed), - mergeReduce(dummyMerge, dummyReduce), - replace(_replace), - isFirstCall(true) - { - offspring.reserve(_offspringSize); // This line avoids an incremental resize of offsprings. - } - /* eoEasyEA(eoContinue & _continuator, eoPopEvalFunc & _pop_eval, @@ -244,44 +219,45 @@ template class eoEasyEA: public eoAlgo /// Apply a few generation of evolution to the population. virtual void operator()(eoPop& _pop) { + if (isFirstCall) + { + size_t total_capacity = _pop.capacity() + offspring.capacity(); + _pop.reserve(total_capacity); + offspring.reserve(total_capacity); + isFirstCall = false; + } - if (isFirstCall) + eoPop empty_pop; + + popEval(empty_pop, _pop); // A first eval of pop. + + do { - size_t total_capacity = _pop.capacity() + offspring.capacity(); - _pop.reserve(total_capacity); - offspring.reserve(total_capacity); - isFirstCall = false; - } - - eoPop empty_pop; - - do - { - try + try { - unsigned pSize = _pop.size(); + unsigned pSize = _pop.size(); + offspring.clear(); // new offspring - offspring.clear(); // new offspring + breed(_pop, offspring); - breed(_pop, offspring); + popEval(_pop, offspring); // eval of parents + offspring if necessary - popEval(_pop, offspring); // eval of parents + offspring if necessary + replace(_pop, offspring); // after replace, the new pop. is in _pop - replace(_pop, offspring); // after replace, the new pop. is in _pop + if (pSize > _pop.size()) + throw std::runtime_error("Population shrinking!"); + else if (pSize < _pop.size()) + throw std::runtime_error("Population growing!"); - if (pSize > _pop.size()) - throw std::runtime_error("Population shrinking!"); - else if (pSize < _pop.size()) - throw std::runtime_error("Population growing!"); } - catch (std::exception& e) + catch (std::exception& e) { - std::string s = e.what(); - s.append( " in eoEasyEA"); - throw std::runtime_error( s ); + std::string s = e.what(); + s.append( " in eoEasyEA"); + throw std::runtime_error( s ); } } - while ( continuator( _pop ) ); + while ( continuator( _pop ) ); } protected : diff --git a/eo/src/eoEvalFuncCounterBounder.h b/eo/src/eoEvalFuncCounterBounder.h index 1c8a29b15..7114e7f37 100644 --- a/eo/src/eoEvalFuncCounterBounder.h +++ b/eo/src/eoEvalFuncCounterBounder.h @@ -55,7 +55,7 @@ public : throw eoEvalFuncCounterBounderException(_threshold); } - func(eo); + this->func(eo); } } diff --git a/mo/src/explorer/moRandomNeutralWalkExplorer.h b/mo/src/explorer/moRandomNeutralWalkExplorer.h index 6db9ad32b..3a5eddc3e 100644 --- a/mo/src/explorer/moRandomNeutralWalkExplorer.h +++ b/mo/src/explorer/moRandomNeutralWalkExplorer.h @@ -73,7 +73,7 @@ public: nbStep(_nbStep) { isAccept = false; if (!neighborhood.isRandom()) { - std::cout << "moRandomNeutralWalkExplorer::Warning -> the neighborhood used is not random" << std::endl; + std::cout << "moRandomNeutralWalkExplorer::Warning -> the neighborhood used is not random (" << neighborhood.className() << ")" << std::endl; } } diff --git a/mo/src/explorer/moRandomWalkExplorer.h b/mo/src/explorer/moRandomWalkExplorer.h index 5f4de7eef..78f1be303 100644 --- a/mo/src/explorer/moRandomWalkExplorer.h +++ b/mo/src/explorer/moRandomWalkExplorer.h @@ -68,7 +68,7 @@ public: moRandomWalkExplorer(Neighborhood& _neighborhood, moEval& _eval) : moNeighborhoodExplorer(_neighborhood, _eval) { isAccept = false; if (!neighborhood.isRandom()) { - std::cout << "moRandomWalkExplorer::Warning -> the neighborhood used is not random" << std::endl; + std::cout << "moRandomNeutralWalkExplorer::Warning -> the neighborhood used is not random (" << neighborhood.className() << ")" << std::endl; } } diff --git a/mo/src/perturb/moMonOpPerturb.h b/mo/src/perturb/moMonOpPerturb.h index c056bbf6a..a4bcea574 100644 --- a/mo/src/perturb/moMonOpPerturb.h +++ b/mo/src/perturb/moMonOpPerturb.h @@ -48,8 +48,9 @@ public: * Constructor * @param _monOp an eoMonOp (pertubation operator) * @param _fullEval a full evaluation function + * @param _nbPerturbation number of operator executions for perturbation */ - moMonOpPerturb(eoMonOp& _monOp, eoEvalFunc& _fullEval):monOp(_monOp), fullEval(_fullEval) {} + moMonOpPerturb(eoMonOp& _monOp, eoEvalFunc& _fullEval, unsigned int _nbPerturbation = 1):monOp(_monOp), fullEval(_fullEval), nbPerturbation(_nbPerturbation) {} /** * Apply monOp on the solution @@ -57,16 +58,22 @@ public: * @return value of monOp */ bool operator()(EOT& _solution) { - bool res = monOp(_solution); - _solution.invalidate(); - fullEval(_solution); - return res; + bool res = false; + + for(unsigned int i = 0; i < nbPerturbation; i++) + res = res || monOp(_solution); + + _solution.invalidate(); + fullEval(_solution); + + return res; } private: - /** monOp */ - eoMonOp& monOp; - eoEvalFunc& fullEval; + /** monOp */ + eoMonOp& monOp; + eoEvalFunc& fullEval; + unsigned int nbPerturbation; }; #endif diff --git a/mo/src/problems/bitString/moBitFlipNeighborhood.h b/mo/src/problems/bitString/moBitFlipNeighborhood.h index 21cbed35c..dbbe05c26 100644 --- a/mo/src/problems/bitString/moBitFlipNeighborhood.h +++ b/mo/src/problems/bitString/moBitFlipNeighborhood.h @@ -1,36 +1,36 @@ /* - - Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 - - Sebastien Verel, Arnaud Liefooghe, Jeremie Humeau - - 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 Lille - Nord Europe, 2006-2010 + + Sebastien Verel, Arnaud Liefooghe, Jeremie Humeau + + 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 _moBitFlipNeighborhood_h #define _moBitFlipNeighborhood_h @@ -51,111 +51,119 @@ template< class Neighbor > class moBitFlipNeighborhood : public moNeighborhood { public: - - /** - * Define type of a solution corresponding to Neighbor - */ - typedef typename Neighbor::EOT EOT; - - /** - * Constructor - * - * @param _rate bit flip rate (per bit) - * @param _length bit string length - * @param _sampleSize number of neighbor to sample in the neighborhood, if 0 all the neighborhood is sampled - */ - moBitFlipNeighborhood(double _rate, unsigned _length, unsigned _sampleSize): moNeighborhood(), rate(_rate), length(_length), sampleSize(_sampleSize) { - nNeighbors = 0; - } - - /** - * Test if it exist a neighbor - * @param _solution the solution to explore - * @return true if the neighborhood was not empty (bit string larger than 0) - */ - virtual bool hasNeighbor(EOT& _solution) { - return _solution.size() > 0; - } - - /** - * one random neighbor - * - * @param _solution the solution to explore - * @param _neighbor the first neighbor - */ - virtual void randomNeighbor(EOT & _solution, Neighbor & _neighbor) { - // number of flipped bits - _neighbor.nBits = 0; - - for(unsigned int i = 0; i < _solution.size(); i++) { - if (rng.flip(rate)) { - if (_neighbor.nBits < _neighbor.bits.size()) - _neighbor.bits[_neighbor.nBits] = i; - else - _neighbor.bits.push_back(i); - _neighbor.nBits++; - } + + /** + * Define type of a solution corresponding to Neighbor + */ + typedef typename Neighbor::EOT EOT; + + /** + * Constructor + * + * @param _rate bit flip rate (per bit) + * @param _length bit string length + * @param _sampleSize number of neighbor to sample in the neighborhood, if 0 all the neighborhood is sampled + */ + moBitFlipNeighborhood(double _rate, unsigned _length, unsigned _sampleSize): moNeighborhood(), rate(_rate), length(_length), sampleSize(_sampleSize) { + nNeighbors = 0; } - - // reduce the size if necessary - if (_neighbor.nBits < _neighbor.bits.size()) - _neighbor.bits.resize(_neighbor.nBits); - } - - /** - * Initialization of the neighborhood: - * one random neighbor - * - * @param _solution the solution to explore - * @param _neighbor the first neighbor - */ - virtual void init(EOT & _solution, Neighbor & _neighbor) { - randomNeighbor(_solution, _neighbor); - - nNeighbors = 1; - } - - /** - * Give the next neighbor - * apply several bit flips on the solution - * @param _solution the solution to explore (population of solutions) - * @param _neighbor the next neighbor which in order of distance - */ - virtual void next(EOT & _solution, Neighbor & _neighbor) { - randomNeighbor(_solution, _neighbor); - - nNeighbors++; - } - - /** - * Test if all neighbors are explored or not,if false, there is no neighbor left to explore - * @param _solution the solution to explore - * @return true if there is again a neighbor to explore: population size larger or equals than 1 - */ - virtual bool cont(EOT & _solution) { - return nNeighbors < sampleSize ; - } - - /** - * Return the class Name - * @return the class name as a std::string - */ - virtual std::string className() const { - return "moBitFlipNeighborhood"; - } - + + /** + * Test if it exist a neighbor + * @param _solution the solution to explore + * @return true if the neighborhood was not empty (bit string larger than 0) + */ + virtual bool hasNeighbor(EOT& _solution) { + return _solution.size() > 0; + } + + /** + * one random neighbor + * + * @param _solution the solution to explore + * @param _neighbor the first neighbor + */ + virtual void randomNeighbor(EOT & _solution, Neighbor & _neighbor) { + // number of flipped bits + _neighbor.nBits = 0; + + for(unsigned int i = 0; i < _solution.size(); i++) { + if (rng.flip(rate)) { + if (_neighbor.nBits < _neighbor.bits.size()) + _neighbor.bits[_neighbor.nBits] = i; + else + _neighbor.bits.push_back(i); + _neighbor.nBits++; + } + } + + // reduce the size if necessary + if (_neighbor.nBits < _neighbor.bits.size()) + _neighbor.bits.resize(_neighbor.nBits); + } + + /** + * Initialization of the neighborhood: + * one random neighbor + * + * @param _solution the solution to explore + * @param _neighbor the first neighbor + */ + virtual void init(EOT & _solution, Neighbor & _neighbor) { + randomNeighbor(_solution, _neighbor); + + nNeighbors = 1; + } + + /** + * Give the next neighbor + * apply several bit flips on the solution + * @param _solution the solution to explore (population of solutions) + * @param _neighbor the next neighbor which in order of distance + */ + virtual void next(EOT & _solution, Neighbor & _neighbor) { + randomNeighbor(_solution, _neighbor); + + nNeighbors++; + } + + /** + * Test if all neighbors are explored or not,if false, there is no neighbor left to explore + * @param _solution the solution to explore + * @return true if there is again a neighbor to explore: population size larger or equals than 1 + */ + virtual bool cont(EOT & _solution) { + return nNeighbors < sampleSize ; + } + + /** + * The neighborhood is random here + * @return true, since the neighborhood is random + */ + bool isRandom() { + return true; + } + + /** + * Return the class Name + * @return the class name as a std::string + */ + virtual std::string className() const { + return "moBitFlipNeighborhood"; + } + protected: - // bit flip rate - double rate; - - // length of the bit string - unsigned int length; - - // maximum number of visited neighbor i.e. number of neighbor to sample in the neighborhood - unsigned int sampleSize; - - // number of visited neighbors - unsigned nNeighbors; + // bit flip rate + double rate; + + // length of the bit string + unsigned int length; + + // maximum number of visited neighbor i.e. number of neighbor to sample in the neighborhood + unsigned int sampleSize; + + // number of visited neighbors + unsigned nNeighbors; }; #endif diff --git a/mo/src/problems/eval/moQAPIncrEval.h b/mo/src/problems/eval/moQAPIncrEval.h index 3fd529a7f..5c47623d9 100644 --- a/mo/src/problems/eval/moQAPIncrEval.h +++ b/mo/src/problems/eval/moQAPIncrEval.h @@ -61,10 +61,10 @@ public: int d; int k; - unsigned i, j; - - _neighbor.getIndices(n, i, j); + unsigned i = _neighbor.first(); + unsigned j = _neighbor.second(); + // _neighbor.getIndices(n, i, j); d = (A[i][i]-A[j][j])*(B[_solution[j]][_solution[j]]-B[_solution[i]][_solution[i]]) + (A[i][j]-A[j][i])*(B[_solution[j]][_solution[i]]-B[_solution[i]][_solution[j]]); diff --git a/mo/src/problems/permutation/moIndexedSwapNeighbor.h b/mo/src/problems/permutation/moIndexedSwapNeighbor.h index 06491f134..d30305100 100644 --- a/mo/src/problems/permutation/moIndexedSwapNeighbor.h +++ b/mo/src/problems/permutation/moIndexedSwapNeighbor.h @@ -107,6 +107,22 @@ public: index( _first + n * (n - 1) / 2 ); } + /** + * Getter of the firt location + * @return first indice + */ + unsigned int first() { + return indices.first; + } + + /** + * Getter of the second location + * @return second indice + */ + unsigned int second() { + return indices.second; + } + private: std::pair indices; diff --git a/mo/src/problems/permutation/moShiftNeighbor.h b/mo/src/problems/permutation/moShiftNeighbor.h index 88d48301d..87dfb9265 100644 --- a/mo/src/problems/permutation/moShiftNeighbor.h +++ b/mo/src/problems/permutation/moShiftNeighbor.h @@ -1,114 +1,186 @@ /* - -Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 + + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 -Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau + Sebastien Verel, Arnaud Liefooghe, Jeremie Humeau -This software is governed by the CeCILL license under French law and -abiding by the rules of distribution of free software. You can ue, -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". + This software is governed by the CeCILL license under French law and + abiding by the rules of distribution of free software. You can ue, + 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". -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. + 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 + ParadisEO WebSite : http://paradiseo.gforge.inria.fr + Contact: paradiseo-help@lists.gforge.inria.fr */ #ifndef _moShiftNeighbor_h #define _moShiftNeighbor_h +#include #include /** * Indexed Shift Neighbor + * Other name : insertion operator */ template -class moShiftNeighbor: public moIndexNeighbor +class moShiftNeighbor: public moBackableNeighbor, public moIndexNeighbor { public: - using moIndexNeighbor::key; + using moBackableNeighbor::fitness; + using moIndexNeighbor::key; + using moIndexNeighbor::index; + + /** + * Apply move on a solution regarding a key + * @param _solution the solution to move + */ + virtual void move(EOT & _solution) { + insertion(_solution, indices.first, indices.second); - /** - * Apply move on a solution regarding a key - * @param _sol the solution to move - */ - virtual void move(EOT & _sol) { - unsigned int tmp ; - size=_sol.size(); - translate(key+1); - // keep the first component to change - tmp = _sol[first]; - // shift - if (first < second) { - for (unsigned int i=first; i second*/ - for (unsigned int i=first; i>second; i--) - _sol[i] = _sol[i-1]; - // shift the first component - _sol[second] = tmp; - } - _sol.invalidate(); - } + _solution.invalidate(); + } - /** - * fix two indexes regarding a key - * @param _key the key allowing to compute the two indexes for the shift - */ - void translate(unsigned int _key) { - int step; - int val = _key; - int tmpSize = size * (size-1) / 2; - // moves from left to right - if (val <= tmpSize) { - step = size - 1; - first = 0; - while ((val - step) > 0) { - val = val - step; - step--; - first++; - } - second = first + val + 1; - } - // moves from right to left (equivalent moves are avoided) - else { /* val > tmpSize */ - val = val - tmpSize; - step = size - 2; - second = 0; - while ((val - step) > 0) { - val = val - step; - step--; - second++; - } - first = second + val + 1; - } - } + /** + * apply the correct insertion to restore the solution (use by moFullEvalByModif) + * @param _solution the solution to move back + */ + virtual void moveBack(EOT& _solution) { + if (indices.first < indices.second) + insertion(_solution, indices.second - 1, indices.first); + else + insertion(_solution, indices.second, indices.first + 1); + } - void print() { - std::cout << key << ": [" << first << ", " << second << "] -> " << (*this).fitness() << std::endl; + /** + * Setter + * The "parameters" of the neighbor is a function of key and the current solution + * for example, for variable length solution + * + * @param _solution solution from which the neighborhood is visited + * @param _key index of the IndexNeighbor + */ + virtual void index(EOT & _solution, unsigned int _key) { + index( _key ); + + indices.first = _key % _solution.size() ; + indices.second = _key / _solution.size() ; + + if (indices.first <= indices.second) + indices.second += 2; + + // =============== To kill : + // int step; + // int val = _key; + // int tmpSize = _solution.size() * (_solution.size() - 1) / 2; + + // // moves from left to right + // if (val <= tmpSize) { + // step = _solution.size() - 1; + // indices.first = 0; + // while ((val - step) > 0) { + // val = val - step; + // step--; + // indices.first++; + // } + // indices.second = indices.first + val + 1; + // } + // // moves from right to left (equivalent moves are avoided) + // else { /* val > tmpSize */ + // val = val - tmpSize; + // step = _solution.size() - 2; + // indices.second = 0; + // while ((val - step) > 0) { + // val = val - step; + // step--; + // indices.second++; + // } + // indices.first = indices.second + val + 1; + // } + } + + /** + * Setter to fix the two indexes to swap + * @param _solution solution from which the neighborhood is visited + * @param _first first index + * @param _second second index + */ + void set(EOT & _solution, unsigned int _first, unsigned int _second) { + indices.first = _first; + indices.second = _second; + + // set the index + if (_first < _second) { + index( (_second - 2) * _solution.size() + _first ); + } else { + index( _second * _solution.size() + _first ); } + } + + /** + * Getter of the firt location + * @return first indice + */ + unsigned int first() { + return indices.first; + } + + /** + * Getter of the second location + * @return second indice + */ + unsigned int second() { + return indices.second; + } + + void print() { + std::cout << key << ": [" << indices.first << ", " << indices.second << "] -> " << (*this).fitness() << std::endl; + } private: - unsigned int first; - unsigned int second; - unsigned int size; + std::pair indices; + + /** + * Apply insertion move on a solution regarding a key + * @param _sol the solution to move + * @param _first first position + * @param _second second position + */ + void insertion(EOT & _sol, unsigned int _first, unsigned int _second) { + unsigned int tmp ; + + // keep the first component to change + tmp = _sol[_first]; + // shift + if (_first < _second) { + for (unsigned int i = _first; i < _second - 1; i++) + _sol[i] = _sol[i+1]; + // shift the first component + _sol[_second-1] = tmp; + } + else { /* first > second*/ + for (unsigned int i = _first; i > _second; i--) + _sol[i] = _sol[i-1]; + // shift the first component + _sol[_second] = tmp; + } + } + }; diff --git a/mo/test/CMakeLists.txt b/mo/test/CMakeLists.txt index 1e600f3fc..652b66be3 100644 --- a/mo/test/CMakeLists.txt +++ b/mo/test/CMakeLists.txt @@ -93,7 +93,7 @@ set (TEST_LIST t-moNeutralWalkSampling t-moStatistics t-moIndexedVectorTabuList - t-moRndIndexedVectorTabuList +# t-moRndIndexedVectorTabuList t-moDynSpanCoolingSchedule ) diff --git a/moeo/src/utils/moeoConvertPopToObjectiveVectors.h b/moeo/src/utils/moeoConvertPopToObjectiveVectors.h index 62c5af29f..8eb6e5fb7 100644 --- a/moeo/src/utils/moeoConvertPopToObjectiveVectors.h +++ b/moeo/src/utils/moeoConvertPopToObjectiveVectors.h @@ -55,8 +55,7 @@ class moeoConvertPopToObjectiveVectors : public eoUF < const eoPop < MOEOT >, co */ const std::vector < ObjectiveVector > operator()(const eoPop < MOEOT > _pop) { - std::vector < ObjectiveVector > result; - result.resize(_pop.size()); + std::vector < ObjectiveVector > result(0); for (unsigned int i=0; i<_pop.size(); i++) { result.push_back(_pop[i].objectiveVector()); diff --git a/smp/src/abstractIsland.h b/smp/src/abstractIsland.h index ba8a3f43a..fc4bebe98 100644 --- a/smp/src/abstractIsland.h +++ b/smp/src/abstractIsland.h @@ -74,7 +74,7 @@ public: * Update the island by adding population to send in the imigrants list. * @param _data Population to integrate. */ - virtual void update(eoPop _data) = 0; + virtual bool update(eoPop _data) = 0; /** * Check if the algorithm is stopped. @@ -82,6 +82,11 @@ public: */ virtual bool isStopped(void) const = 0; + /** + * Set the stopped indicator on false + */ + virtual void setRunning(void) = 0; + /** * Receive population by integrate individuals. */ diff --git a/smp/src/bimap.cpp b/smp/src/bimap.cpp index dafd11e19..b20e96d46 100644 --- a/smp/src/bimap.cpp +++ b/smp/src/bimap.cpp @@ -49,9 +49,9 @@ std::map paradiseo::smp::Bimap::getLeft() const template void paradiseo::smp::Bimap::removeFromRight(const A& a) { - for(auto& it : leftAssociation) - if(it->second == a) - leftAssociation.erase(it); + leftAssociation.erase(remove(leftAssociation.begin(), leftAssociation.end(), + [&](std::pair& i) -> bool { return i->second == a; }), + leftAssociation.end()); rightAssociation.erase(a); } @@ -59,9 +59,9 @@ void paradiseo::smp::Bimap::removeFromRight(const A& a) template void paradiseo::smp::Bimap::removeFromLeft(const B& b) { - for(auto& it : rightAssociation) - if(it->second == b) - rightAssociation.erase(it); + rightAssociation.erase(remove(rightAssociation.begin(), rightAssociation.end(), + [&](std::pair& i) -> bool { return i->second == b; }), + rightAssociation.end()); leftAssociation.erase(b); } diff --git a/smp/src/island.cpp b/smp/src/island.cpp index 22ab472cf..ea3e5ea92 100644 --- a/smp/src/island.cpp +++ b/smp/src/island.cpp @@ -67,7 +67,10 @@ void paradiseo::smp::Island::operator()() stopped = true; // Let's wait the end of communications with the island model for(auto& message : sentMessages) - message.join(); + message.wait(); + + // Clear the sentMessages container + sentMessages.clear(); } template