Differential Evolution C++ library
C:/dev/de/differentialevolution/individual.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_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