Evocosm - A C++ Framework for Evolutionary Computing

Main Index

Created by Scott Robert Ladd at Coyote Gulch Productions.


migrator.h

00001 /*
00002     Evocosm is a heterogenous collection of mathematical tools,  written in Standard C.
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_MIGRATOR_H)
00054 #define LIBEVOCOSM_MIGRATOR_H
00055 
00056 // libevocosm
00057 #include "organism.h"
00058 
00059 namespace libevocosm
00060 {
00062 
00070     template <class OrganismType>
00071     class migrator : protected globals
00072     {
00073     public:
00075 
00082         virtual ~migrator()
00083         {
00084             // nada
00085         }
00086 
00088 
00098         virtual void migrate(vector< population<OrganismType> >  & a_populations) = 0;
00099     };
00100 
00102 
00107     template <class OrganismType>
00108     class null_migrator : public migrator<OrganismType>
00109     {
00110     public:
00112 
00116         virtual void migrate(vector< population<OrganismType> >  & a_populations)
00117         {
00118             // nada
00119         }
00120     };
00121 
00123 
00128     template <class OrganismType>
00129     class random_pool_migrator : public migrator<OrganismType>
00130     {
00131     public:
00133 
00136         random_pool_migrator(size_t a_how_many)
00137           : m_how_many(a_how_many)
00138         {
00139             // nada
00140         }
00141 
00143 
00147         virtual void migrate(vector< population<OrganismType> > & a_populations)
00148         {
00149             // don't do anything is the value is zero
00150             if (m_how_many == 0)
00151                 return;
00152 
00153             // get this value now so we don't keep calling size()
00154             size_t pop_count = a_populations.size();
00155 
00156             // keeps track of how many organisms have change in a given population
00157             size_t * move_count = new size_t [pop_count];
00158 
00159             for (size_t n = 0; n < pop_count; ++n)
00160                 move_count[n] = 0;
00161 
00162             // migrate organisms
00163             for (size_t p = 0; p < pop_count; ++p)
00164             {
00165                 // don't move any more organisms if this population is at its limit
00166                 if (move_count[p] < m_how_many)
00167                 {
00168                     size_t pop_size = a_populations[p].size();
00169                     size_t number_to_move = m_how_many - move_count[p];
00170 
00171                     for (size_t n = 0; n < number_to_move; ++n);
00172                     {
00173                         // pick a random organism
00174                         size_t org1 = globals::rand_index(pop_size);
00175 
00176                         // pick another population
00177                         size_t trader = globals::rand_index(pop_count);
00178 
00179                         // Sequential search for someone who hasn't reached their trade limit;
00180                         // can't keep randomly selecting because we might never hit the "one"
00181                         // open trader late in the sequence. Can't skip the current "p"
00182                         // population because it might be the only one that hasn't swapped yet!
00183                         while (move_count[trader] >= m_how_many)
00184                         {
00185                             ++trader;
00186 
00187                             if (trader == pop_count)
00188                                 trader = 0;
00189                         }
00190 
00191                         if (trader != p)
00192                         {
00193                             // pick random member of other population
00194                             size_t org2 = globals::rand_index(a_populations[trader].size());
00195 
00196                             // exchange organisms
00197                             OrganismType temp = a_populations[p][org1];
00198                             a_populations[p][org1] = a_populations[trader][org2];
00199                             a_populations[trader][org2] = temp;
00200 
00201                             // increment counts
00202                             ++move_count[p];
00203                             ++move_count[trader];
00204                         }
00205                     }
00206                 }
00207             }
00208 
00209             delete [] move_count;
00210         }
00211 
00212     private:
00213         // How many to migrate
00214         size_t m_how_many;
00215     };
00216 
00217 };
00218 
00219 #endif

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