diff --git a/eo/NEWS b/eo/NEWS index 6657f36b8..a90d996d3 100644 --- a/eo/NEWS +++ b/eo/NEWS @@ -1,4 +1,6 @@ * current release: + - added an EOT& parameter to the moCoolingSchedule::update interface method because some cooling schedules need it + - eoMonitor's are no more executed in moCheckpoint::init to prevent access to uninitialized data * release 1.3.1 (2012-07-27) - the eo::mpi modules is no longer dependent from boost::mpi diff --git a/eo/src/eo b/eo/src/eo index 8196e2b14..5057371d3 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -35,6 +35,7 @@ // general purpose #include #include +#include #include #include #include diff --git a/eo/src/eoOptional.h b/eo/src/eoOptional.h new file mode 100644 index 000000000..9143be3cd --- /dev/null +++ b/eo/src/eoOptional.h @@ -0,0 +1,130 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +/* +(c) Thales group, 2013 + + 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: +Lionel Parreaux + +*/ + +/** + +A utility class for wrapping non-const references and use them as default arguments in functions. +This especially is useful for avoiding constructor multiplication. + +For example, this is not valid C++98 code: + +\code +struct MyClass { + MyClass(T& my_T = default_T) + : actual_T(my_T) + { } +private: + T default_T; + T& actual_T; +}; +\endcode + +This is the same code using eoOptional, which is valid: + +\code +struct MyClass { + MyClass(eoOptional my_T = NULL) + : actual_T(my_T.getOr(default_T)) + { } +private: + T default_T; + T& actual_T; +}; +\endcode + +And from the point of view of the user, it is transparent: + +\code +// Three ways of using MyClass: +MyClass mc1; +MyClass mc2(NULL); +T t; +MyClass mc3(t); +\endcode + + +@ingroup Utilities +@{ +*/ + +#ifndef _EOOPTIONAL_H +#define _EOOPTIONAL_H + +#include +#include +//#include + + +template< class T > +class eoOptional { +public: + static const eoOptional null; // = eoOptional(); + + eoOptional (T& init) + : _val(&init) + { } + + // used mainly for converting NULL to this class + eoOptional (T* init) + : _val(init) + { } + + bool hasValue() const + { + return _val != NULL; + } + + T& get () const + { + if (!hasValue()) + throw std::runtime_error("Cannot get a reference from a eoOptional wrapper with no value"); + //throw eoEx; + return *_val; + } + + T& getOr (T& defaultValue) const + { + return hasValue()? *_val: defaultValue; + } + +protected: + eoOptional () + : _val(NULL) + { } + +private: + T* _val; +}; + +template< class T > +const eoOptional eoOptional::null = eoOptional(); + + +#endif // _EOOPTIONAL_H + + +/** @} */ + diff --git a/eo/src/utils/eoFileMonitor.cpp b/eo/src/utils/eoFileMonitor.cpp index 3cc96deb1..4927fe2ab 100644 --- a/eo/src/utils/eoFileMonitor.cpp +++ b/eo/src/utils/eoFileMonitor.cpp @@ -73,16 +73,18 @@ eoMonitor& eoFileMonitor::operator()(void) eoMonitor& eoFileMonitor::operator()(std::ostream& os) { - - iterator it = vec.begin(); - - os << (*it)->getValue(); - - for(++it; it != vec.end(); ++it) + if (vec.size() > 0) { - os << delim.c_str() << (*it)->getValue(); + iterator it = vec.begin(); + + os << (*it)->getValue(); + + for(++it; it != vec.end(); ++it) + { + os << delim.c_str() << (*it)->getValue(); + } } - + os << std::endl; return *this; diff --git a/eo/src/utils/eoGetterUpdater.h b/eo/src/utils/eoGetterUpdater.h new file mode 100644 index 000000000..99d2d8c54 --- /dev/null +++ b/eo/src/utils/eoGetterUpdater.h @@ -0,0 +1,90 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef _eoGetterUpdater_h +#define _eoGetterUpdater_h + +#include + +template class eoCheckPoint; + +/** + eoGetterUpdater is an eoUpdater + TODO + + @ingroup Utilities +*/ +template +class eoGetterUpdater : public eoUpdater, public eoValueParam +{ +public: + using eoValueParam::value; + + virtual std::string className(void) const { return "eoGetterUpdater"; } + + typedef V (T::*MethodType)(); + + // Overload to accept const getter methods; safely casts them to non-const + eoGetterUpdater(T& _instance, V (T::*_method)() const) + //eoGetterUpdater(T& _instance, V (T::*_method)()=&T::value) + //: instance(_instance), method(static_cast(_method)) + //: instance(_instance), method(const_cast(_method)) + : instance(_instance), method((MethodType)_method) + { } + + //eoGetterUpdater(T& _instance, V (T::*_method)()) + eoGetterUpdater(T& _instance, MethodType _method) + //eoGetterUpdater(T& _instance, V (T::*_method)()=&T::value) + : instance(_instance), method(_method) + { } + + virtual void operator()() + { + value() = (instance.*method)(); + } + +private: + T& instance; + V (T::*method)(); +}; + + + +#endif + + + + + + + + + + + + + + + diff --git a/eo/src/utils/eoLogger.cpp b/eo/src/utils/eoLogger.cpp index 1330c5323..10371b0a0 100644 --- a/eo/src/utils/eoLogger.cpp +++ b/eo/src/utils/eoLogger.cpp @@ -37,14 +37,20 @@ Caner Candan #include // used to define EOF #include +#include // std::find #include "eoLogger.h" + +#ifdef USE_SET +typedef std::set::iterator StreamIter; +#else +typedef std::vector::iterator StreamIter; +#endif + + void eoLogger::_init() { - _standard_io_streams[&std::cout] = 1; - _standard_io_streams[&std::clog] = 2; - _standard_io_streams[&std::cerr] = 2; // /!\ If you want to add a level dont forget to add it at the header file in the enumerator Levels @@ -55,10 +61,11 @@ void eoLogger::_init() addLevel("logging", eo::logging); addLevel("debug", eo::debug); addLevel("xdebug", eo::xdebug); + } eoLogger::eoLogger() : - std::ostream(NULL), + std::ostream(NULL), _verbose("quiet", "verbose", "Set the verbose level", 'v'), _printVerboseLevels(false, "print-verbose-levels", "Print verbose levels", 'l'), @@ -66,33 +73,17 @@ eoLogger::eoLogger() : _selectedLevel(eo::progress), _contextLevel(eo::quiet), - _fd(2), - _obuf(_fd, _contextLevel, _selectedLevel) + _obuf(_contextLevel, _selectedLevel) { - std::ostream::init(&_obuf); + std::ostream::init(&_obuf); _init(); } -eoLogger::eoLogger(eo::file file) : - std::ostream(NULL), - - _verbose("quiet", "verbose", "Set the verbose level", 'v'), - _printVerboseLevels(false, "print-verbose-levels", "Print verbose levels", 'l'), - _output("", "output", "Redirect a standard output to a file", 'o'), - - _selectedLevel(eo::progress), - _contextLevel(eo::quiet), - _fd(2), - _obuf(_fd, _contextLevel, _selectedLevel) -{ - std::ostream::init(&_obuf); - _init(); - *this << file; -} - eoLogger::~eoLogger() { - if (_fd > 2) { ::close(_fd); } + if (_obuf._ownedFileStream != NULL) { + delete _obuf._ownedFileStream; + } } void eoLogger::_createParameters( eoParser& parser ) @@ -110,19 +101,21 @@ void eoLogger::_createParameters( eoParser& parser ) //------------------------------------------------------------------ - // we're gonna redirect the log to the given filename if -o is used. + // we redirect the log to the given filename if -o is used. //------------------------------------------------------------------ if ( ! _output.value().empty() ) { - eo::log << eo::file( _output.value() ); + redirect(_output.value()); } + + //------------------------------------------------------------------ //------------------------------------------------------------------ - // we're gonna print the list of levels if -l parameter is used. + // we print the list of levels if -l parameter is used. //------------------------------------------------------------------ if ( _printVerboseLevels.value() ) @@ -163,12 +156,6 @@ eoLogger& operator<<(eoLogger& l, const eo::Levels lvl) return l; } -eoLogger& operator<<(eoLogger& l, eo::file f) -{ - l._fd = ::open(f._f.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644); - return l; -} - eoLogger& operator<<(eoLogger& l, eo::setlevel v) { l._selectedLevel = (v._lvl < 0 ? l._levels[v._v] : v._lvl); @@ -177,37 +164,106 @@ eoLogger& operator<<(eoLogger& l, eo::setlevel v) eoLogger& operator<<(eoLogger& l, std::ostream& os) { - if (l._standard_io_streams.find(&os) != l._standard_io_streams.end()) - { - l._fd = l._standard_io_streams[&os]; - } +#warning deprecated + l.addRedirect(os); return l; } -eoLogger::outbuf::outbuf(const int& fd, - const eo::Levels& contexlvl, +void eoLogger::redirect(std::ostream& os) +{ + doRedirect(&os); +} + +void eoLogger::doRedirect(std::ostream* os) +{ + if (_obuf._ownedFileStream != NULL) { + delete _obuf._ownedFileStream; + _obuf._ownedFileStream = NULL; + } + _obuf._outStreams.clear(); + if (os != NULL) + #ifdef USE_SET + _obuf._outStreams.insert(os); + #else + _obuf._outStreams.push_back(os); + #endif +} + +void eoLogger::addRedirect(std::ostream& os) +{ + bool already_there = tryRemoveRedirect(&os); +#ifdef USE_SET + _obuf._outStreams.insert(&os); +#else + _obuf._outStreams.push_back(&os); +#endif + if (already_there) + eo::log << eo::warnings << "Cannot redirect the logger to a stream it is already redirected to." << std::endl; +} + +void eoLogger::removeRedirect(std::ostream& os) +{ + if (!tryRemoveRedirect(&os)) + eo::log << eo::warnings << "Cannot remove from the logger a stream it was not redirected to."; +} + +bool eoLogger::tryRemoveRedirect(std::ostream* os) +{ + StreamIter it = find(_obuf._outStreams.begin(), _obuf._outStreams.end(), os); + if (it == _obuf._outStreams.end()) + return false; + _obuf._outStreams.erase(it); + return true; +} + +void eoLogger::redirect(const char * filename) +{ + std::ofstream * os; + if (filename == NULL) { + os = NULL; + } else { + os = new std::ofstream(filename); + } + doRedirect(os); + _obuf._ownedFileStream = os; +} + +void eoLogger::redirect(const std::string& filename) +{ + redirect(filename.c_str()); +} + + +eoLogger::outbuf::outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl) - : _fd(fd), _contextLevel(contexlvl), _selectedLevel(selectedlvl) -{} + : +#ifndef USE_SET + _outStreams(1, &std::cout), +#endif + _ownedFileStream(NULL), _contextLevel(contexlvl), _selectedLevel(selectedlvl) +{ +#ifdef USE_SET + _outStreams.insert(&std::cout); +#endif +} int eoLogger::outbuf::overflow(int_type c) { if (_selectedLevel >= _contextLevel) - { - if (_fd >= 0 && c != EOF) - { - ::write(_fd, &c, 1); - } - } + { + for (StreamIter it = _outStreams.begin(); it != _outStreams.end(); it++) + { + if (c != EOF) + { + (**it) << (char) c; + } + } + } return c; } namespace eo { - file::file(const std::string f) - : _f(f) - {} - setlevel::setlevel(const std::string v) : _v(v), _lvl((Levels)-1) {} diff --git a/eo/src/utils/eoLogger.h b/eo/src/utils/eoLogger.h index 9ac1c2115..98ba09660 100644 --- a/eo/src/utils/eoLogger.h +++ b/eo/src/utils/eoLogger.h @@ -1,6 +1,7 @@ // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- /* + (c) Thales group, 2010 This library is free software; you can redistribute it and/or @@ -30,56 +31,7 @@ Caner Candan Global logger for EO. - Here's an example explaning how to use eoLogger: -\code - #include - - int main(int ac, char** av) - { - // We are declaring the usual eoParser class - eoParser parser(ac, av); - - // This call is important to allow -v parameter to change user level. - make_verbose(parser); - - // At this time we are switching to warning message and messages - // which are going to follow it are going to be warnings message too. - // These messages can be displayed only if the user level (sets with - // eo::setlevel function) is set to eo::warnings. - eo::log << eo::warnings; - - // With the following eo::file function we are defining that - // all future logs are going to this new file resource which is - // test.txt - eo::log << eo::file("test.txt") << "In FILE" << std::endl; - - // Now we are changing again the resources destination to cout which - // is the standard output. - eo::log << std::cout << "In COUT" << std::endl; - - // Here are 2 differents examples of how to set the errors user level - // in using either a string or an identifier. - eo::log << eo::setlevel("errors"); - eo::log << eo::setlevel(eo::errors); - - // Now we are writting a message, that will be displayed only if we are above the "quiet" level - eo::log << eo::quiet << "1) Must be in quiet mode to see that" << std::endl; - - // And so on... - eo::log << eo::setlevel(eo::warnings) << eo::warnings << "2) Must be in warnings mode to see that" << std::endl; - - eo::log << eo::setlevel(eo::logging); - - eo::log << eo::errors; - eo::log << "3) Must be in errors mode to see that"; - eo::log << std::endl; - - eo::log << eo::debug << 4 << ')' - << " Must be in debug mode to see that\n"; - - return 0; - } -\endcode + For an example explaning how to use eoLogger, please refer to paradiseo/eo/test/t-eoLogger.cpp @{ */ @@ -91,10 +43,23 @@ Caner Candan #include #include #include +#include #include "eoObject.h" #include "eoParser.h" +#define USE_SET // defines if a set is to be used instead of a vector for storing streams the logger is redirected to +#undef USE_SET +/* expriments have shown that here a vector is by far faster than a set even if O(n), + * because it needs less dynamic allocations, uses less memory and less instructions + */ + + +#ifdef USE_SET +#include +#endif + + namespace eo { /** @@ -110,16 +75,6 @@ namespace eo debug, xdebug}; - /** - * file - * this structure combined with the friend operator<< below is an easy way to select a file as output. - */ - struct file - { - explicit file(const std::string f); - const std::string _f; - }; - /** * setlevel * this structure combined with the friend operator<< below is an easy way to set a verbose level. @@ -146,7 +101,7 @@ public: eoLogger(); //! overidded ctor in order to instanciate a logger with a file define in parameter - eoLogger(eo::file file); + //eoLogger(eo::file file); //! dtor ~eoLogger(); @@ -181,6 +136,12 @@ private: //! used by the set of ctors to initiate some useful variables void _init(); + //! helper function regrouping redirection operations; takes a pointer because can be given NULL + void doRedirect(std::ostream*); + + //! helper function searching for a stream and removing it, returning true if successful, false otherwise + bool tryRemoveRedirect(std::ostream*); + private: /** * outbuf @@ -189,11 +150,19 @@ private: class outbuf : public std::streambuf { public: - outbuf(const int& fd, const eo::Levels& contexlvl, const eo::Levels& selectedlvl); + outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl); + //std::ostream * _outStream; + + #ifdef USE_SET + std::set _outStreams; + #else + std::vector _outStreams; + #endif + + std::ofstream * _ownedFileStream; protected: virtual int overflow(int_type c); private: - const int& _fd; const eo::Levels& _contextLevel; const eo::Levels& _selectedLevel; }; @@ -211,12 +180,6 @@ public: //! in order to use stream style to define the context verbose level where the following logs will be saved friend eoLogger& operator<<(eoLogger&, const eo::Levels); - /** - * operator<< used there to set a filename through the class file. - */ - //! in order to use stream style to define a file to dump instead the standart output - friend eoLogger& operator<<(eoLogger&, eo::file); - /** * operator<< used there to set a verbose level through the class setlevel. */ @@ -224,12 +187,39 @@ public: friend eoLogger& operator<<(eoLogger&, eo::setlevel); /** - * operator<< used there to be able to use std::cout to say that we wish to redirect back the buffer to a standard output. + * DEPRECATED: Use instead the redirect or addRedirect method; has the same effect as addRedirect */ - //! in order to use stream style to go back to a standart output defined by STL - //! and to get retro-compatibility friend eoLogger& operator<<(eoLogger&, std::ostream&); + /** + * Redirects the logger to a given output stream. + * Closing the stream and returning its memory is at the charge of the caller, + * but should not be done while the log is still redirected to it. + * This resets all previous redirections set up with redirect and add_redirect. + */ + void redirect(std::ostream&); + + /** + * Adds a redirection from the logger to a given output stream. + * Closing the stream and returning its memory is at the charge of the caller, + * but should not be done while the log is still redirected to it. + * This does not reset previous redirections, which remain active. + */ + void addRedirect(std::ostream&); + + /** + * Removes a redirection from the logger to the given output stream. + * This only resets the redirection to the stream passed in argument. + */ + void removeRedirect(std::ostream&); + + /** + * Redirects the logger to a file using a filename. + * Closing the file will be done automatically when the logger is redirected again or destroyed. + */ + void redirect(const char * filename); + void redirect(const std::string& filename); + private: friend void make_verbose(eoParser&); @@ -244,13 +234,7 @@ private: eo::Levels _contextLevel; /** - * _fd in storing the file descriptor at this place we can disable easily the buffer in - * changing the value at -1. It is used by operator <<. - */ - int _fd; - - /** - * _obuf std::ostream mandates to use a buffer. _obuf is a outbuf inheriting of std::streambuf. + * _obuf std::ostream mandates to use a buffer. _obuf is a outbuf inheriting from std::streambuf. */ outbuf _obuf; diff --git a/eo/src/utils/eoMonitor.h b/eo/src/utils/eoMonitor.h index 1c92e9c00..d234921c4 100644 --- a/eo/src/utils/eoMonitor.h +++ b/eo/src/utils/eoMonitor.h @@ -78,3 +78,4 @@ protected : }; #endif + diff --git a/eo/src/utils/eoParam.h b/eo/src/utils/eoParam.h index 948092c93..1c0937528 100644 --- a/eo/src/utils/eoParam.h +++ b/eo/src/utils/eoParam.h @@ -224,7 +224,9 @@ public : void setValue(const std::string& _value) { std::istringstream is(_value); - is >> repValue; + bool read = (is >> repValue); + if (!read) + throw std::runtime_error("Could not read value passed in eoValueParam::setValue"); } protected: diff --git a/eo/src/utils/eoUpdater.h b/eo/src/utils/eoUpdater.h index 072b9a9bb..e86225950 100644 --- a/eo/src/utils/eoUpdater.h +++ b/eo/src/utils/eoUpdater.h @@ -50,6 +50,29 @@ public: eoUpdater& addTo(eoCheckPoint& cp) { cp.add(*this); return *this; } }; +/** + an eoUpdater that simply calls a function with no arguments + + @ingroup Utilities +*/ +class eoFunctionCaller : public eoUpdater +{public : + /** Default Ctor - requires a pointer to the function to call */ + eoFunctionCaller(void (*_fct)()) + : fct(_fct) + { } + + /** Simply increments */ + virtual void operator()() + { + (*fct)(); + } + + virtual std::string className(void) const { return "eoFunctionCaller"; } +private: + void (*fct)(); +}; + /** an eoUpdater that simply increments a counter diff --git a/eo/test/CMakeLists.txt b/eo/test/CMakeLists.txt index 15fd22464..e283ab958 100644 --- a/eo/test/CMakeLists.txt +++ b/eo/test/CMakeLists.txt @@ -69,6 +69,7 @@ set (TEST_LIST #t-openmp # does not work anymore since functions used in this test were removed from EO #t-eoDualFitness t-eoParser + t-eoOptional ) diff --git a/eo/test/t-eoLogger.cpp b/eo/test/t-eoLogger.cpp index 198a88720..0406cb6b1 100644 --- a/eo/test/t-eoLogger.cpp +++ b/eo/test/t-eoLogger.cpp @@ -3,30 +3,78 @@ //----------------------------------------------------------------------------- #include +//#include +#include +#include +#include +#include //----------------------------------------------------------------------------- +static void test(); + int main(int ac, char** av) { eoParser parser(ac, av); if (parser.userNeedsHelp()) - { - parser.printHelp(std::cout); - exit(1); - } + { + parser.printHelp(std::cout); + exit(1); + } make_help(parser); make_verbose(parser); + test(); + + return 0; +} + +static void test() +{ eo::log << eo::setlevel(eo::debug); eo::log << eo::warnings; eo::log << "We are writing on the default output stream" << std::endl; - eo::log << eo::file("test.txt") << "In FILE" << std::endl; - eo::log << std::cout << "on COUT" << std::endl; + { + eo::log.redirect("logtest.txt"); + eo::log << "In FILE" << std::endl; + std::ofstream ofs("logtest2.txt"); // closed and destroyed at the en of the scope + eo::log.addRedirect(ofs); + eo::log << "In FILE 2" << std::endl; + eo::log.removeRedirect(ofs); // must be removed because the associated stream is closed + } + + std::ifstream ifs("logtest2.txt"); // stream to logtest2.txt is closed, we can start reading + std::string line; + assert(std::getline(ifs, line)); + assert(line == "In FILE 2"); + assert(!std::getline(ifs, line)); + + std::ostringstream oss; + eo::log.addRedirect(oss); + eo::log << "In STRINGSTREAM"; + + std::cout << "Content of ostringstream: " << oss.str() << std::endl; + assert(oss.str() == "In STRINGSTREAM"); + + eo::log.redirect(std::cout); // removes all previously redirected streams; closes the file logtest.txt + eo::log << "on COUT" << std::endl; + + + ifs.close(); + ifs.open("logtest.txt"); + assert(std::getline(ifs, line)); + assert(line == "In FILE"); + assert(std::getline(ifs, line)); + assert(line == "In FILE 2"); + assert(std::getline(ifs, line)); + assert(line == "In STRINGSTREAM"); + assert(!std::getline(ifs, line)); + eo::log << eo::setlevel("errors"); eo::log << eo::setlevel(eo::errors); @@ -42,9 +90,8 @@ int main(int ac, char** av) eo::log << std::endl; eo::log << eo::debug << 4 << ')' - << "4) in debug mode\n"; - - return 0; + << "4) in debug mode\n"; + } //----------------------------------------------------------------------------- diff --git a/eo/test/t-eoOptional.cpp b/eo/test/t-eoOptional.cpp new file mode 100644 index 000000000..5b4a9fbc2 --- /dev/null +++ b/eo/test/t-eoOptional.cpp @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// t-eoOptional.cpp +//----------------------------------------------------------------------------- + +#include "eoOptional.h" + +//----------------------------------------------------------------------------- + +typedef int T; + +struct MyClass { + MyClass(eoOptional my_T = NULL) + : default_T(42), actual_T(my_T.getOr(default_T)) + { + std::cout << "Value " << actual_T << " was used for construction" << std::endl; + } +private: + T default_T; + T& actual_T; +}; + +int main(int ac, char** av) +{ + // Three ways of using MyClass: + MyClass mc1; + MyClass mc2(NULL); + T t(666); + MyClass mc3(t); +} + diff --git a/mo/src/algo/moLocalSearch.h b/mo/src/algo/moLocalSearch.h index bf77a8f3f..ca2f04c6e 100644 --- a/mo/src/algo/moLocalSearch.h +++ b/mo/src/algo/moLocalSearch.h @@ -47,99 +47,109 @@ template class moLocalSearch: public eoMonOp { public: - typedef moNeighborhood Neighborhood; - typedef moNeighborhoodExplorer NeighborhoodExplorer; - typedef typename Neighbor::EOT EOT; + typedef moNeighborhood Neighborhood; + typedef moNeighborhoodExplorer NeighborhoodExplorer; + typedef typename Neighbor::EOT EOT; - /** - * Constructor of a moLocalSearch - * @param _searchExpl a neighborhood explorer - * @param _cont an external continuator (can be a checkpoint!) - * @param _fullEval a full evaluation function - */ - moLocalSearch(NeighborhoodExplorer& _searchExpl, - moContinuator & _cont, eoEvalFunc& _fullEval) : - searchExplorer(_searchExpl), cont(&_cont), fullEval(_fullEval) { - } - ; + /** + * Constructor of a moLocalSearch + * @param _searchExpl a neighborhood explorer + * @param _cont an external continuator (can be a checkpoint!) + * @param _fullEval a full evaluation function + */ + moLocalSearch(NeighborhoodExplorer& _searchExpl, moContinuator & _cont, eoEvalFunc& _fullEval) + : searchExplorer(_searchExpl), cont(&_cont), fullEval(_fullEval), currentSolutionFitness(0) + { } - /** - * Run the local search on a solution - * @param _solution the related solution - */ - virtual bool operator()(EOT & _solution) { + /** + * Run the local search on a solution + * @param _solution the related solution + */ + virtual bool operator()(EOT & _solution) { - if (_solution.invalid()) - fullEval(_solution); + if (_solution.invalid()) + fullEval(_solution); + + // initialization of the parameter of the search (for example fill empty the tabu list) + searchExplorer.initParam(_solution); + + // initialization of the external continuator (for example the time, or the number of generations) + cont->init(_solution); + + bool b; + do { + currentSolutionFitness = _solution.fitness(); + //std::cout << currentSolutionFitness << std::endl; + //std::cin.get(); + + // explore the neighborhood of the solution + searchExplorer(_solution); + // if a solution in the neighborhood can be accepted + if (searchExplorer.accept(_solution)) { + searchExplorer.move(_solution); + searchExplorer.moveApplied(true); + } else + searchExplorer.moveApplied(false); - // initialization of the parameter of the search (for example fill empty the tabu list) - searchExplorer.initParam(_solution); + // update the parameter of the search (for ex. Temperature of the SA) + searchExplorer.updateParam(_solution); - // initialization of the external continuator (for example the time, or the number of generations) - cont->init(_solution); + b = (*cont)(_solution); + } while (b && searchExplorer.isContinue(_solution)); - bool b; - do { - // explore the neighborhood of the solution - searchExplorer(_solution); - // if a solution in the neighborhood can be accepted - if (searchExplorer.accept(_solution)) { - searchExplorer.move(_solution); - searchExplorer.moveApplied(true); - } else - searchExplorer.moveApplied(false); + searchExplorer.terminate(_solution); - // update the parameter of the search (for ex. Temperature of the SA) - searchExplorer.updateParam(_solution); + cont->lastCall(_solution); - b = (*cont)(_solution); - } while (b && searchExplorer.isContinue(_solution)); + return true; + } - searchExplorer.terminate(_solution); + /** + * Set an external continuator + * @param _cont the external continuator + */ + void setContinuator(moContinuator & _cont) { + cont = &_cont; + } - cont->lastCall(_solution); + /** + * external continuator object + * + * @overload + * @return the external continuator + */ + moContinuator* getContinuator() const { + return cont; + } - return true; - } - ; - - /** - * Set an external continuator - * @param _cont the external continuator - */ - void setContinuator(moContinuator & _cont) { - cont = &_cont; - } - - /** - * external continuator object - * - * @overload - * @return the external continuator - */ - moContinuator* getContinuator() const { - return cont; - } - - /** - * to get the neighborhood explorer - * - * @overload - * @return the neighborhood explorer - */ - moNeighborhoodExplorer & getNeighborhoodExplorer() const { - return searchExplorer; - } + /** + * to get the neighborhood explorer + * + * @overload + * @return the neighborhood explorer + */ + moNeighborhoodExplorer & getNeighborhoodExplorer() const { + return searchExplorer; + } + + // TODO doc + double getCurrentSolutionFitness() const { + return currentSolutionFitness; + } protected: - // make the exploration of the neighborhood according to a local search heuristic - moNeighborhoodExplorer& searchExplorer; + // make the exploration of the neighborhood according to a local search heuristic + moNeighborhoodExplorer& searchExplorer; - // external continuator - moContinuator * cont; + // external continuator + moContinuator * cont; - //full evaluation function - eoEvalFunc& fullEval; + //full evaluation function + eoEvalFunc& fullEval; + +private: + double currentSolutionFitness; + }; #endif diff --git a/mo/src/algo/moMetropolisHasting.h b/mo/src/algo/moMetropolisHastings.h similarity index 80% rename from mo/src/algo/moMetropolisHasting.h rename to mo/src/algo/moMetropolisHastings.h index 5b4292459..069451e9b 100644 --- a/mo/src/algo/moMetropolisHasting.h +++ b/mo/src/algo/moMetropolisHastings.h @@ -2,7 +2,7 @@ Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 -Sebastien Verel, Arnaud Liefooghe, Jeremie Humeau +Sebastien Verel, Arnaud Liefooghe, Jeremie Humeau, Lionel Parreaux This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software. You can ue, @@ -27,11 +27,12 @@ ParadisEO WebSite : http://paradiseo.gforge.inria.fr Contact: paradiseo-help@lists.gforge.inria.fr */ -#ifndef _moMetropolisHasting_h -#define _moMetropolisHasting_h +#ifndef _moMetropolisHastings_h +#define _moMetropolisHastings_h #include -#include +#include +#include #include #include #include @@ -50,7 +51,7 @@ Contact: paradiseo-help@lists.gforge.inria.fr * the algorithm stops when the number of iterations is too large */ template -class moMetropolisHasting: public moLocalSearch +class moMetropolisHastings: public moLocalSearch { public: typedef typename Neighbor::EOT EOT; @@ -63,7 +64,7 @@ public: * @param _eval neighbor's evaluation function * @param _nbStep maximum step to do */ - moMetropolisHasting(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, unsigned int _nbStep): + moMetropolisHastings(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, unsigned int _nbStep): moLocalSearch(explorer, trueCont, _fullEval), explorer(_neighborhood, _eval, defaultNeighborComp, defaultSolNeighborComp, _nbStep) {} @@ -76,7 +77,7 @@ public: * @param _nbStep maximum step to do * @param _cont an external continuator */ - moMetropolisHasting(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, unsigned int _nbStep, moContinuator& _cont): + moMetropolisHastings(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, unsigned int _nbStep, moContinuator& _cont): moLocalSearch(explorer, _cont, _fullEval), explorer(_neighborhood, _eval, defaultNeighborComp, defaultSolNeighborComp, _nbStep) {} @@ -91,7 +92,7 @@ public: * @param _compN a neighbor vs neighbor comparator * @param _compSN a solution vs neighbor comparator */ - moMetropolisHasting(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, unsigned int _nbStep, moContinuator& _cont, moNeighborComparator& _compN, moSolNeighborComparator& _compSN): + moMetropolisHastings(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, unsigned int _nbStep, moContinuator& _cont, moNeighborComparator& _compN, moSolNeighborComparator& _compSN): moLocalSearch(explorer, _cont, _fullEval), explorer(_neighborhood, _eval, _compN, _compSN, _nbStep) {} @@ -104,7 +105,8 @@ private: // compare the fitness values of the solution and the neighbor moSolNeighborComparator defaultSolNeighborComp; // MetropolisHasting explorer - moMetropolisHastingExplorer explorer; + //moMetropolisHastingsExplorer explorer; + moSimpleMetropolisHastingsExplorer explorer; }; #endif diff --git a/mo/src/algo/moSA.h b/mo/src/algo/moSA.h index c126f31fc..4cf1b3fba 100644 --- a/mo/src/algo/moSA.h +++ b/mo/src/algo/moSA.h @@ -2,7 +2,7 @@ Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 -Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau +Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau, Lionel Parreaux This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software. You can ue, @@ -31,12 +31,13 @@ Contact: paradiseo-help@lists.gforge.inria.fr #define _moSA_h #include -#include +#include #include #include #include #include #include +#include /** * Simulated Annealing @@ -60,38 +61,64 @@ public: * @param _span number of iteration with equal temperature for cooling schedule (default = 100) * @param _finalT final temperature, threshold of the stopping criteria for cooling schedule (default = 0.01) */ - moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, double _initT=10, double _alpha=0.9, unsigned _span=100, double _finalT=0.01): - moLocalSearch(explorer, trueCont, _fullEval), - defaultCool(_initT, _alpha, _span, _finalT), - explorer(_neighborhood, _eval, defaultSolNeighborComp, defaultCool) - {} + /*moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, double _initT=10, double _alpha=0.9, unsigned _span=100, double _finalT=0.01) + : defaultCool(_initT, _alpha, _span, _finalT), + explorer(_neighborhood, _eval, defaultSolNeighborComp, defaultCool), + moLocalSearch(explorer, defaultContinuator, _fullEval) + { }*/ + moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, double _initT=10, double _alpha=0.9, unsigned _span=100, double _finalT=0.01) + : moLocalSearch ( + *(explorer_ptr = defaultExplorer = new moSAExplorer(_neighborhood, _eval, /*NULL,*/ *(defaultCool = new moSimpleCoolingSchedule(_initT, _alpha, _span, _finalT)), NULL)), + *(defaultContinuator = new moTrueContinuator()), + _fullEval ), + explorer(*explorer_ptr), + //defaultCool(), + defaultEval(NULL) // removed in C++11 with unique_ptr + //defaultSolNeighborComp(new moSolNeighborComparator()) + //explorer(_neighborhood, _eval, *defaultSolNeighborComp, *defaultCool) + { } - /** - * Simple constructor for a simulated annealing - * @param _neighborhood the neighborhood - * @param _fullEval the full evaluation function - * @param _eval neighbor's evaluation function - * @param _cool a cooling schedule - */ - moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, moCoolingSchedule& _cool): - moLocalSearch(explorer, trueCont, _fullEval), - defaultCool(0, 0, 0, 0), - explorer(_neighborhood, _eval, defaultSolNeighborComp, _cool) - {} - - /** - * General constructor for a simulated annealing - * @param _neighborhood the neighborhood - * @param _fullEval the full evaluation function - * @param _eval neighbor's evaluation function - * @param _cool a cooling schedule - * @param _cont an external continuator - */ - moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, moCoolingSchedule& _cool, moContinuator& _cont): - moLocalSearch(explorer, _cont, _fullEval), - defaultCool(0, 0, 0, 0), - explorer(_neighborhood, _eval, defaultSolNeighborComp, _cool) - {} +// /** +// * Simple constructor for a simulated annealing +// * @param _neighborhood the neighborhood +// * @param _fullEval the full evaluation function +// * @param _eval neighbor's evaluation function +// * @param _cool a cooling schedule +// */ +// moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, moCoolingSchedule& _cool): +// moLocalSearch(explorer, defaultContinuator, _fullEval), +// defaultCool(0, 0, 0, 0), +// explorer(_neighborhood, _eval, defaultSolNeighborComp, _cool) +// {} +// +// /** +// * General constructor for a simulated annealing +// * @param _neighborhood the neighborhood +// * @param _fullEval the full evaluation function +// * @param _eval neighbor's evaluation function +// * @param _cool a cooling schedule +// * @param _cont an external continuator +// */ +// moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, moCoolingSchedule& _cool, moContinuator& _cont): +// moLocalSearch(explorer, _cont, _fullEval), +// defaultCool(0, 0, 0, 0), +// explorer(_neighborhood, _eval, defaultSolNeighborComp, _cool) +// {} +// +// /** +// * General constructor for a simulated annealing +// * @param _neighborhood the neighborhood +// * @param _fullEval the full evaluation function +// * @param _eval neighbor's evaluation function +// * @param _cool a cooling schedule +// * @param _comp a solution vs neighbor comparator +// * @param _cont an external continuator +// */ +// moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, moCoolingSchedule& _cool, moSolNeighborComparator& _comp, moContinuator& _cont): +// moLocalSearch(explorer, _cont, _fullEval), +// defaultCool(0, 0, 0, 0), +// explorer(_neighborhood, _eval, _comp, _cool) +// {} /** * General constructor for a simulated annealing @@ -102,19 +129,107 @@ public: * @param _comp a solution vs neighbor comparator * @param _cont an external continuator */ - moSA(Neighborhood& _neighborhood, eoEvalFunc& _fullEval, moEval& _eval, moCoolingSchedule& _cool, moSolNeighborComparator& _comp, moContinuator& _cont): - moLocalSearch(explorer, _cont, _fullEval), - defaultCool(0, 0, 0, 0), - explorer(_neighborhood, _eval, _comp, _cool) - {} - - + moSA ( + Neighborhood& _neighborhood, + eoEvalFunc& _fullEval, + moCoolingSchedule& _cool, + eoOptional< moEval > _eval = NULL, + eoOptional< moContinuator > _cont = NULL, + eoOptional< moSolNeighborComparator > _comp = NULL + ) + /*: moLocalSearch(explorer, _cont.hasValue()? _cont.get(): *(defaultContinuator = new moTrueContinuator()), _fullEval), + defaultCool(NULL), // removed in C++11 with unique_ptr + defaultEval(NULL), // removed in C++11 with unique_ptr + defaultSolNeighborComp(NULL), // removed in C++11 with unique_ptr + defaultContinuator(NULL), // removed in C++11 with unique_ptr + explorer ( + _neighborhood, + _eval.hasValue()? _eval.get(): *(defaultEval = new moFullEvalByCopy(_fullEval)), + // C++11: _eval.hasValue()? _eval.get(): defaultEval = new moFullEvalByCopy(), + _comp.hasValue()? _comp.get(): *(defaultSolNeighborComp = new moSolNeighborComparator()), + _cool ) + { }*/ + : moLocalSearch ( + *(explorer_ptr = defaultExplorer = new moSAExplorer ( + _neighborhood, + //_eval, //_eval.hasValue()? _eval.get(): *(defaultEval = new moFullEvalByCopy(_fullEval)), + _eval.hasValue()? defaultEval = NULL, _eval.get(): *(defaultEval = new moFullEvalByCopy(_fullEval)), + // C++11: _eval.hasValue()? _eval.get(): defaultEval = new moFullEvalByCopy(), + //_comp, //_comp.hasValue()? _comp.get(): *(defaultSolNeighborComp = new moSolNeighborComparator()), + //_cool ), + _cool, + _comp )), + // ), + _cont.hasValue()? defaultContinuator = NULL, _cont.get(): *(defaultContinuator = new moTrueContinuator()), + _fullEval ), + explorer(*explorer_ptr), + defaultCool(NULL) // removed in C++11 with unique_ptr + //defaultEval(NULL), // removed in C++11 with unique_ptr + //defaultContinuator(NULL) // removed in C++11 with unique_ptr + //defaultSolNeighborComp(NULL) // removed in C++11 with unique_ptr + { } + + + moSA ( + eoEvalFunc& _fullEval, + moSAExplorer& _explorer, + eoOptional< moContinuator > _cont = NULL + ) + : moLocalSearch ( + *(explorer_ptr = &_explorer), + _cont.hasValue()? defaultContinuator = NULL, _cont.get(): *(defaultContinuator = new moTrueContinuator()), _fullEval ), + defaultEval(NULL), // removed in C++11 with unique_ptr + defaultExplorer(NULL), // removed in C++11 with unique_ptr + explorer(*explorer_ptr), + defaultCool(NULL) // removed in C++11 with unique_ptr + //defaultEval(NULL) // removed in C++11 with unique_ptr + //defaultContinuator(NULL) // removed in C++11 with unique_ptr + //defaultSolNeighborComp(NULL) // removed in C++11 with unique_ptr + { } + + /* + moSA ( + eoEvalFunc& _fullEval, + moSAExplorer& _explorer, + moContinuator _cont + ) + : moLocalSearch ( + *(explorer = &_explorer), + _cont, _fullEval ), + defaultExplorer(NULL), // removed in C++11 with unique_ptr + defaultCool(NULL), // removed in C++11 with unique_ptr + //defaultEval(NULL), // removed in C++11 with unique_ptr + defaultContinuator(NULL) // removed in C++11 with unique_ptr + //defaultSolNeighborComp(NULL) // removed in C++11 with unique_ptr + { } + */ + + + + + + virtual ~moSA () + { + // Note: using unique_ptr would allow us to remove this explicit destructor, but they were only introduced in C++11 + if (defaultContinuator != NULL) + delete defaultContinuator; + if (defaultExplorer != NULL) + delete defaultExplorer; + if (defaultEval != NULL) + delete defaultEval; + } private: - moTrueContinuator trueCont; - moSimpleCoolingSchedule defaultCool; - moSolNeighborComparator defaultSolNeighborComp; - moSAexplorer explorer; + moFullEvalByCopy* defaultEval; + moSAExplorer* defaultExplorer; + moSAExplorer* explorer_ptr; // Not NULL + moSAExplorer& explorer; + moSimpleCoolingSchedule* defaultCool; // C++11: const std::unique_ptr> + //moFullEvalByCopy* defaultEval; + moTrueContinuator* defaultContinuator; + //moSolNeighborComparator* defaultSolNeighborComp; }; #endif + + diff --git a/mo/src/continuator/moCheckpoint.h b/mo/src/continuator/moCheckpoint.h index 37b5cd610..950b96fa0 100644 --- a/mo/src/continuator/moCheckpoint.h +++ b/mo/src/continuator/moCheckpoint.h @@ -107,14 +107,23 @@ public : virtual void init(EOT& _sol) { for (unsigned i = 0; i < stats.size(); ++i) stats[i]->init(_sol); - counter=1; - + counter = 1; + for (unsigned i = 0; i < moupdaters.size(); ++i) moupdaters[i]->init(); - + + //for (unsigned i = 0; i < updaters.size(); ++i) + // updaters[i]->init(); + + /* + * Removed because there was no reason for it to be done here + * It caused premature monitoring of eoParams with uninitialized values + * (eoUpdater's don't have a init function) + * for (unsigned int i = 0; i < monitors.size(); ++i) (*monitors[i])(); - + */ + for (unsigned i = 0; i < continuators.size(); ++i) continuators[i]->init(_sol); } diff --git a/mo/src/continuator/moCounterMonitorSaver.h b/mo/src/continuator/moCounterMonitorSaver.h index f57e05d2d..6ac5a7062 100644 --- a/mo/src/continuator/moCounterMonitorSaver.h +++ b/mo/src/continuator/moCounterMonitorSaver.h @@ -52,7 +52,11 @@ public : moCounterMonitorSaver(unsigned _interval, eoMonitor& _mon) : interval(_interval), counter(0) { monitors.push_back(&_mon); } - + + moCounterMonitorSaver(unsigned _interval) + : interval(_interval), counter(0) + { } + /** * call monitors if interval is reach by a counter */ diff --git a/mo/src/continuator/moFitnessMomentsStat.h b/mo/src/continuator/moFitnessMomentsStat.h new file mode 100644 index 000000000..0aaa5ad48 --- /dev/null +++ b/mo/src/continuator/moFitnessMomentsStat.h @@ -0,0 +1,110 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef moFitnessMomentsStat_h +#define moFitnessMomentsStat_h + +#include +#include + +/** + * Statistic that saves the standard deviation of the fitness of the solutions during the search + */ +template +//class moFitnessMomentsStat : public moStat > +class moFitnessMomentsStat : public moStat > +{ +public : + typedef typename EOT::Fitness Fitness; + //typedef std::pair Pair; + typedef std::pair Pair; + using moStat::value; + + /** + * Default Constructor + * @param _reInitSol when true the best so far is reinitialized + */ + moFitnessMomentsStat(bool _reInitSol = true) + : moStat(Pair(Fitness(), 0.0), "moments (average and stdev)"), + reInitSol(_reInitSol), firstTime(true), + nbSolutionsEncountered(0), currentAvg(0), currentVar(0) + { } + + /** + * Initialization of the best solution on the first one + * @param _sol the first solution + */ + virtual void init(EOT & _sol) { + if (reInitSol || firstTime) + { + value() = Pair(0.0,0.0); + nbSolutionsEncountered = currentAvg = currentVar = 0; + firstTime = false; + } + /*else if (firstTime) + { + value() = 0.0; + firstTime = false; + }*/ + operator()(_sol); + } + + /** + * Update the best solution + * @param _sol the current solution + */ + virtual void operator()(EOT & _sol) { + ++nbSolutionsEncountered; + double x = _sol.fitness(); + double oldAvg = currentAvg; + currentAvg = oldAvg + (x - oldAvg)/nbSolutionsEncountered; + if (nbSolutionsEncountered > 1) // <- not really necessary + { + //value() = (value()/nbSolutionsEncountered + _sol.fitness())/(nbSolutionsEncountered+1); + double oldVar = currentVar; + currentVar = oldVar + (x - oldAvg) * (x - currentAvg); + value() = Pair(currentAvg, currentVar/nbSolutionsEncountered); + } + } + + /** + * @return name of the class + */ + virtual std::string className(void) const { + return "moFitnessVarianceStat"; + } + +protected: + bool reInitSol; + bool firstTime; + double + nbSolutionsEncountered + , currentAvg + , currentVar // actually the var * n + ; + +}; + +#endif // moFitnessMomentsStat_h diff --git a/mo/src/continuator/moFitnessVarianceStat.h b/mo/src/continuator/moFitnessVarianceStat.h new file mode 100644 index 000000000..3415ab3ea --- /dev/null +++ b/mo/src/continuator/moFitnessVarianceStat.h @@ -0,0 +1,97 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef moFitnessVarianceStat_h +#define moFitnessVarianceStat_h + +#include + +/** + * Statistic that incrementally computes the variance of the fitness of the solutions during the search + */ +template +class moFitnessVarianceStat : public moStat +{ +public : + typedef typename EOT::Fitness Fitness; + using moStat< EOT , typename EOT::Fitness >::value; + + /** + * Default Constructor + * @param _reInitSol when true the best so far is reinitialized + */ + moFitnessVarianceStat(bool _reInitSol = true) + : moStat(Fitness(), "var"), + reInitSol(_reInitSol), firstTime(true), + nbSolutionsEncountered(0), currentAvg(0), currentVar(0) + { } + + /** + * Initialization of the best solution on the first one + * @param _sol the first solution + */ + virtual void init(EOT & _sol) { + if (reInitSol || firstTime) + { + value() = 0.0; + nbSolutionsEncountered = currentAvg = currentVar = 0; + firstTime = false; + } + operator()(_sol); + } + + /** + * Update the best solution + * @param _sol the current solution + */ + virtual void operator()(EOT & _sol) { + ++nbSolutionsEncountered; + double x = _sol.fitness(); + double oldAvg = currentAvg; + currentAvg = oldAvg + (x - oldAvg)/nbSolutionsEncountered; + double oldVar = currentVar; + currentVar = oldVar + (x - oldAvg) * (x - currentAvg); + value() = currentVar/nbSolutionsEncountered; + } + + /** + * @return name of the class + */ + virtual std::string className(void) const { + return "moFitnessVarianceStat"; + } + +protected: + bool reInitSol; + bool firstTime; + double + nbSolutionsEncountered + , currentAvg + , currentVar // actually the var * n + ; + +}; + +#endif // moFitnessVarianceStat_h diff --git a/mo/src/continuator/moFunctionContinuator.h b/mo/src/continuator/moFunctionContinuator.h new file mode 100644 index 000000000..f2cf7747e --- /dev/null +++ b/mo/src/continuator/moFunctionContinuator.h @@ -0,0 +1,64 @@ +/* + + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 + + Sébastien Verel, Arnaud Liefooghe, Jérémie 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 _moFunctionContinuator_h +#define _moFunctionContinuator_h + +#include +#include + +/** + * To make specific continuator from a solution + */ +template< class Neighbor > +class moFunctionContinuator : public moContinuator +{ +public: + + typedef typename Neighbor::EOT EOT ; + + /** + * Init Continuator parameters + * @param _solution the related solution + */ + virtual void init(EOT& _solution) {}; + + /** + * Last Call to terminate the checkpoint + * @param _solution the related solution + */ + virtual void lastCall(EOT& _solution) {}; +}; + +#endif diff --git a/mo/src/continuator/moStdFitnessNeighborStat.h b/mo/src/continuator/moStdFitnessNeighborStat.h index b9a547954..4c058c8ee 100644 --- a/mo/src/continuator/moStdFitnessNeighborStat.h +++ b/mo/src/continuator/moStdFitnessNeighborStat.h @@ -42,7 +42,7 @@ * From moNeighborhoodStat, to compute the average and the standard deviation of fitness in the neighborhood */ template< class Neighbor > -class moStdFitnessNeighborStat : public moStat +class moStdFitnessNeighborStat : public moStat { public : typedef typename Neighbor::EOT EOT ; diff --git a/mo/src/continuator/moUpdater.h b/mo/src/continuator/moUpdater.h index 0be846d38..37a26a04f 100644 --- a/mo/src/continuator/moUpdater.h +++ b/mo/src/continuator/moUpdater.h @@ -39,9 +39,8 @@ #include /** - * Base class for to update what ever you want - * similar to eoUpdater - * But there is an init method ! + * Base class for updating whatever you want. + * Similar to eoUpdater, but there is an "init" method ! */ class moUpdater : public eoF { diff --git a/mo/src/coolingSchedule/moCoolingSchedule.h b/mo/src/coolingSchedule/moCoolingSchedule.h index 9b65cf1b5..b9863b02f 100644 --- a/mo/src/coolingSchedule/moCoolingSchedule.h +++ b/mo/src/coolingSchedule/moCoolingSchedule.h @@ -55,8 +55,9 @@ public: * update the temperature * @param _temp current temperature to update * @param _acceptedMove true when the move is accepted, false otherwise + * @param _currentSolution the current solution */ - virtual void update(double& _temp, bool _acceptedMove) = 0; + virtual void update(double& _temp, bool _acceptedMove, EOT & _currentSolution) = 0; }; diff --git a/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h b/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h index 34b386312..5ec3a886c 100644 --- a/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h +++ b/mo/src/coolingSchedule/moDynSpanCoolingSchedule.h @@ -80,26 +80,27 @@ public: * update the temperature by a factor * @param _temp current temperature to update * @param _acceptedMove true when the move is accepted, false otherwise + * @param _currentSolution the current solution */ - virtual void update(double& _temp, bool _acceptedMove) { - spanTries++; - - if (_acceptedMove) - spanMove++; - - if (spanTries >= spanTriesMax || spanMove >= spanMoveMax) { - _temp *= alpha; - - if (spanMove == 0) // no move during this span ? - nbSpan++; - else - nbSpan = 0; - - spanTries = 0; - spanMove = 0; - } - } - + virtual void update(double& _temp, bool _acceptedMove, EOT & _currentSolution) { + spanTries++; + + if (_acceptedMove) + spanMove++; + + if (spanTries >= spanTriesMax || spanMove >= spanMoveMax) { + _temp *= alpha; + + if (spanMove == 0) // no move during this span ? + nbSpan++; + else + nbSpan = 0; + + spanTries = 0; + spanMove = 0; + } + } + /** * compare the number of span with no move * @param _temp current temperature diff --git a/mo/src/coolingSchedule/moHuangCoolingSchedule.h b/mo/src/coolingSchedule/moHuangCoolingSchedule.h new file mode 100644 index 000000000..c702b852f --- /dev/null +++ b/mo/src/coolingSchedule/moHuangCoolingSchedule.h @@ -0,0 +1,155 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef _moHuangCoolingSchedule_h +#define _moHuangCoolingSchedule_h + +#include + +#include +#include +#include +#include +#include + + +//#include +//using namespace std; + +#include + + +//! +/*! + */ +template< class EOT > +class moHuangCoolingSchedule: public moCoolingSchedule< EOT > +{ +public: + //typedef typename Neighbor::EOT EOT ; + //typedef moNeighborhood Neighborhood ; + + //! Constructor + /*! + */ + +// moHuangCoolingSchedule (double _initTemp, int _spanSize, double _lambda = .7, double _finalTemp = .01) +// moHuangCoolingSchedule (double _initTemp, int _spanSize, double _lambda = .7, double _finalStdDev = .01) + moHuangCoolingSchedule (double _initTemp, int _spanSize, double _lambda = .7, double _finalTempDecrease = .995) + : initTemp(_initTemp) + , spanSize(_spanSize) + , lambda(_lambda) +// , finalTemp(_finalTemp) + , finalStdDev(_finalTempDecrease) +// , statIsInitialized(false) +// , step(0) +// , currentStdDevEstimation(std::numeric_limits::max()) + { } + + /** + * Initial temperature + * @param _solution initial solution + */ + double init(EOT & _solution) { + statIsInitialized = terminated = false; + step = 0; + return initTemp; + } + + /** + * update the temperature by a factor + * @param _temp current temperature to update + * @param _acceptedMove true when the move is accepted, false otherwise + */ + void update(double& _temp, bool _acceptedMove, EOT & _solution) { + + if (_acceptedMove) + { + if (statIsInitialized) + momentStat(_solution); + else momentStat.init(_solution), statIsInitialized = true; + + } + + if (step >= spanSize) + { + step = 0; + /* + //double avgFitness = momentStat.value().first; + double variance = momentStat.value().second; + //double stdDevEstimation = sqrt(variance); + double currentStdDevEstimation = sqrt(variance); + _temp *= exp( -lambda*_temp / currentStdDevEstimation );*/ + double alpha = exp( -lambda*_temp / sqrt(momentStat.value().second) ); + _temp *= alpha; + //std::cout << alpha << std::endl; + terminated = alpha > finalStdDev; + } + + step++; + } + + //! Function which proceeds to the cooling + /*! + */ + bool operator() (double temperature) + { + //return temperature > finalTemp; + //return currentStdDevEstimation > finalStdDev; + return !terminated; + } + + +private: + + const double + // parameters of the algorithm + initTemp +// , stdDevEstimation + , lambda +// , finalTemp + , finalStdDev + ; + const int spanSize; + int step; + + //double currentStdDevEstimation; + + moFitnessMomentsStat momentStat; + bool statIsInitialized, terminated; + +}; + +#endif + + + + + + + + + + diff --git a/mo/src/coolingSchedule/moSimpleCoolingSchedule.h b/mo/src/coolingSchedule/moSimpleCoolingSchedule.h index 5ff4f4920..aa8f1138f 100644 --- a/mo/src/coolingSchedule/moSimpleCoolingSchedule.h +++ b/mo/src/coolingSchedule/moSimpleCoolingSchedule.h @@ -52,7 +52,8 @@ public: * @param _span number of iteration with equal temperature * @param _finalT final temperature, threshold of the stopping criteria */ - moSimpleCoolingSchedule(double _initT, double _alpha, unsigned _span, double _finalT) : initT(_initT), alpha(_alpha), span(_span), finalT(_finalT) {} + moSimpleCoolingSchedule(double _initT, double _alpha, unsigned _span, double _finalT) + : initT(_initT), alpha(_alpha), span(_span), finalT(_finalT) {} /** * Getter on the initial temperature @@ -70,8 +71,9 @@ public: * update the temperature by a factor * @param _temp current temperature to update * @param _acceptedMove true when the move is accepted, false otherwise + * @param _currentSolution the current solution */ - virtual void update(double& _temp, bool _acceptedMove) { + virtual void update(double& _temp, bool _acceptedMove, EOT & _currentSolution) { if (step >= span) { _temp *= alpha; step = 0; diff --git a/mo/src/coolingSchedule/moTrikiCoolingSchedule.h b/mo/src/coolingSchedule/moTrikiCoolingSchedule.h new file mode 100644 index 000000000..0b4466671 --- /dev/null +++ b/mo/src/coolingSchedule/moTrikiCoolingSchedule.h @@ -0,0 +1,613 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef _moTrikiCoolingSchedule_h +#define _moTrikiCoolingSchedule_h + +#include + +#include +#include +#include +#include +#include + + +/* +#include + +#include +#include +#include +#include + */ + +#include +using namespace std; + +/* +static const char * stoppingReasons[] = {"no accepted solution", "null std dev" , "frozen >= theta"}; +static const char * chainEndingReasons[] = {"MAX GENerated solutions", "MAX ACCepted solutions"}; +*/ + +//! +/*! + */ +//template< class Neighbor > //, class Neighborhood > +//class moTrikiCoolingSchedule: public moCoolingSchedule< typename Neighbor::EOT > +template< class EOT > +class moTrikiCoolingSchedule: public moCoolingSchedule< EOT > +{ +public: + //typedef typename Neighbor::EOT EOT ; + //typedef moNeighborhood Neighborhood ; + + //! Constructor + /*! + */ + /* + moTrikiCoolingSchedule (Neighborhood& _neighborhood, moEval& _eval, double _initTemp) // FIXME rem useless params!! + : initTemp(_initTemp), + mu2(10), // mu2 typically belongs to [1; 20] + K1(2), // K1 in [1; 4], the number of chains without reaching equilibrium before we raise the temperature + K2(5), // ??? + lambda1(2), // the increase in temperature, typically in [1.5; 4] + lambda2(.7), // lambda2 in [0.5; 0.99] + mu1(10), // target decrease in cost factor, in [2; 20] + xi(1.05), // xi typically belongs to [1; 1.1] + max_accepted(50), // depends on pb/neighborhood + max_generated(100), // depends on pb/neighborhood + theta(10), // theta is typically set to 10 + statIsInitialized(false)//, + //outf("out.data") + { } +*/ + +// moTrikiCoolingSchedule ( +// Neighborhood& _neighborhood, moEval& _eval, double _initTemp, +// double _max_accepted, +// double _max_generated +// ) +// : initTemp(_initTemp), +// mu2(10), // mu2 typically belongs to [1; 20] +// K1(2), // K1 in [1; 4], the number of chains without reaching equilibrium before we raise the temperature +// K2(5), // ??? +// lambda1(2), // the increase in temperature, typically in [1.5; 4] +// lambda2(.7), // lambda2 in [0.5; 0.99] +// mu1(10), // target decrease in cost factor, in [2; 20] +// xi(1.05), // xi typically belongs to [1; 1.1] +// max_accepted(_max_accepted), // depends on pb/neighborhood +// max_generated(_max_generated), // depends on pb/neighborhood +// theta(10), // theta is typically set to 10 +// statIsInitialized(false)//, +// //outf("out.data") +// { } + + moTrikiCoolingSchedule ( + double _initTemp, + int _max_accepted = 50, + int _max_generated = 100, + double _mu2 = 2, + double _mu1 = 10, + double _lambda1 = 2, + double _lambda2 = .7, + double _xi = 1.05, + int _theta = 10, + int _K1 = 10, + int _K2 = 5 + ) // TODO reorder inits + : initTemp(_initTemp), + mu2(_mu2), // mu2 typically belongs to [1; 20] + K1(_K1), // K1 in [1; 4], the number of chains without reaching equilibrium before we raise the temperature + K2(_K2), // ??? + lambda1(_lambda1), // the increase in temperature (reheating factor), typically in [1.5; 4] + lambda2(_lambda2), // lambda2 in [0.5; 0.99] + mu1(_mu1), // target decrease in cost factor, in [2; 20] + xi(_xi), // xi typically belongs to [1; 1.1] + max_accepted(_max_accepted), // depends on pb/neighborhood + max_generated(_max_generated), // depends on pb/neighborhood + theta(_theta), // theta is typically set to 10 + statIsInitialized(false) + { + chainStat.temperature = initTemp; + } + + /** + * Initial temperature + * @param _solution initial solution + */ + double init(EOT & _solution) { + + accepted = generated = 0;// = costs_sum = 0; + + negative_temp = equilibrium_not_reached = frozen = 0; + + chainStat.delta = initTemp/mu2; + + //cout << "acc " << max_accepted << " " << max_generated << endl; + + /* + reinitializing = false; + terminated = false; + statIsInitialized = false; + */ + reinitializing = false; + //cout << "INIT T=" << initTemp << endl; + //cout << "INIT T=" << chainStat.temperature << endl; + + //chainStat.temperature = initTemp; + + /// + //cout << "INIT T=" << initTemp << endl; + /// + + //outf.open("out"); + //outf << "ok"; + //outf.close(); + + + return initTemp; + } + + /** + * update the temperature by a factor + * @param _temp current temperature to update + * @param _acceptedMove true when the move is accepted, false otherwise + */ + void update(double& _temp, bool _acceptedMove, EOT & _solution) { + + //cout << _temp << " g " << generated << endl; + chainStat.temperature = _temp; + chainStat.stoppingReason = NULL; + chainStat.chainEndingReason = NULL; + chainStat.equilibriumNotReached = false; + chainStat.negativeTemp = false; + //chainStat.markovChainEnded = false; + chainStat.generatedSolutions = generated; + chainStat.acceptedSolutions = accepted; + + generated++; + //cout << "gen " << generated << endl; + + + if (_acceptedMove) + { + accepted++; + //costs_sum += _solution.fitness(); + //varStat(_solution); + if (statIsInitialized) + momentStat(_solution); + else momentStat.init(_solution), statIsInitialized = true; + + //cout << _solution.fitness() << " avgFitness=" << momentStat.value().first << endl; + } + + if (accepted > max_accepted || generated > max_generated) { + + chainStat.chainEndingReason = accepted > max_accepted ? chainEndingReasons[0]: chainEndingReasons[1]; + + //chainStat.markovChainEnded = true; + + if (accepted == 0) // ADDED! Otherwise the computed std dev is null; we're probably at equilibrium + { + /// + //cout << "Stopping: no accepted solution" << endl; + /// + + chainStat.terminated = true, chainStat.stoppingReason = stoppingReasons[0]; + return; // FIXME nutgud + } + + /// + //cout << (accepted > max_accepted? "MAXACC ": "MAXGEN "); + /// + + //double avgFitness = costs_sum/(double)accepted; + //double stdDev = sqrt(varStat.value()); // WARNING: IT'S NO MORE THE AVG COST, NOW IT'S THE STD DEV! + //double variance = varStat.value(); + double avgFitness = momentStat.value().first; + double variance = momentStat.value().second; + //double stdDev = sqrt(variance); + chainStat.stdDev = sqrt(variance); + double sigma = chainStat.stdDev; + /////////////// + //double delta = sigma/mu2; + /////////////// + + + //outf << avgFitness << endl; + //outf << _temp << endl; + //outf << prevAvgFitness-delta << endl; + + + accepted = generated = 0; // = costs_sum = 0; + //momentStat.init(_solution);//TODONE use next chain's first sol + statIsInitialized = false; + + /// + //cout << "T=" << _temp << " avgFitness=" << avgFitness << " stdDev=" << chainStat.stdDev << " currCost=" << _solution.fitness() << endl; + /// + + double alpha = 0; + double prevAvgFitness = chainStat.avgFitness; + + /// + //cout << "negTemp: " << negative_temp << " / " << K2 << endl; + /// + + if (negative_temp < K2) + { + //if (!chainStat.reinitializing) + if (!reinitializing) + { + /// + //if (avgFitness/(chainStat.prevAvgFitness-delta) > xi) cout << "/!\\ eq not reached!" << endl; + /// + + if (avgFitness/(prevAvgFitness-chainStat.delta) > xi) + equilibrium_not_reached++, chainStat.equilibriumNotReached = true; + else equilibrium_not_reached = 0; + } + if (equilibrium_not_reached > K1) + { + /// + //cout << "/!\\ Reinitializing (eq not reached)" << endl; + /// + + //chainStat.reinitializing = true; + reinitializing = true; + //chainStat.equilibriumNotReached = true; + + alpha = lambda1; + chainStat.delta = sigma/mu1; + equilibrium_not_reached = 0; // ADDED! Otherwise the algo gets trapped here! + } + else if (_temp*chainStat.delta/(sigma*sigma) >= 1) + { + /// + //cout << "/!\\ neg temp!" << endl; + /// + + negative_temp++; + reinitializing = true; + chainStat.negativeTemp = true; + + if (negative_temp < K2) + { + alpha = lambda1; + chainStat.delta = sigma/mu1; + } else + alpha = lambda2; + } + + // First interpretation of the pseudocode indentation: (seems obviously false because it makes the above code unreachable) + /* + } + else + { + cout << "ccc" << endl; + reinitializing = false; + prevAvgFitness = avgFitness; + alpha = 1-_temp*delta/(sigma*sigma); + } + */ + + // Second interpretation of the pseudocode indentation: + else + { + /// + //cout << "[normal decrease]" << endl; + /// + + reinitializing = false; + //chainStat.avgFitness = avgFitness; + //alpha = 1-_temp*delta/(sigma*sigma); + alpha = 1-_temp*chainStat.delta/variance; + + //alpha = (sigma==0? 1: 1-_temp*delta/(sigma*sigma)); // ADDED! but removed + + if (sigma == 0) // ADDED! When std dev is null, the solution is probably at eq, and the algo can't go on anyways + chainStat.terminated = true, chainStat.stoppingReason = stoppingReasons[1]; //, cout << "Stopping: null std dev" << endl; + } + } + // FIXME: else what? alpha=? + + /// + //cout << "*=" << alpha << endl; + /// + + _temp *= alpha; + + chainStat.currentFitness = _solution.fitness(); // FIXME here? + chainStat.alpha = alpha; + //chainStat.delta = delta; + chainStat.avgFitness = avgFitness; + + + // Never seems to be used + if (avgFitness == prevAvgFitness) // use a neighborhood to approximate double floating equality? + frozen++; + else frozen = 0; + + + if (frozen >= theta) + chainStat.terminated = true, chainStat.stoppingReason = stoppingReasons[2];; + + //exit(0); + //cin.get(); + + + } + + } + + //! Function which proceeds to the cooling + /*! + */ + bool operator() (double temperature) + { + /// + //if (chainStat.terminated) cout << "TERMINATED" << endl; + /// + + return frozen < theta + && !chainStat.terminated ; // ADDED! because 'frozen' doesn't terminate anything + + + return !chainStat.terminated ; // ADDED! because 'frozen' doesn't terminate anything + + } + + /* + bool markovChainJustEnded() const + { + return markovChainEnded; + }*/ + + + // Code for generating the getters: +/* +#define __triki_getterType double +#define __triki_makeGetter(name) __triki_getterType name() { return chainStat.name; } + + __triki_makeGetter(stdDev) + __triki_makeGetter(avgFitness) + __triki_makeGetter(prevTemp) + __triki_makeGetter(currentFitness) + __triki_makeGetter(alpha) + +#undef __triki_getterType +#define __triki_getterType int + + __triki_makeGetter(generatedSolutions) + __triki_makeGetter(acceptedSolutions) + +#undef __triki_getterType +#define __triki_getterType const char * + + __triki_makeGetter(stoppingReason) + __triki_makeGetter(chainEndingReason) + +#undef __triki_getterType +#undef __triki_makeGetter + */ + +#define __triki_makeGetter(name, type) type name() { return chainStat.name; } + + __triki_makeGetter(stdDev, double) + __triki_makeGetter(avgFitness, double) + __triki_makeGetter(temperature, double) + __triki_makeGetter(currentFitness, double) + __triki_makeGetter(alpha, double) + __triki_makeGetter(delta, double) + + __triki_makeGetter(generatedSolutions, int) + __triki_makeGetter(acceptedSolutions, int) + + __triki_makeGetter(equilibriumNotReached, bool) + __triki_makeGetter(negativeTemp, bool) + __triki_makeGetter(terminated, bool) + + __triki_makeGetter(stoppingReason, const char *) + __triki_makeGetter(chainEndingReason, const char *) + +#undef __triki_makeGetter + + + const bool markovChainEnded() const + { + return chainStat.chainEndingReason != NULL; + } + + struct MarkovChainStats; + const MarkovChainStats& markovChainStats() const + { + return chainStat; + } + + struct MarkovChainStats { + + MarkovChainStats() + : stdDev(0), avgFitness(0), temperature(-1), currentFitness(-1), alpha(0), delta(0), + //equilibriumNotReached(false), negativeTemp(false), terminated(false), markovChainEnded(false) + equilibriumNotReached(false), negativeTemp(false), terminated(false) + { } + + double + stdDev, + avgFitness, + //prevAvgFitness, + //expectedDecreaseInCost, // delta + //costs_sum, + temperature, + currentFitness, + alpha, + delta + ; + int generatedSolutions, acceptedSolutions; + //bool reinitializing, terminated, markovChainEnded; + bool equilibriumNotReached, negativeTemp, terminated; //, markovChainEnded; + const char * stoppingReason; + const char * chainEndingReason; // if NULL, the chain has not ended + //EOT& currentSolution; + //moTrikiCoolingSchedule& coolingSchedule; + void print(std::ostream& os = std::cout, bool onlyWhenChainEnds = true) const + { + //if (markovChainEnded || !onlyWhenChainEnds) + if (chainEndingReason != NULL || !onlyWhenChainEnds) + { + //os << "T=" << prevTemp << " avgFitness=" << prevAvgFitness << " stdDev=" << stdDev << " currentFitness=" << currentSolution.fitness() << endl; + os << "T=" << temperature << " avgFitness=" << avgFitness << " stdDev=" << stdDev << " currentFitness=" << currentFitness << " expected decrease in cost=" << delta << endl; + //os << "T=" << prevTemp << " \t\tavgFitness=" << prevAvgFitness << " \t\tstdDev=" << stdDev << " \t\tcurrentFitness=" << currentFitness << endl; + //os << "T*=" << alpha << " reinitializing=" << reinitializing << " markovChainEnded=" << markovChainEnded << endl;// << " terminated=" << terminated; + //os << "T*=" << alpha << " markovChainEnded=" << markovChainEnded;// << " terminated=" << terminated; + // TODONE print delta ? (expected decrease in cost) + if (chainEndingReason != NULL) + os << "T*=" << alpha << " chain ended, because " << chainEndingReason; + if (equilibriumNotReached) + os << " /!\\ equilibrium not reached"; + if (negativeTemp) + os << " /!\\ negative temperature"; + os << endl; + if (terminated) + os << "Terminated, because " << stoppingReason << endl; + // os << endl; + } + } + }; + + +private: +//public://FIXME add friend + //moNeighborhoodStat nhStat; + //moStdFitnessNeighborStat stdDevStat; + const double + // parameters of the algorithm + //currentTemp, + initTemp, + //ratio, + //threshold, + mu2, // mu2 typically belongs to [1; 20] + K1, // K1 in [1; 4], the number of chains without reaching equilibrium before we raise the temperature + K2, + lambda1, // the increase in temperature, typically in [1.5; 4] + lambda2, // lambda2 in [0.5; 0.99] + mu1, // target decrease in cost factor, in [2; 20] + xi // xi typically belongs to [1; 1.1] + // private variables + ; + /* + double + stdDev, + prevAvgFitness, + expectedDecreaseInCost, // delta + costs_sum, + prevTemp + ;*/ + MarkovChainStats chainStat; + //double costs_sum; + + const int + max_accepted, + max_generated, + theta // theta is typically set to 10 + ; + int + accepted, + generated, + equilibrium_not_reached, + negative_temp, + frozen + ; + //bool reinitializing, terminated, markovChainEnded; + + //moFitnessVarianceStat varStat; + moFitnessMomentsStat momentStat; + bool statIsInitialized, reinitializing; + + //ofstream outf; + /* + static const char * stoppingReasons[] = {"no accepted solution", "null std dev" , "frozen >= theta"}; + static const char * chainEndingReasons[] = {"MAX GENerated solutions", "MAX ACCepted solutions"}; + */ + static const char * stoppingReasons[]; + static const char * chainEndingReasons[]; + +protected: + +// class Monitor { +// public: +// +// Monitor(moTrikiCoolingSchedule& _cooling) +// : cooling(_cooling) +// { } +// +// /*void setTemperatureOstream(ostream& os) +// { +// +// }*/ +// void getLatestTemperature() +// { +// return cooling.prevTemp; +// } +// +// void printCurrentStatus(ostream& os) +// { +// if (accepted >= max_accepted || generated >= max_generated) +// { +// os << "Markov chain finished. Temp was " << getLatestTemperature(); // chain number +// +// } +// } +// +// private: +// moTrikiCoolingSchedule& cooling; +// }; + +}; + + + +template< class Neighbor > +const char * moTrikiCoolingSchedule::stoppingReasons[] = {"no accepted solution", "null std dev" , "frozen >= theta"}; + +template< class Neighbor > +//const char * moTrikiCoolingSchedule::chainEndingReasons[] = {"MAX GENerated solutions", "MAX ACCepted solutions"}; +const char * moTrikiCoolingSchedule::chainEndingReasons[] = {"MAX ACCepted solutions", "MAX GENerated solutions"}; + + + + +#endif + + + + + + + + + + diff --git a/mo/src/explorer/moMetropolisHastingExplorer.h b/mo/src/explorer/moMetropolisHastingsExplorer.h similarity index 56% rename from mo/src/explorer/moMetropolisHastingExplorer.h rename to mo/src/explorer/moMetropolisHastingsExplorer.h index 3123c4914..caf44f49f 100644 --- a/mo/src/explorer/moMetropolisHastingExplorer.h +++ b/mo/src/explorer/moMetropolisHastingsExplorer.h @@ -1,8 +1,8 @@ /* - + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 - Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau + Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau, Lionel Parreaux This software is governed by the CeCILL license under French law and abiding by the rules of distribution of free software. You can use, @@ -32,16 +32,18 @@ Contact: paradiseo-help@lists.gforge.inria.fr */ -#ifndef _moMetropolisHastingExplorer_h -#define _moMetropolisHastingExplorer_h +#ifndef _moMetropolisHastingsExplorer_h +#define _moMetropolisHastingsExplorer_h #include +#include #include #include #include #include +#include #include /** @@ -49,8 +51,8 @@ * Only the symetric case is considered when Q(x,y) = Q(y,x) * Fitness must be > 0 */ -template< class Neighbor > -class moMetropolisHastingExplorer : public moNeighborhoodExplorer +template< class Neighbor, class Derived /*TODO reqs on Derived*/> +class moMetropolisHastingsExplorer : public moNeighborhoodExplorer { public: typedef typename Neighbor::EOT EOT ; @@ -68,42 +70,54 @@ public: * @param _solNeighborComparator a solution vs neighbor comparator * @param _nbStep maximum number of step to do */ - moMetropolisHastingExplorer(Neighborhood& _neighborhood, moEval& _eval, moNeighborComparator& _neighborComparator, moSolNeighborComparator& _solNeighborComparator, unsigned int _nbStep) : moNeighborhoodExplorer(_neighborhood, _eval), neighborComparator(_neighborComparator), solNeighborComparator(_solNeighborComparator), nbStep(_nbStep) { - isAccept = false; + moMetropolisHastingsExplorer( + Neighborhood& _neighborhood, + moEval& _eval, + //moNeighborComparator& _neighborComparator, + //moSolNeighborComparator& _solNeighborComparator + eoOptional< moSolNeighborComparator > _comp = NULL + ) + : moNeighborhoodExplorer(_neighborhood, _eval), + //neighborComparator(_neighborComparator), + //solNeighborComparator(_solNeighborComparator), + defaultSolNeighborComp(NULL), + solNeighborComparator(_comp.hasValue()? _comp.get(): *(defaultSolNeighborComp = new moSolNeighborComparator())) + { + //isMoveAccepted = false; if (!neighborhood.isRandom()) { - std::cout << "moMetropolisHastingExplorer::Warning -> the neighborhood used is not random" << std::endl; + //std::cout << "moMetropolisHastingsExplorer::Warning -> the neighborhood used is not random" << std::endl; + eo::log << eo::warnings << "moMetropolisHastingsExplorer::Warning -> the neighborhood used is not random" << std::endl; } } /** * Destructor */ - ~moMetropolisHastingExplorer() { + ~moMetropolisHastingsExplorer() { + if (defaultSolNeighborComp != NULL) + delete defaultSolNeighborComp; } - /** - * initialization of the number of step to be done - * @param _solution unused solution - */ - virtual void initParam(EOT & _solution) { - step = 0; - isAccept = true; - }; - - /** - * increase the number of step - * @param _solution unused solution - */ - virtual void updateParam(EOT & _solution) { - step++; - }; - - /** - * terminate: NOTHING TO DO - * @param _solution unused solution - */ +// /** +// * initialization of the number of step to be done +// * @param _solution unused solution +// */ +// virtual void initParam(EOT & _solution) { +// step = 0; +// isMoveAccepted = true; +// }; +// +// /** +// * terminate: NOTHING TO DO +// * @param _solution unused solution +// */ +// virtual void terminate(EOT & _solution) {}; + + virtual void initParam(EOT & _solution) {}; virtual void terminate(EOT & _solution) {}; - + + + /** * Explore the neighborhood of a solution * @param _solution @@ -113,67 +127,76 @@ public: if (neighborhood.hasNeighbor(_solution)) { //init the first neighbor neighborhood.init(_solution, selectedNeighbor); - - //eval the _solution moved with the neighbor and stock the result in the neighbor + + //eval the _solution moved with the neighbor and stores the result in the neighbor eval(_solution, selectedNeighbor); } + /* else { //if _solution hasn't neighbor, - isAccept=false; - } + isMoveAccepted = false; + }*/ }; - - /** - * continue if there is a neighbor and it is remainds some steps to do - * @param _solution the solution - * @return true there is some steps to do - */ - virtual bool isContinue(EOT & _solution) { - return (step < nbStep) ; - }; - + /** * accept test if an ameliorated neighbor was found * @param _solution the solution * @return true if the best neighbor ameliorate the fitness */ virtual bool accept(EOT & _solution) { - double alpha=0.0; + /*double alpha=0.0; if (neighborhood.hasNeighbor(_solution)) { - if (solNeighborComparator(_solution, selectedNeighbor)) - isAccept = true; + if (solNeighborComparator(_solution, selectedNeighbor)) + isMoveAccepted = true; else { if (_solution.fitness() != 0) { if ( (double)selectedNeighbor.fitness() < (double)_solution.fitness()) // maximizing alpha = (double) selectedNeighbor.fitness() / (double) _solution.fitness(); else //minimizing alpha = (double) _solution.fitness() / (double) selectedNeighbor.fitness(); - isAccept = (rng.uniform() < alpha) ; + isMoveAccepted = (rng.uniform() < alpha) ; } else { if ( (double) selectedNeighbor.fitness() < (double) _solution.fitness()) // maximizing - isAccept = true; + isMoveAccepted = true; else - isAccept = false; + isMoveAccepted = false; } } + }*/ + /*bool accepted = false; + if (neighborhood.hasNeighbor(_solution)) { + if (solNeighborComparator(_solution, selectedNeighbor)) // accept if the current neighbor is better than the solution + accepted = true; + //else accepted = static_cast(this)->doAccept(_solution); + else accepted = rng.uniform() <= static_cast(this)->getAlpha(_solution); } - return isAccept; + return isMoveAccepted = accepted;*/ + bool isMoveAccepted = false; + if (neighborhood.hasNeighbor(_solution)) { + if (solNeighborComparator(_solution, selectedNeighbor)) // accept if the current neighbor is better than the solution + isMoveAccepted = true; + //else accepted = static_cast(this)->doAccept(_solution); + else isMoveAccepted = rng.uniform() < static_cast(this)->alpha(_solution); + } + return isMoveAccepted; }; - + private: + moSolNeighborComparator* defaultSolNeighborComp; + // comparator betwenn solution and neighbor or between neighbors - moNeighborComparator& neighborComparator; + //moNeighborComparator& neighborComparator; moSolNeighborComparator& solNeighborComparator; - + /* // current number of step unsigned int step; // maximum number of steps to do unsigned int nbStep; - + */ // true if the move is accepted - bool isAccept ; + //bool isMoveAccepted ; }; diff --git a/mo/src/explorer/moNeighborhoodExplorer.h b/mo/src/explorer/moNeighborhoodExplorer.h index 8b4113b7a..76ee12af7 100644 --- a/mo/src/explorer/moNeighborhoodExplorer.h +++ b/mo/src/explorer/moNeighborhoodExplorer.h @@ -65,15 +65,19 @@ public: typedef typename Neighbor::EOT EOT; typedef typename EOT::Fitness Fitness ; - moNeighborhoodExplorer():neighborhood(dummyNeighborhood), eval(dummyEval), isMoved(false) {} + moNeighborhoodExplorer() + : neighborhood(dummyNeighborhood), eval(dummyEval), isMoved(false) + { } /** * Constructor with a Neighborhood and evaluation function * @param _neighborhood the neighborhood * @param _eval the evaluation function */ - moNeighborhoodExplorer(Neighborhood& _neighborhood, moEval& _eval):neighborhood(_neighborhood), eval(_eval), isMoved(false) {} - + moNeighborhoodExplorer(Neighborhood& _neighborhood, moEval& _eval) + : neighborhood(_neighborhood), eval(_eval), isMoved(false) + { } + /** * Init Search parameters * @param _solution the solution to explore diff --git a/mo/src/explorer/moSAExplorer.h b/mo/src/explorer/moSAExplorer.h new file mode 100644 index 000000000..12afeac1f --- /dev/null +++ b/mo/src/explorer/moSAExplorer.h @@ -0,0 +1,243 @@ +/* + + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 + + Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau, Lionel Parreaux + + 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 _moSAExplorer_h +#define _moSAExplorer_h + +#include + +//#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * Explorer for the Simulated Annealing + * Only the symetric case is considered when Q(x,y) = Q(y,x) + * Fitness must be > 0 + * + */ +template< class Neighbor > +class moSAExplorer : public moMetropolisHastingsExplorer< Neighbor, moSAExplorer > +{ +public: + typedef typename Neighbor::EOT EOT ; + typedef moNeighborhood Neighborhood ; + + using moNeighborhoodExplorer::neighborhood; + using moNeighborhoodExplorer::eval; + using moNeighborhoodExplorer::selectedNeighbor; + + + /*moSAExplorer(Neighborhood& _neighborhood, moEval& _eval) + : moNeighborhoodExplorer(_neighborhood, _eval) + { }*/ + + moSAExplorer ( + Neighborhood& _neighborhood, + //eoOptional< moEval > _eval = NULL, + moEval& _eval, + moCoolingSchedule& _cool, + eoOptional< moSolNeighborComparator > _comp = NULL + ) + : moMetropolisHastingsExplorer< Neighbor, moSAExplorer >(_neighborhood, _eval, _comp), + /*moNeighborhoodExplorer(_neighborhood, _eval.hasValue()? _eval.get(): *(default_eval = new moFullEvalByCopy(_fullEval))), + default_eval(NULL), // removed in C++11 with unique_ptr*/ + //defaultSolNeighborComp(NULL), // removed in C++11 with unique_ptr + //solNeighborComparator(_comp.hasValue()? _comp.get(): *(defaultSolNeighborComp = new moSolNeighborComparator())), + //coolingSchedule(_coolingSchedule) + coolingSchedule(_cool) + { + /*isMoveAccepted = false; + if (!neighborhood.isRandom()) { + std::cout << "moSAexplorer::Warning -> the neighborhood used is not random" << std::endl; + }*/ + } + + /** + * Destructor + */ + ~moSAExplorer() { + } + + /** + * initialization of the initial temperature + * @param _solution the solution + */ + virtual void initParam(EOT & _solution) { + temperature = coolingSchedule.init(_solution); + //isMoveAccepted = false; + }; + + /** + * decrease the temperature if necessary + * @param _solution unused solution + */ + virtual void updateParam(EOT & _solution) { + coolingSchedule.update(temperature, this->moveApplied(), _solution); + }; + + /** + * terminate: NOTHING TO DO + * @param _solution unused solution + */ + virtual void terminate(EOT & _solution) {}; + + /** + * Explore one random solution in the neighborhood + * @param _solution the solution + */ + virtual void operator()(EOT & _solution) { + //Test if _solution has a Neighbor + if (neighborhood.hasNeighbor(_solution)) { + //init on the first neighbor: supposed to be random solution in the neighborhood + neighborhood.init(_solution, selectedNeighbor); + + //eval the _solution moved with the neighbor and stock the result in the neighbor + eval(_solution, selectedNeighbor); + } + else { + //if _solution hasn't neighbor, + //isMoveAccepted = false; + } + }; + + /** + * continue if the temperature is not too low + * @param _solution the solution + * @return true if the criteria from the cooling schedule is true + */ + virtual bool isContinue(EOT & _solution) { + return coolingSchedule(temperature); + }; + + /** + * acceptance criterion according to the boltzmann criterion + * @param _solution the solution + * @return true if better neighbor or rnd < exp(delta f / T) + */ +// virtual bool accept(EOT & _solution) { +// if (neighborhood.hasNeighbor(_solution)) { +// if (solNeighborComparator(_solution, selectedNeighbor)) // accept if the current neighbor is better than the solution +// isMoveAccepted = true; +// else { +// /* +// double alpha=0.0; +// double fit1, fit2; +// fit1=(double)selectedNeighbor.fitness(); +// fit2=(double)_solution.fitness(); +// if (fit1 < fit2) // this is a maximization +// alpha = exp((fit1 - fit2) / temperature ); +// else // this is a minimization +// alpha = exp((fit2 - fit1) / temperature ); +// isMoveAccepted = (rng.uniform() < alpha) ;*/ +// /* +// double fit1 = (double)selectedNeighbor.fitness(), +// fit2 = (double)_solution.fitness(), +// alpha = fit1 < fit2 ? exp((fit1 - fit2) / temperature) : exp((fit2 - fit1) / temperature); +// //if (fit1 < fit2) // this is a maximization +// //else // this is a minimization +// isMoveAccepted = (rng.uniform() < alpha);*/ +// /*double fit1 = (double) selectedNeighbor.fitness(), +// fit2 = (double) _solution.fitness(), +// alpha = fit1 < fit2 ? exp((fit1 - fit2) / temperature) : 1; +// isMoveAccepted = (rng.uniform() <= alpha);*/ +// /* +// double fit1 = (double) selectedNeighbor.fitness(), +// fit2 = (double) _solution.fitness(), +// alpha = exp( - fabs(fit1 - fit2) / temperature ); +// // (fit1 - fit2) positive or negative depending on whether we're maximizing or minimizing +// isMoveAccepted = (rng.uniform() <= alpha);*/ +// //isMoveAccepted = Accepter::accept(_solution, selectedNeighbor); +// isMoveAccepted = static_cast(this)->accept(_solution); +// } +// } +// return isMoveAccepted; +// }; + + /** + * Getter + * @return the temperature + */ + double getTemperature() const { + return temperature; + } + + + /* + virtual bool doAccept(EOT & _solution) { + double fit1 = (double) selectedNeighbor.fitness(), + fit2 = (double) _solution.fitness(), + alpha = exp( - fabs(fit1 - fit2) / temperature ); + // (fit1 - fit2) positive or negative depending on whether we're maximizing or minimizing + return rng.uniform() <= alpha; + }*/ + double alpha(EOT & _solution) { + //std::cout << "ok " << exp( - fabs((double) selectedNeighbor.fitness() - (double) _solution.fitness()) / temperature ) << " "; + return exp( - fabs((double) selectedNeighbor.fitness() - (double) _solution.fitness()) / temperature ); + } + + +private: + + //moSolNeighborComparator* defaultSolNeighborComp; + +public://FIXME add friend + // comparator betwenn solution and neighbor + //moSolNeighborComparator& solNeighborComparator; + + moCoolingSchedule& coolingSchedule; + + // temperatur of the process + double temperature; + + // true if the move is accepted + //bool isMoveAccepted ; + + /** + * Getter + * @return the temperature + */ + //virtual double getTemperature() = 0; + +}; + + +#endif + diff --git a/mo/src/explorer/moSAexplorer.h b/mo/src/explorer/moSAexplorer.h deleted file mode 100644 index 3d9f477ee..000000000 --- a/mo/src/explorer/moSAexplorer.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - - Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 - - Sébastien Verel, Arnaud Liefooghe, Jérémie 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 _moSAexplorer_h -#define _moSAexplorer_h - -#include - -#include -#include -#include -#include - -#include - -/** - * Explorer for the Simulated Annealing - * Only the symetric case is considered when Q(x,y) = Q(y,x) - * Fitness must be > 0 - * - */ -template< class Neighbor > -class moSAexplorer : public moNeighborhoodExplorer -{ -public: - typedef typename Neighbor::EOT EOT ; - typedef moNeighborhood Neighborhood ; - - using moNeighborhoodExplorer::neighborhood; - using moNeighborhoodExplorer::eval; - using moNeighborhoodExplorer::selectedNeighbor; - - /** - * Constructor - * @param _neighborhood the neighborhood - * @param _eval the evaluation function - * @param _solNeighborComparator a solution vs neighbor comparator - * @param _coolingSchedule the cooling schedule - */ - moSAexplorer(Neighborhood& _neighborhood, moEval& _eval, moSolNeighborComparator& _solNeighborComparator, moCoolingSchedule& _coolingSchedule) : moNeighborhoodExplorer(_neighborhood, _eval), solNeighborComparator(_solNeighborComparator), coolingSchedule(_coolingSchedule) { - isAccept = false; - - if (!neighborhood.isRandom()) { - std::cout << "moSAexplorer::Warning -> the neighborhood used is not random" << std::endl; - } - } - - /** - * Destructor - */ - ~moSAexplorer() { - } - - /** - * initialization of the initial temperature - * @param _solution the solution - */ - virtual void initParam(EOT & _solution) { - temperature = coolingSchedule.init(_solution); - isAccept = false; - }; - - /** - * decrease the temperature if necessary - * @param _solution unused solution - */ - virtual void updateParam(EOT & _solution) { - coolingSchedule.update(temperature, this->moveApplied()); - }; - - /** - * terminate: NOTHING TO DO - * @param _solution unused solution - */ - virtual void terminate(EOT & _solution) {}; - - /** - * Explore one random solution in the neighborhood - * @param _solution the solution - */ - virtual void operator()(EOT & _solution) { - //Test if _solution has a Neighbor - if (neighborhood.hasNeighbor(_solution)) { - //init on the first neighbor: supposed to be random solution in the neighborhood - neighborhood.init(_solution, selectedNeighbor); - - //eval the _solution moved with the neighbor and stock the result in the neighbor - eval(_solution, selectedNeighbor); - } - else { - //if _solution hasn't neighbor, - isAccept=false; - } - }; - - /** - * continue if the temperature is not too low - * @param _solution the solution - * @return true if the criteria from the cooling schedule is true - */ - virtual bool isContinue(EOT & _solution) { - return coolingSchedule(temperature); - }; - - /** - * acceptance criterion according to the boltzmann criterion - * @param _solution the solution - * @return true if better neighbor or rnd < exp(delta f / T) - */ - virtual bool accept(EOT & _solution) { - if (neighborhood.hasNeighbor(_solution)) { - if (solNeighborComparator(_solution, selectedNeighbor)) // accept if the current neighbor is better than the solution - isAccept = true; - else { - double alpha=0.0; - double fit1, fit2; - fit1=(double)selectedNeighbor.fitness(); - fit2=(double)_solution.fitness(); - if (fit1 < fit2) // this is a maximization - alpha = exp((fit1 - fit2) / temperature ); - else // this is a minimization - alpha = exp((fit2 - fit1) / temperature ); - isAccept = (rng.uniform() < alpha) ; - } - } - return isAccept; - }; - - /** - * Getter - * @return the temperature - */ - double getTemperature() { - return temperature; - } - -private: - // comparator betwenn solution and neighbor - moSolNeighborComparator& solNeighborComparator; - - moCoolingSchedule& coolingSchedule; - - // temperatur of the process - double temperature; - - // true if the move is accepted - bool isAccept ; -}; - - -#endif diff --git a/mo/src/explorer/moSimpleMetropolisHastingsExplorer.h b/mo/src/explorer/moSimpleMetropolisHastingsExplorer.h new file mode 100644 index 000000000..64fdc7bd9 --- /dev/null +++ b/mo/src/explorer/moSimpleMetropolisHastingsExplorer.h @@ -0,0 +1,230 @@ +/* + + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 + + Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau, Lionel Parreaux + + 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 _moSimpleMetropolisHastingsExplorer_h +#define _moSimpleMetropolisHastingsExplorer_h +/* +#include + +#include +#include +#include +#include + +#include */ +#include + + +/** + * Explorer for the Metropolis-Hasting Sampling. + * Only the symetric case is considered when Q(x,y) = Q(y,x) + * Fitness must be > 0 + */ +template< class Neighbor > +class moSimpleMetropolisHastingsExplorer : public moMetropolisHastingsExplorer< Neighbor, moSimpleMetropolisHastingsExplorer > +{ +public: + typedef typename Neighbor::EOT EOT ; + typedef moNeighborhood Neighborhood ; + /* + using moNeighborhoodExplorer::neighborhood; + using moNeighborhoodExplorer::eval; + using moNeighborhoodExplorer::selectedNeighbor; + */ + + using moNeighborhoodExplorer::selectedNeighbor; + + + /** +// * Constructor TODO +// * @param _neighborhood the neighborhood +// * @param _eval the evaluation function +// * @param _neighborComparator a neighbor comparator +// * @param _solNeighborComparator a solution vs neighbor comparator +// * @param _maxSteps maximum number of currentStepNb to do +// */ + moSimpleMetropolisHastingsExplorer ( + Neighborhood& _neighborhood, + moEval& _eval, + unsigned int _maxSteps, + eoOptional< moSolNeighborComparator > _comp = NULL + ) + : moMetropolisHastingsExplorer< Neighbor, moSimpleMetropolisHastingsExplorer >(_neighborhood, _eval, _comp), + maxSteps(_maxSteps) + { } + + + + + + /** +// * Constructor +// * @param _neighborhood the neighborhood +// * @param _eval the evaluation function +// * @param _neighborComparator a neighbor comparator +// * @param _solNeighborComparator a solution vs neighbor comparator +// * @param _maxSteps maximum number of currentStepNb to do +// */ +// moSimpleMetropolisHastingsExplorer( +// Neighborhood& _neighborhood, +// moEval& _eval, +// moNeighborComparator& _neighborComparator, +// moSolNeighborComparator& _solNeighborComparator, +// unsigned int _maxSteps +// ): moNeighborhoodExplorer(_neighborhood, _eval), +// neighborComparator(_neighborComparator), +// solNeighborComparator(_solNeighborComparator), +// maxSteps(_maxSteps) +// { +// isAccept = false; +// if (!neighborhood.isRandom()) { +// std::cout << "moSimpleMetropolisHastingsExplorer::Warning -> the neighborhood used is not random" << std::endl; +// } +// } +// +// /** +// * Destructor +// */ +// ~moSimpleMetropolisHastingsExplorer() { +// } +// + /** + * initialization of the number of currentStepNb to be done + * @param _solution unused solution + */ + virtual void initParam(EOT & _solution) { + currentStepNb = 0; + //isAccept = true; + }; +// + /** + * increase the number of currentStepNb + * @param _solution unused solution + */ + virtual void updateParam(EOT & _solution) { + currentStepNb++; + }; +// +// /** +// * terminate: NOTHING TO DO +// * @param _solution unused solution +// */ +// virtual void terminate(EOT & _solution) {}; +// +// /** +// * Explore the neighborhood of a solution +// * @param _solution +// */ +// virtual void operator()(EOT & _solution) { +// //Test if _solution has a Neighbor +// if (neighborhood.hasNeighbor(_solution)) { +// //init the first neighbor +// neighborhood.init(_solution, selectedNeighbor); +// +// //eval the _solution moved with the neighbor and stock the result in the neighbor +// eval(_solution, selectedNeighbor); +// } +// else { +// //if _solution hasn't neighbor, +// isAccept=false; +// } +// }; +// + /** + * continue if there is a neighbor and it is remainds some steps to do + * @param _solution the solution + * @return true there is some steps to do + */ + virtual bool isContinue(EOT & _solution) { + return currentStepNb < maxSteps; + }; +// +// /** +// * accept test if an ameliorated neighbor was found +// * @param _solution the solution +// * @return true if the best neighbor ameliorate the fitness +// */ +// virtual bool accept(EOT & _solution) { +// double alpha=0.0; +// if (neighborhood.hasNeighbor(_solution)) { +// if (solNeighborComparator(_solution, selectedNeighbor)) +// isAccept = true; +// else { +// if (_solution.fitness() != 0) { +// if ( (double)selectedNeighbor.fitness() < (double)_solution.fitness()) // maximizing +// alpha = (double) selectedNeighbor.fitness() / (double) _solution.fitness(); +// else //minimizing +// alpha = (double) _solution.fitness() / (double) selectedNeighbor.fitness(); +// isAccept = (rng.uniform() < alpha) ; +// } +// else { +// if ( (double) selectedNeighbor.fitness() < (double) _solution.fitness()) // maximizing +// isAccept = true; +// else +// isAccept = false; +// } +// } +// } +// return isAccept; +// }; + + double alpha(EOT & _solution) { + if (selectedNeighbor.fitness() == 0) + return selectedNeighbor.fitness() < (double) _solution.fitness() ? 1: 0; + return (double) _solution.fitness() / (double) selectedNeighbor.fitness(); + } +// +//private: +// // comparator betwenn solution and neighbor or between neighbors +// moNeighborComparator& neighborComparator; +// moSolNeighborComparator& solNeighborComparator; +// +// // current number of currentStepNb +// unsigned int currentStepNb; +// +// // maximum number of steps to do +// unsigned int maxSteps; +// +// // true if the move is accepted +// bool isAccept ; +private: + // current number of steps + unsigned int currentStepNb; + + // maximum number of steps to do + unsigned int maxSteps; +}; + + +#endif diff --git a/mo/src/mo.h b/mo/src/mo.h index 2a56a86a5..922a2c01e 100755 --- a/mo/src/mo.h +++ b/mo/src/mo.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include @@ -105,6 +105,8 @@ #include #include #include +#include +#include #include #include @@ -116,14 +118,15 @@ #include #include #include -#include +#include #include #include #include #include #include #include -#include +#include +//#include #include #include #include @@ -207,5 +210,6 @@ #include #include #include +#include #endif diff --git a/mo/src/neighborhood/moRealNeighbor.h b/mo/src/neighborhood/moRealNeighbor.h new file mode 100644 index 000000000..e4a4a18d6 --- /dev/null +++ b/mo/src/neighborhood/moRealNeighbor.h @@ -0,0 +1,112 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef __moRealNeighbor_h__ +#define __moRealNeighbor_h__ + +#include +#include +#include + +//! A neighbor as produced by a moRealNeighborhood +/*! + * In a real neighborhood, the move is just a translation vector, of the same type than a solution. + */ + +template +class moRealNeighbor : public moNeighbor +{ +protected: + //! The move to be applied + EOT _translation; + + edoBounder * _bounder; + + +public: + + moRealNeighbor() : _bounder( NULL ) { } + + //! Returns the solution attached to this neighbor + EOT translation() { return _translation; } + + //! Set the translation + void translation( EOT translation ) { _translation = translation; } + + + void bounder( edoBounder * bounder ) { _bounder = bounder; } + + /** + * Assignment operator + * @param _neighbor the neighbor to assign + * @return a neighbor equal to the other + */ + virtual moNeighbor& operator=(const moNeighbor& _neighbor) { + fitness( _neighbor.fitness() ); + return (*this); + } + + /*! + * Move a solution to the solution of this neighbor + * @param _solution the related solution + */ + virtual void move(EOT & _solution) + { + assert( _solution.size() == _translation.size() ); + + for( unsigned int i=0, size= _solution.size(); i& _neighbor) { + return _neighbor.translation() == _translation; + } + + /** + * Return the class Name + * @return the class name as a std::string + */ + virtual std::string className() const { + return "moRealNeighbor"; + } +}; + + +#endif // __moRealNeighbor_h__ + diff --git a/mo/src/neighborhood/moRealNeighborhood.h b/mo/src/neighborhood/moRealNeighborhood.h new file mode 100644 index 000000000..cd06e1c68 --- /dev/null +++ b/mo/src/neighborhood/moRealNeighborhood.h @@ -0,0 +1,108 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef __moRealNeighborhood_h__ +#define __moRealNeighborhood_h__ + +#include +#include "neighborhood/moRealNeighbor.h" + +template +class moRealNeighborhood : public moRndNeighborhood< Neighbor > +{ +public: + typedef typename Distrib::EOType EOT; + +protected: + Distrib & _distrib; + edoSampler & _sampler; + edoBounder & _bounder; + +public: + + moRealNeighborhood( + Distrib& distrib, + edoSampler& sampler, + edoBounder& bounder + ): _distrib(distrib), + _sampler(sampler), + _bounder(bounder) + { } + + /** + * It alway remains at least a solution in an infinite neighborhood + * @param _solution the related solution + * @return true + */ + virtual bool hasNeighbor(EOT &) + { + return true; + } + + /** + * Draw the next neighbor + * @param _solution the solution to explore + * @param _current the next neighbor + */ + virtual void next(EOT &, Neighbor & _current) + { + _current.bounder( &_bounder ); + + // Draw a translation in the distrib, using the sampler + _current.translation( _sampler( _distrib ) ); + } + + + /** + * Initialization of the neighborhood + * @param _solution the solution to explore + * @param _current the first neighbor + */ + virtual void init(EOT & _solution, Neighbor & _current) + { + // there is no difference between an init and a random draw + next( _solution, _current ); + } + /** + * There is always a solution in an infinite neighborhood + * @param _solution the solution to explore + * @return true + */ + virtual bool cont(EOT &) + { + return true; + } + + /** + * Return the class Name + * @return the class name as a std::string + */ + virtual std::string className() const { + return "moRealNeighborhood"; + } + +}; + +#endif // __moRealNeighborhood_h__ diff --git a/mo/src/sampling/moMHBestFitnessCloudSampling.h b/mo/src/sampling/moMHBestFitnessCloudSampling.h index ebba8a3b9..e9c71f35b 100644 --- a/mo/src/sampling/moMHBestFitnessCloudSampling.h +++ b/mo/src/sampling/moMHBestFitnessCloudSampling.h @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -87,7 +87,7 @@ public: delete localSearch; // Metropolis-Hasting sampling - localSearch = new moMetropolisHasting(_neighborhood, _fullEval, _eval, _nbStep); + localSearch = new moMetropolisHastings(_neighborhood, _fullEval, _eval, _nbStep); // delete the checkpoint with the wrong continuator delete checkpoint; diff --git a/mo/src/sampling/moMHRndFitnessCloudSampling.h b/mo/src/sampling/moMHRndFitnessCloudSampling.h index 292d42344..2a3cca639 100644 --- a/mo/src/sampling/moMHRndFitnessCloudSampling.h +++ b/mo/src/sampling/moMHRndFitnessCloudSampling.h @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -87,7 +87,7 @@ public: delete localSearch; // Metropolis-Hasting sampling - localSearch = new moMetropolisHasting(_neighborhood, _fullEval, _eval, _nbStep); + localSearch = new moMetropolisHastings(_neighborhood, _fullEval, _eval, _nbStep); // delete the checkpoint with the wrong continuator delete checkpoint; diff --git a/mo/src/sampling/moStdDevEstimator.h b/mo/src/sampling/moStdDevEstimator.h new file mode 100644 index 000000000..63afb6d24 --- /dev/null +++ b/mo/src/sampling/moStdDevEstimator.h @@ -0,0 +1,134 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#ifndef __moStdDevEstimator_h__ +#define __moStdDevEstimator_h__ + +#include +#include + +#include // TODO rm +#include // TODO rm + // TODO make tests + + +template< class EOT, class Neighbor > +class moStdDevEstimator : public eoUF +{ +public: + + /** + * General constructor for the estimator + * @param continuator a user-defined continuator + * @param neighborhood the neighborhood + * @param fullEval the full evaluation function + * @param eval neighbor's evaluation function + * @param walker a local search algorithm + */ + moStdDevEstimator ( + moContinuator& continuator, + moNeighborhood& neighborhood, + eoEvalFunc& fullEval, + + /* The following should be read: + moEval& eval = _default_eval + * (which is not possible to achieve as is in C++) */ + const eoOptional< moEval >& eval = eoOptional< moEval >::null, + + const eoOptional< moLocalSearch >& walker = eoOptional< moLocalSearch >::null + ) + : _default_eval ( fullEval ), + _eval(eval.hasValue()? eval.get(): _default_eval), + _default_continuator( 0 ), + _continuator( _continuator ), + _checkpoint( _continuator ), + _default_walker( neighborhood, fullEval, _eval, _checkpoint ), + _walker( walker.hasValue()? walker.get(): _default_walker ) + { + _checkpoint.add( _varStat ); + } + + /** + * Simpler constructor for the estimator + * @param max_iters the number of steps the default moIterContinuator should perform + * @param neighborhood the neighborhood + * @param fullEval the full evaluation function + * @param eval neighbor's evaluation function + * @param walker a local search algorithm + */ + moStdDevEstimator ( + unsigned int max_iters, + moNeighborhood < Neighbor > & neighborhood, + eoEvalFunc& fullEval, + const eoOptional< moEval >& eval = eoOptional< moEval >::null, + const eoOptional< moLocalSearch >& walker = eoOptional< moLocalSearch >::null + ) + : _default_eval ( fullEval ), + _eval(eval.hasValue()? eval.get(): _default_eval), + _default_continuator( max_iters, false ), + _continuator( _default_continuator ), + _checkpoint( _continuator ), + _default_walker( neighborhood, fullEval, _eval, _checkpoint ), + _walker( walker.hasValue()? walker.get(): _default_walker ) + { + _checkpoint.add( _varStat ); + } + + /** + * Evaluates the estimator with the walker algorithm and returns the standard deviation + * @param solution the solution from where to start the walk + */ + double operator()( EOT & solution ) + { + _walker(solution); + return sqrt(_varStat.value()); + } + + /** + * @return the class name + */ + virtual std::string className(void) const { + return "moStdDevEstimator"; + } + +private: + + moFullEvalByCopy _default_eval; + moEval& _eval; + + moIterContinuator _default_continuator; + moContinuator & _continuator; + + moCheckpoint _checkpoint; + + moRandomWalk _default_walker; + moLocalSearch _walker; + + moFitnessVarianceStat _varStat; +}; + +#endif // __moStdDevEstimator_h__ + + diff --git a/mo/test/CMakeLists.txt b/mo/test/CMakeLists.txt index 652b66be3..898e6e22d 100644 --- a/mo/test/CMakeLists.txt +++ b/mo/test/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories(${EO_SRC_DIR}/src) include_directories(${MO_SRC_DIR}/src) +include_directories(${EDO_SRC_DIR}/src) include_directories(${PROBLEMS_SRC_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -37,7 +38,7 @@ set (TEST_LIST t-moNeutralHCexplorer t-moFirstImprHCexplorer t-moRandomWalkExplorer - t-moMetropolisHastingExplorer + t-moMetropolisHastingsExplorer t-moRandomNeutralWalkExplorer t-moTSexplorer t-moSolComparator @@ -51,7 +52,7 @@ set (TEST_LIST t-moMonOpPerturb t-moRestartPerturb t-moNeighborhoodPerturb - t-moSAexplorer + t-moSAExplorer t-moSA t-moLocalSearch t-moILSexplorer @@ -64,7 +65,7 @@ set (TEST_LIST t-moILS t-moDummyLS t-moRandomSearch - t-moMetropolisHasting + t-moMetropolisHastings t-moNeutralHC t-moRandomWalk t-moRandomNeutralWalk @@ -94,7 +95,11 @@ set (TEST_LIST t-moStatistics t-moIndexedVectorTabuList # t-moRndIndexedVectorTabuList + t-moFitnessVarianceStat + t-moStdDevEstimator t-moDynSpanCoolingSchedule + t-moTriki + t-moTrikiReal ) ###################################################################################### diff --git a/mo/test/t-moDynSpanCoolingSchedule.cpp b/mo/test/t-moDynSpanCoolingSchedule.cpp index 7bef4ad59..da67008ea 100755 --- a/mo/test/t-moDynSpanCoolingSchedule.cpp +++ b/mo/test/t-moDynSpanCoolingSchedule.cpp @@ -48,38 +48,38 @@ int main() { assert(temperature == 100); //temperature must not changed 2* - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 100); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 100); assert(test(temperature)); //then temperature must be /10 - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 10); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 10); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 10); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 1); std::cout << "\n"; assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); std::cout << "\n"; assert(temperature == 1); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); std::cout << "\n"; assert(temperature == 1); assert(test(temperature)); - test.update(temperature, 0); + test.update(temperature, 0, sol); assert(temperature == 0.1); assert(!test(temperature)); diff --git a/mo/test/t-moFitnessVarianceStat.cpp b/mo/test/t-moFitnessVarianceStat.cpp new file mode 100644 index 000000000..a1510a831 --- /dev/null +++ b/mo/test/t-moFitnessVarianceStat.cpp @@ -0,0 +1,66 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +//----------------------------------------------------------------------------- +// t-moFitnessNeighborStat.cpp +//----------------------------------------------------------------------------- + +#include +#include "es/eoReal.h" +#include "continuator/moFitnessVarianceStat.h" +#include "neighborhood/moRealNeighbor.h" +#include "neighborhood/moRealNeighborhood.h" + +//----------------------------------------------------------------------------- + +typedef eoReal< eoMinimizingFitness > EOT; +typedef moRealNeighbor< EOT > Neighbor; + +double objective_function(const EOT & sol) +{ + double sum = 0; + + for ( size_t i = 0; i < sol.size(); ++i ) + { + sum += sol[i] * sol[i]; + } + + return sum; +} + +int main(int ac, char** av) +{ + moFitnessVarianceStat stat; + eoEvalFuncPtr< EOT, double > eval( objective_function ); + EOT solution(2, 5); + eval(solution); + stat(solution); + solution[0] = solution[1] = 0; + solution.invalidate(); + eval(solution); + stat(solution); + std::cout << "var: " << stat.value() << std::endl; + assert(stat.value() == 625); +} diff --git a/mo/test/t-moMetropolisHasting.cpp b/mo/test/t-moMetropolisHastings.cpp similarity index 81% rename from mo/test/t-moMetropolisHasting.cpp rename to mo/test/t-moMetropolisHastings.cpp index 638c64bd8..6bab6c332 100644 --- a/mo/test/t-moMetropolisHasting.cpp +++ b/mo/test/t-moMetropolisHastings.cpp @@ -1,5 +1,5 @@ /* - + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau @@ -31,7 +31,7 @@ Contact: paradiseo-help@lists.gforge.inria.fr #include #include -#include +#include #include "moTestClass.h" #include #include @@ -40,7 +40,7 @@ Contact: paradiseo-help@lists.gforge.inria.fr int main() { - std::cout << "[t-moMetropolisHasting] => START" << std::endl; + std::cout << "[t-moMetropolisHastings] => START" << std::endl; bitNeighborhood nh(4); oneMaxEval fullEval; @@ -50,15 +50,15 @@ int main() { moNeighborComparator ncomp; //test du 1er constructeur - moMetropolisHasting test1(nh, fullEval, eval, 3); + moMetropolisHastings test1(nh, fullEval, eval, 3); //test du 2eme constructeur - moMetropolisHasting test2(nh, fullEval, eval, 3, cont); + moMetropolisHastings test2(nh, fullEval, eval, 3, cont); //test du 3eme constructeur - moMetropolisHasting test3(nh, fullEval, eval, 3, cont, ncomp, sncomp); + moMetropolisHastings test3(nh, fullEval, eval, 3, cont, ncomp, sncomp); - std::cout << "[t-moMetropolisHasting] => OK" << std::endl; + std::cout << "[t-moMetropolisHastings] => OK" << std::endl; return EXIT_SUCCESS; } diff --git a/mo/test/t-moMetropolisHastingExplorer.cpp b/mo/test/t-moMetropolisHastingsExplorer.cpp similarity index 87% rename from mo/test/t-moMetropolisHastingExplorer.cpp rename to mo/test/t-moMetropolisHastingsExplorer.cpp index 6214465a1..b7504486d 100644 --- a/mo/test/t-moMetropolisHastingExplorer.cpp +++ b/mo/test/t-moMetropolisHastingsExplorer.cpp @@ -1,5 +1,5 @@ /* - + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau @@ -27,7 +27,7 @@ ParadisEO WebSite : http://paradiseo.gforge.inria.fr Contact: paradiseo-help@lists.gforge.inria.fr */ -#include +#include #include "moTestClass.h" #include @@ -36,7 +36,7 @@ Contact: paradiseo-help@lists.gforge.inria.fr int main() { - std::cout << "[t-moMetropolisHastingExplorer] => START" << std::endl; + std::cout << "[t-moMetropolisHastingsExplorer] => START" << std::endl; //Instanciation eoBit sol(4, true); @@ -46,7 +46,8 @@ int main() { moNeighborComparator ncomp; moSolNeighborComparator sncomp; - moMetropolisHastingExplorer test(nh, eval, ncomp, sncomp, 3); + //moSimpleMetropolisHastingsExplorer test(nh, eval, ncomp, sncomp, 3); + moSimpleMetropolisHastingsExplorer test(nh, eval, 3, sncomp); //test de l'acceptation d'un voisin améliorant test.initParam(sol); @@ -90,7 +91,7 @@ int main() { test(sol); assert(!test.accept(sol)); - std::cout << "[t-moMetropolisHastingExplorer] => OK" << std::endl; + std::cout << "[t-moMetropolisHastingsExplorer] => OK" << std::endl; return EXIT_SUCCESS; } diff --git a/mo/test/t-moSA.cpp b/mo/test/t-moSA.cpp index b1cdfeb67..3c67865cb 100644 --- a/mo/test/t-moSA.cpp +++ b/mo/test/t-moSA.cpp @@ -51,12 +51,12 @@ int main() { //test second constructor moSimpleCoolingSchedule cool(10, 0.9, 100, 0.01); - moSA test2(nh, fullEval, eval, cool); + moSA test2(nh, fullEval, cool, eval); //test third constructor moTrueContinuator cont; moSolNeighborComparator comp; - moSA test3(nh, fullEval, eval, cool, comp, cont); + moSA test3(nh, fullEval, cool, eval, cont, comp); std::cout << "[t-moSA] => OK" << std::endl; diff --git a/mo/test/t-moSAexplorer.cpp b/mo/test/t-moSAExplorer.cpp similarity index 89% rename from mo/test/t-moSAexplorer.cpp rename to mo/test/t-moSAExplorer.cpp index 4c619ff88..873dbf080 100644 --- a/mo/test/t-moSAexplorer.cpp +++ b/mo/test/t-moSAExplorer.cpp @@ -1,5 +1,5 @@ /* - + Copyright (C) DOLPHIN Project-Team, INRIA Lille - Nord Europe, 2006-2010 Sébastien Verel, Arnaud Liefooghe, Jérémie Humeau @@ -32,12 +32,12 @@ Contact: paradiseo-help@lists.gforge.inria.fr #include #include "moTestClass.h" -#include +#include #include int main() { - std::cout << "[t-moSAexplorer] => START" << std::endl; + std::cout << "[t-moSAExplorer] => START" << std::endl; eoBit sol(4, true); sol.fitness(4); @@ -47,8 +47,8 @@ int main() { moSolNeighborComparator sncomp; moSimpleCoolingSchedule cool(10,0.1,2,0.1); - moSAexplorer test1(emptyNH, eval, sncomp, cool); - moSAexplorer test2(nh, eval, sncomp, cool); + moSAExplorer test1(emptyNH, eval, cool, sncomp); + moSAExplorer test2(nh, eval, cool, sncomp); //test d'un voisinage vide test1.initParam(sol); @@ -80,7 +80,7 @@ int main() { - std::cout << "[t-moSAexplorer] => OK" << std::endl; + std::cout << "[t-moSAExplorer] => OK" << std::endl; return EXIT_SUCCESS; } diff --git a/mo/test/t-moSimpleCoolingSchedule.cpp b/mo/test/t-moSimpleCoolingSchedule.cpp index b2f8cca17..dc78c6870 100644 --- a/mo/test/t-moSimpleCoolingSchedule.cpp +++ b/mo/test/t-moSimpleCoolingSchedule.cpp @@ -48,38 +48,38 @@ int main() { assert(temperature==100); //temperature must not changed 2* - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==100); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==100); assert(test(temperature)); //then temperature must be /10 - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==10); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==10); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==10); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature == 1); std::cout<< "\n"; assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); std::cout<< "\n"; assert(temperature==1); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); std::cout<< "\n"; assert(temperature==1); assert(test(temperature)); - test.update(temperature,0); + test.update(temperature,0,sol); assert(temperature==0.1); assert(!test(temperature)); diff --git a/mo/test/t-moStdDevEstimator.cpp b/mo/test/t-moStdDevEstimator.cpp new file mode 100644 index 000000000..6473ffceb --- /dev/null +++ b/mo/test/t-moStdDevEstimator.cpp @@ -0,0 +1,86 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +//----------------------------------------------------------------------------- +// t-moStdDevEstimator.cpp +//----------------------------------------------------------------------------- + +#include +#include "es/eoReal.h" +#include "neighborhood/moRealNeighbor.h" + +//Representation and initializer +#include +//#include +#include + +// fitness function +#include + +//Neighbors and Neighborhoods +#include +#include + +//Sampling +#include + + +//----------------------------------------------------------------------------- +// Define types of the representation solution, different neighbors and neighborhoods +//----------------------------------------------------------------------------- +typedef eoInt Queen; //Permutation (Queen's problem representation) + +typedef moShiftNeighbor shiftNeighbor; //shift Neighbor +typedef moRndWithReplNeighborhood rndShiftNeighborhood; //rnd shift Neighborhood (Indexed) + +//----------------------------------------------------------------------------- + +typedef eoReal< eoMinimizingFitness > EOT; +typedef moRealNeighbor< EOT > Neighbor; + +int main(int ac, char** av) +{ + unsigned vecSize = 8; + + queenEval fullEval; + + eoInitPermutation init(vecSize); + + rndShiftNeighborhood rndShiftNH((vecSize-1) * (vecSize-1)); + + Queen solution; + + init(solution); + + fullEval(solution); + + moStdDevEstimator initTemp (500, rndShiftNH, fullEval); + + double temp = initTemp(solution); + + std::cout << "temp: " << temp << std::endl; + + assert(temp >= 0); +} diff --git a/mo/test/t-moTriki.cpp b/mo/test/t-moTriki.cpp new file mode 100644 index 000000000..d8f5e7119 --- /dev/null +++ b/mo/test/t-moTriki.cpp @@ -0,0 +1,155 @@ +//============================================================================ +// Name : Trikitest.cpp +// Author : +// Version : +// Copyright : Your copyright notice +// Description : Hello World in C++, Ansi-style +//============================================================================ + +//#define HAVE_GNUPLOT + +#include +using namespace std; + +#include +#include + +//Representation and initializer +#include +#include +#include + +/* +// fitness function +#include +#include +#include + +//Neighbors and Neighborhoods +#include +#include + +//Algorithm and its components +#include +#include + +//comparator +#include + +//continuators +#include +#include +#include +#include +#include +*/ + +//----------------------------------------------------------------------------- +// Define types of the representation solution, different neighbors and neighborhoods +//----------------------------------------------------------------------------- +typedef eoInt Queen; //Permutation (Queen's problem representation) + +typedef moShiftNeighbor shiftNeighbor; //shift Neighbor +typedef moRndWithReplNeighborhood rndShiftNeighborhood; //rnd shift Neighborhood (Indexed) + + + + +int main() { + //cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! + //return 0; + + unsigned vecSize = 8; + + + queenEval fullEval; + + + /* ========================================================= + * + * Initilization of the solution + * + * ========================================================= */ + + eoInitPermutation init(vecSize); + + /* ========================================================= + * + * evaluation of a neighbor solution + * + * ========================================================= */ + + moFullEvalByCopy shiftEval(fullEval); /// by default + + /* ========================================================= + * + * the neighborhood of a solution + * + * ========================================================= */ + + rndShiftNeighborhood rndShiftNH((vecSize-1) * (vecSize-1)); + + /* ========================================================= + * + * the cooling schedule of the process + * + * ========================================================= */ + + /* ========================================================= + * + * the local search algorithm + * + * ========================================================= */ + + /* ========================================================= + * + * execute the local search from random solution + * + * ========================================================= */ + + Queen solution1; + + init(solution1); + + fullEval(solution1); + + moStdDevEstimator initTemp (500, rndShiftNH, fullEval); + + moTrueContinuator continuator; + moCheckpoint checkpoint(continuator); + moFitnessStat fitStat; + checkpoint.add(fitStat); + eoFileMonitor monitor("triki.out", ""); + eoGnuplot1DMonitor monitor2("trikignu.out", true); + moCounterMonitorSaver countMon(100, monitor); + checkpoint.add(countMon); + moCounterMonitorSaver gnuMon (1, monitor2); + checkpoint.add(gnuMon); + monitor.add(fitStat); + monitor2.add(fitStat); + //#ifdef HAVE_GNUPLOT + + + moTrikiCoolingSchedule coolingSchedule(rndShiftNH, shiftEval, initTemp(solution1)); + moSA localSearch1(rndShiftNH, fullEval, coolingSchedule, shiftEval, checkpoint); + + + std::cout << "#########################################" << std::endl; + std::cout << "initial solution1: " << solution1 << std::endl ; + + localSearch1(solution1); + + std::cout << "final solution1: " << solution1 << std::endl ; + std::cout << "#########################################" << std::endl; + + + +} + + + + + + + + diff --git a/mo/test/t-moTrikiReal.cpp b/mo/test/t-moTrikiReal.cpp new file mode 100644 index 000000000..0ee694652 --- /dev/null +++ b/mo/test/t-moTrikiReal.cpp @@ -0,0 +1,164 @@ +/* + +(c) Thales group, 2010 + + 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: +Lionel Parreaux + +*/ + +#include +#include +#include +#include + +#include + +#include "neighborhood/moRealNeighbor.h" +#include "neighborhood/moRealNeighborhood.h" + +#include "sampling/moStdDevEstimator.h" + +#include "coolingSchedule/moTrikiCoolingSchedule.h" + + +typedef eoReal< eoMinimizingFitness > EOT; +typedef moRealNeighbor< EOT > Neighbor; + +double objective_function(const EOT & sol) +{ + double sum = 0; + + for ( size_t i = 0; i < sol.size(); ++i ) + { + sum += sol[i] * sol[i]; + } + + return sum; +} + +int main( int ac, char** av ) +{ + eoParser parser( ac, av ); + + eoState state; + + eoEvalFuncPtr< EOT, double > eval( objective_function ); + moFullEvalByCopy< Neighbor > neval( eval ); + + int dimSize = 20; + + //------------------------------------------------------- + // Parameters + //------------------------------------------------------- + + std::string section( "Temperature initialization paramaters" ); + + unsigned int dimension_size = parser.getORcreateParam( (unsigned int)dimSize, "dimension-size", "Dimension size", 'd', section ).value(); + double jump_bound = parser.getORcreateParam( (double)1, "jump-bound", "Bound of jump", '\0', section ).value(); + unsigned int maxiter = parser.getORcreateParam( (unsigned int)10, "max-iter", "Maximum number of iterations", '\0', section ).value(); + + //------------------------------------------------------- + + + //------------------------------------------------------- + // Instanciate needed classes + //------------------------------------------------------- + + edoUniform< EOT > distrib( EOT(dimension_size, -1 * jump_bound), EOT(dimension_size, 1 * jump_bound) ); + + edoBounder< EOT > bounder_search( EOT(dimension_size, -10), EOT(dimension_size, 10) ); + + edoSamplerUniform< EOT > sampler( bounder_search ); + + moRealNeighborhood< edoUniform< EOT >, Neighbor > neighborhood( distrib, sampler, bounder_search ); + + moStdDevEstimator< EOT, Neighbor > init( maxiter, neighborhood, eval ); + + //------------------------------------------------------- + + + + + //------------------------------------------------------- + // Help + Verbose routines + //------------------------------------------------------- + + if (parser.userNeedsHelp()) + { + parser.printHelp(std::cout); + exit(1); + } + + make_help(parser); + + //------------------------------------------------------- + + + EOT solution(dimSize, 5); + + std::cout << "init temp: " + << init( solution ) + << std::endl; + + + + + moTrueContinuator continuator; + moCheckpoint checkpoint(continuator); + moFitnessStat fitStat; + checkpoint.add(fitStat); + eoFileMonitor monitor("triki.out", ""); + //eoGnuplot1DMonitor monitor2("trikignu.out", true); + moCounterMonitorSaver countMon(1, monitor); + checkpoint.add(countMon); + //moCounterMonitorSaver gnuMon (1, monitor2); + //checkpoint.add(gnuMon); + monitor.add(fitStat); + //monitor2.add(fitStat); + + + + moTrikiCoolingSchedule coolingSchedule ( + neighborhood, neval, init( solution ), + //50, + 200, //150, + //100 + 350 // 250 + ); + //moSA localSearch(neighborhood, eval, neval, coolingSchedule, checkpoint); + //moSA localSearch(neighborhood, eval, neval); + //moSA localSearch(neighborhood, eval, coolingSchedule, neval, checkpoint); + //moSA localSearch(neighborhood, eval, coolingSchedule); + moSA localSearch(neighborhood, eval, coolingSchedule, neval, checkpoint); + + std::cout << "#########################################" << std::endl; + std::cout << "initial solution1: " << solution << std::endl ; + + localSearch(solution); + + std::cout << "final solution1: " << solution << std::endl ; + std::cout << "#########################################" << std::endl; + + + return 0; +} + + + diff --git a/problems/eval/queenEval.h b/problems/eval/queenEval.h index da8dd9ee3..daaed9220 100644 --- a/problems/eval/queenEval.h +++ b/problems/eval/queenEval.h @@ -40,17 +40,17 @@ class queenEval : public eoEvalFunc { public: - /** - * Count number of threat - * @param _queen a solution - */ + /** + * Count number of threat + * @param _queen a solution + */ void operator()(EOT& _queen){ - unsigned int fit=0; - for(unsigned int i=0; i<_queen.size()-1; i++) - for(unsigned int j=i+1; j< _queen.size(); j++) - if(((unsigned int)_queen[i]+j-i == (unsigned int)_queen[j]) || ((unsigned int)_queen[i]+i-j == (unsigned int)_queen[j])) - fit++; - _queen.fitness(fit); + unsigned int fit=0; + for(unsigned int i=0; i<_queen.size()-1; i++) + for(unsigned int j=i+1; j< _queen.size(); j++) + if(((unsigned int)_queen[i]+j-i == (unsigned int)_queen[j]) || ((unsigned int)_queen[i]+i-j == (unsigned int)_queen[j])) + fit++; + _queen.fitness(fit); } };