Differential Evolution C++ library
C:/dev/de/differentialevolution/selection_strategy.hpp
00001 /*
00002  * Copyright (c) 2011 Adrian Michel
00003  * http://www.amichel.com
00004  *
00005  * Permission to use, copy, modify, distribute and sell this 
00006  * software and its documentation for any purpose is hereby 
00007  * granted without fee, provided that both the above copyright 
00008  * notice and this permission notice appear in all copies and in 
00009  * the supporting documentation. 
00010  *  
00011  * This library is distributed in the hope that it will be 
00012  * useful. However, Adrian Michel makes no representations about
00013  * the suitability of this software for any purpose.  It is 
00014  * provided "as is" without any express or implied warranty. 
00015  * 
00016  * Should you find this library useful, please email 
00017  * info@amichel.com with a link or other reference 
00018  * to your work. 
00019 */
00020 
00021 #ifndef DE_SELECTION_STRATEGY_HPP_INCLUDED
00022 #define DE_SELECTION_STRATEGY_HPP_INCLUDED
00023 
00024 // MS compatible compilers support #pragma once
00025 
00026 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00027 #pragma once
00028 #endif
00029 
00030 #include "population.hpp"
00031 
00032 namespace de
00033 {
00034 
00044 class selection_strategy
00045 {
00046 public:
00047         virtual ~selection_strategy(){}
00048 
00061         virtual void operator()( population_ptr& pop1, population_ptr& pop2, individual_ptr& bestInd, bool minimize ) = 0;
00062 };
00063 
00067 typedef boost::shared_ptr< selection_strategy > selection_strategy_ptr;
00068 
00077 class best_parent_child_selection_strategy : public selection_strategy
00078 {
00079 public:
00092         void operator()( population_ptr& pop1, population_ptr& pop2, individual_ptr& bestInd, bool minimize )
00093         {
00094                 assert( pop1 );
00095                 assert( pop2 );
00096 
00097                 assert( pop1->size() == pop2->size() );
00098 
00099                 sort_across( *pop1, *pop2, minimize );
00100 
00101                 // this is the best
00102                 bestInd = (*pop1)[ 0 ];
00103         }
00104 
00105 private:
00106         class individual_compare
00107         {
00108         private:
00109                 const bool m_minimize;
00110 
00111         public:
00112                 individual_compare( bool minimize )
00113                 : m_minimize( minimize )
00114                 {
00115                 }
00116 
00117                 bool operator()( individual_ptr ind1, individual_ptr ind2 )
00118                 {
00119                         assert( ind1 && ind2 );
00120 
00121                         return ind1->better( ind2, m_minimize );
00122                 }
00123         };
00124 
00125         void sort_across( population& v1, population& v2, bool minimize  )
00126         {
00127                 v1.insert( v1.end(), v2.begin(), v2.end() );
00128                 v2.clear();
00129 
00130                 std::sort( v1.begin(), v1.end(), individual_compare( minimize ) );
00131 
00132                 v2.insert( v2.end(), v1.begin() + v1.size() / 2, v1.end() );
00133 
00134                 v1.erase( v1.begin() + v1.size()/2, v1.end() );
00135         }
00136 };
00137 
00145 class tournament_selection_strategy : public selection_strategy
00146 {
00147 public:
00160         void operator()( population_ptr& pop1, population_ptr& pop2, individual_ptr& bestInd, bool minimize )
00161         {
00162                 assert( pop1 );
00163                 assert( pop2 );
00164 
00165                 assert( pop1->size() == pop2->size() );
00166 
00167                 for( size_t i = 0; i < pop1->size(); ++i )
00168                 {
00169                         individual_ptr crt( (*pop2)[ i ] );
00170 
00171                         if( crt->better_or_equal( (*pop1 )[ i ], minimize ) )
00172                         {
00173                                 if( crt->better_or_equal( bestInd, minimize ) )
00174                                         bestInd = crt;
00175                         }
00176                         else
00177                                 (*pop2)[ i ] = (*pop1)[ i ];
00178 
00179                 }
00180 
00181                 std::swap( pop1, pop2 );
00182         }
00183 };
00184 
00185 }
00186 
00187 #endif //DE_SELECTION_STRATEGY_HPP_INCLUDED