Evocosm - A C++ Framework for Evolutionary Computing

Main Index

Created by Scott Robert Ladd at Coyote Gulch Productions.


evocosm.h
00001 /*
00002     Evocosm is a C++ framework for implementing evolutionary algorithms.
00003 
00004     Copyright 2011 Scott Robert Ladd. All rights reserved.
00005 
00006     Evocosm is user-supported open source software. Its continued development is dependent
00007     on financial support from the community. You can provide funding by visiting the Evocosm
00008     website at:
00009 
00010         http://www.coyotegulch.com
00011 
00012     You may license Evocosm in one of two fashions:
00013 
00014     1) Simplified BSD License (FreeBSD License)
00015 
00016     Redistribution and use in source and binary forms, with or without modification, are
00017     permitted provided that the following conditions are met:
00018 
00019     1.  Redistributions of source code must retain the above copyright notice, this list of
00020         conditions and the following disclaimer.
00021 
00022     2.  Redistributions in binary form must reproduce the above copyright notice, this list
00023         of conditions and the following disclaimer in the documentation and/or other materials
00024         provided with the distribution.
00025 
00026     THIS SOFTWARE IS PROVIDED BY SCOTT ROBERT LADD ``AS IS'' AND ANY EXPRESS OR IMPLIED
00027     WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00028     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SCOTT ROBERT LADD OR
00029     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00030     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00032     ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00033     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00034     ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035 
00036     The views and conclusions contained in the software and documentation are those of the
00037     authors and should not be interpreted as representing official policies, either expressed
00038     or implied, of Scott Robert Ladd.
00039 
00040     2) Closed-Source Proprietary License
00041 
00042     If your project is a closed-source or proprietary project, the Simplified BSD License may
00043     not be appropriate or desirable. In such cases, contact the Evocosm copyright holder to
00044     arrange your purchase of an appropriate license.
00045 
00046     The author can be contacted at:
00047 
00048           scott.ladd@coyotegulch.com
00049           scott.ladd@gmail.com
00050           http:www.coyotegulch.com
00051 */
00052 
00053 #if !defined(LIBEVOCOSM_EVOCOSM_H)
00054 #define LIBEVOCOSM_EVOCOSM_H
00055 
00056 #if defined(_MSC_VER)
00057 #pragma warning (disable : 4786)
00058 #endif
00059 
00060 #if defined(_OPENMP)
00061 #include <omp.h>
00062 #endif
00063 
00064 #include <unistd.h>
00065 
00066 // Standard C++ library
00067 #include <vector>
00068 
00069 // libevocosm
00070 #include "validator.h"
00071 #include "listener.h"
00072 #include "organism.h"
00073 #include "landscape.h"
00074 #include "mutator.h"
00075 #include "reproducer.h"
00076 #include "scaler.h"
00077 #include "selector.h"
00078 #include "analyzer.h"
00079 
00081 
00090 namespace libevocosm
00091 {
00092     using std::vector;
00093 
00095 
00101     template <class OrganismType>
00102     class evocosm : protected globals
00103     {
00104     protected:
00106         vector<OrganismType> & m_population;
00107 
00109         landscape<OrganismType> & m_landscape;
00110 
00112         mutator<OrganismType> & m_mutator;
00113 
00115         reproducer<OrganismType> & m_reproducer;
00116 
00118         scaler<OrganismType> & m_scaler;
00119 
00121         selector<OrganismType> & m_selector;
00122 
00124         analyzer<OrganismType> & m_analyzer;
00125 
00127         listener<OrganismType> & m_listener;
00128 
00130         size_t m_iteration;
00131 
00133         unsigned int m_sleep_time;
00134 
00135     public:
00137 
00152         evocosm(vector<OrganismType> &     a_population,
00153                 landscape<OrganismType> &  a_landscape,
00154                 mutator<OrganismType> &    a_mutator,
00155                 reproducer<OrganismType> & a_reproducer,
00156                 scaler<OrganismType> &     a_scaler,
00157                 selector<OrganismType> &   a_selector,
00158                 analyzer<OrganismType> &   a_analyzer,
00159                 listener<OrganismType> &   a_listener);
00160 
00162 
00166         evocosm(const evocosm<OrganismType> & a_source);
00167 
00169 
00176         virtual ~evocosm();
00177 
00179 
00184         evocosm & operator = (const evocosm<OrganismType> & a_source);
00185 
00187 
00196         virtual bool run_generation();
00197 
00199 
00204         vector<OrganismType> & get_population()
00205         {
00206             return m_population;
00207         }
00208 
00210 
00214         unsigned int get_sleep_time()
00215         {
00216             return m_sleep_time;
00217         }
00218 
00220 
00224         void set_sleep_time(unsigned int a_sleep_time)
00225         {
00226             m_sleep_time = a_sleep_time;
00227         }
00228 
00229     protected:
00231 
00236         void yield()
00237         {
00238             if (m_sleep_time > 0)
00239             {
00240               #if defined(_MSC_VER)
00241                 Sleep(m_sleep_time);
00242               #else
00243                 usleep((useconds_t)m_sleep_time);
00244               #endif
00245             }
00246         }
00247 
00248     };
00249 
00250     // constructors
00251     template <class OrganismType>
00252     evocosm<OrganismType>::evocosm(vector<OrganismType> &     a_population,
00253                                    landscape<OrganismType> &  a_landscape,
00254                                    mutator<OrganismType> &    a_mutator,
00255                                    reproducer<OrganismType> & a_reproducer,
00256                                    scaler<OrganismType> &     a_scaler,
00257                                    selector<OrganismType> &   a_selector,
00258                                    analyzer<OrganismType> &   a_analyzer,
00259                                    listener<OrganismType> &   a_listener)
00260       : m_population(a_population),
00261         m_landscape(a_landscape),
00262         m_mutator(a_mutator),
00263         m_reproducer(a_reproducer),
00264         m_scaler(a_scaler),
00265         m_selector(a_selector),
00266         m_analyzer(a_analyzer),
00267         m_listener(a_listener),
00268         m_iteration(0),
00269         m_sleep_time(10000) // default to 10ms sleep time
00270     {
00271         // nada
00272     }
00273 
00274     // copy constructor
00275     template <class OrganismType>
00276     evocosm<OrganismType>::evocosm(const evocosm<OrganismType> & a_source)
00277       : m_population(a_source.a_population),
00278         m_landscape(a_source.m_landscape),
00279         m_mutator(a_source.m_mutator),
00280         m_reproducer(a_source.m_reproducer),
00281         m_scaler(a_source.m_scaler),
00282         m_selector(a_source.m_selector),
00283         m_analyzer(a_source.m_analyzer),
00284         m_listener(a_source.m_listener),
00285         m_iteration(a_source.m_iteration),
00286         m_sleep_time(a_source.m_sleep_time)
00287     {
00288         // nada
00289     }
00290 
00291     // destructor
00292     template <class OrganismType>
00293     evocosm<OrganismType>::~evocosm()
00294     {
00295         // nada
00296     }
00297 
00298     // assignment operator
00299     template <class OrganismType>
00300     evocosm<OrganismType> & evocosm<OrganismType>::operator = (const evocosm<OrganismType> & a_source)
00301     {
00302         m_population  = a_source.m_population;
00303         m_landscape   = a_source.m_landscape;
00304         m_scaler      = a_source.m_scaler;
00305         m_analyzer    = a_source.m_analyzer;
00306         m_listener    = a_source.m_analyzer;
00307         m_iteration   = a_source.m_iteration;
00308         m_sleep_time  = a_source.m_sleep_time;
00309 
00310         return *this;
00311     }
00312 
00313     // compute next generation
00314     template <class OrganismType>
00315     bool evocosm<OrganismType>::run_generation()
00316     {
00317         bool keep_going = true;
00318 
00319         OrganismType * best = NULL;
00320 
00321         ++m_iteration;
00322 
00323         // announce beginning of new generation
00324         m_listener.ping_generation_begin(m_population, m_iteration);
00325 
00326         // check population fitness
00327         m_landscape.test(m_population);
00328         yield();
00329 
00330         // we're done testing this generation
00331         m_listener.ping_generation_end(m_population, m_iteration);
00332         yield();
00333 
00334         // analyze the results of testing, and decide if we're going to stop or not
00335         keep_going = m_analyzer.analyze(m_population, m_iteration);
00336 
00337         if (keep_going)
00338         {
00339             // fitness scaling
00340             m_scaler.scale_fitness(m_population);
00341             yield();
00342 
00343             // get survivors and number of chromosomes to add
00344             vector<OrganismType> survivors = m_selector.select_survivors(m_population);
00345             yield();
00346 
00347             // give birth to new chromosomes
00348             vector<OrganismType> children = m_reproducer.breed(m_population, m_population.size() - survivors.size());
00349             yield();
00350 
00351             // debugging only
00352             //fitness_stats<OrganismType> s(survivors);
00353             //fitness_stats<OrganismType> c(children);
00354 
00355             // mutate the child chromosomes
00356             m_mutator.mutate(children);
00357             yield();
00358 
00359             // append children to survivors and replace existing population form combined vector
00360             survivors.insert(survivors.end(),children.begin(),children.end());
00361             m_population = survivors;
00362             yield();
00363         }
00364         else
00365         {
00366             m_listener.run_complete(m_population);
00367         }
00368 
00369         return keep_going;
00370     }
00371 };
00372 
00373 #endif

© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.