Differential Evolution C++ library
|
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_INDIVIDUAL_HPP_INCLUDED 00022 #define DE_INDIVIDUAL_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 <queue> 00031 00032 #include "de_types.hpp" 00033 #include "de_constraints.hpp" 00034 #include "multithread.hpp" 00035 00036 namespace de 00037 { 00038 00039 class individual; 00040 typedef boost::shared_ptr< individual > individual_ptr; 00041 00052 class individual 00053 { 00054 private: 00055 de::DVectorPtr m_vars; 00056 double m_cost; 00057 de::mutex m_mx; 00058 00059 public: 00067 individual( size_t varCount ) 00068 : m_vars( boost::make_shared< de::DVector >( varCount ) ) 00069 { 00070 } 00071 00080 individual( const de::DVector& vars ) 00081 : m_vars( boost::make_shared< de::DVector >( vars ) ) 00082 { 00083 } 00084 00093 void init( constraints_ptr constraints ) 00094 { 00095 assert( constraints ); 00096 assert( m_vars ); 00097 assert( m_vars->size() == constraints->size() ); 00098 00099 for( de::DVector::size_type j = 0; j < m_vars->size(); ++j ) 00100 (*m_vars)[ j ] = constraints->get_rand_value( j ); 00101 } 00102 00110 double cost() const { return m_cost; } 00111 00121 void ensureConstraints( constraints_ptr constraints, de::DVectorPtr origin ) 00122 { 00123 assert( constraints ); 00124 assert( m_vars ); 00125 assert( origin ); 00126 assert( m_vars->size() == constraints->size() ); 00127 00128 for( de::DVector::size_type j = 0; j < m_vars->size(); ++j ) 00129 { 00130 (*m_vars)[ j ] = constraints->get_rand_value( j, (*m_vars)[ j ], (*origin)[ j ] ); 00131 } 00132 } 00133 00141 de::DVectorPtr vars() const { return m_vars; } 00142 00154 de::Double& operator[]( size_t index ) { return (*m_vars)[ index ]; } 00155 00166 const de::Double& operator[]( size_t index ) const { return (*m_vars)[ index ]; } 00167 00175 void setCost( double cost ) { m_cost = cost; } 00176 00188 bool operator<=( const individual& ind ) const 00189 { 00190 assert( ind.size() == size() ); 00191 return cost() <= ind.cost(); 00192 } 00193 00205 bool operator<( const individual& ind ) const 00206 { 00207 assert( ind.size() == size() ); 00208 return cost() < ind.cost(); 00209 } 00210 00224 bool better_or_equal( const individual_ptr ind, bool minimize ) const 00225 { 00226 assert( ind ); 00227 return minimize ? *this <= *ind : *ind <= *this; 00228 } 00229 00243 bool better( const individual_ptr ind, bool minimize ) const 00244 { 00245 assert( ind ); 00246 return minimize ? *this < *ind : *ind < *this; 00247 } 00248 00256 size_t size() const { return m_vars->size(); } 00257 00266 std::string to_string() const 00267 { 00268 std::ostringstream os; 00269 00270 os << "cost: " << cost() << ", vars: "; 00271 00272 for( de::DVector::size_type j = 0; j < m_vars->size(); ++j ) 00273 { 00274 os << (*m_vars)[ j ] << ", "; 00275 } 00276 00277 return os.str(); 00278 00279 } 00280 }; 00281 00282 typedef std::queue< individual_ptr > individual_queue_base; 00283 00292 class individual_queue : public individual_queue_base 00293 { 00294 private: 00295 de::mutex m_mx; 00296 00297 public: 00307 void push_back( individual_ptr ind ) 00308 { 00309 de::lock lock( m_mx ); 00310 00311 individual_queue_base::push( ind ); 00312 } 00313 00325 individual_ptr pop() 00326 { 00327 de::lock lock( m_mx ); 00328 00329 if( !individual_queue_base::empty() ) 00330 { 00331 individual_ptr p( individual_queue_base::front() ); 00332 00333 individual_queue_base::pop(); 00334 00335 return p; 00336 } 00337 else 00338 return individual_ptr(); 00339 } 00340 }; 00341 00342 } 00343 00344 #endif //DE_INDIVIDUAL_HPP_INCLUDED