GeneticAlgorithm.h

Go to the documentation of this file.
00001 // ---------------------------------------------------------------------------
00002 // $Id: GeneticAlgorithm.h 230 2008-08-14 01:45:04Z daaugusto $
00003 //
00004 //   GeneticAlgorithm.h (created on Tue Nov 08 01:08:35 BRT 2005)
00005 // 
00006 //   Genetic Algorithm File Fitter (gaffitter)
00007 //
00008 //   Copyright (C) 2005-2008 Douglas A. Augusto
00009 // 
00010 // This file is part of gaffitter.
00011 // 
00012 // gaffitter is free software; you can redistribute it and/or modify it
00013 // under the terms of the GNU General Public License as published by the
00014 // Free Software Foundation; either version 3 of the License, or (at
00015 // your option) any later version.
00016 // 
00017 // gaffitter is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // General Public License for more details.
00021 // 
00022 // You should have received a copy of the GNU General Public License
00023 // along with gaffitter; if not, see <http://www.gnu.org/licenses/>.
00024 //
00025 // ---------------------------------------------------------------------------
00026 
00027 #ifndef GeneticAlgorithm_hh
00028 #define GeneticAlgorithm_hh
00029 
00030 #include "../Input.h"
00031 #include "../util/Random.h"
00032 #include "../Optimizer.h"
00033 
00034 #include <vector>
00035 #include <iterator>
00036 
00037 static const Params::Size_t WORST_FITNESS = 0.0;
00038 static const Params::Size_t BEST_FITNESS = 1.0;
00039 
00040 // ---------------------------------------------------------------------------
00050 class Individual {
00051 public:
00054    Individual(): m_fitness( WORST_FITNESS ) {}
00055 
00058    Params::Size_t Fitness() const { return m_fitness; }
00061    void Fitness( Params::Size_t f ) { m_fitness = f; }
00062 
00069    bool operator==( const Individual& i ) const
00070    {
00071       if( !AlmostEqual( Fitness(), i.Fitness() ) ) return false;
00072 
00073       return Genome() == i.Genome();
00074    }
00075 
00079    friend bool operator>( Individual &a, Individual &b ) 
00080    { 
00081       return a.m_fitness > b.m_fitness; 
00082    }
00083 
00087    BinSet& Genome() { return m_genome; }
00091    const BinSet& Genome() const { return m_genome; }
00092 
00096    Bin& Genome(int i) { return m_genome[i]; }
00100    const Bin& Genome(int i) const { return m_genome[i]; }
00101 
00102 public:
00103    BinSet m_genome; 
00105    Params::Size_t m_fitness; 
00106 };
00107 
00108 // ---------------------------------------------------------------------------
00132 class GeneticAlgorithm: public Optimizer {
00133 public:
00138    GeneticAlgorithm( Input& );
00139 private:
00141    GeneticAlgorithm( const GeneticAlgorithm& );
00143    GeneticAlgorithm& operator=( const GeneticAlgorithm& );
00144 
00145 public:
00146 
00153    void Evolve();
00154  
00158    bool Evaluate( int i ) { return Evaluate( m_individuals[i] ); }
00162    bool Evaluate( Individual& );
00163 
00164 protected:
00173    bool InitPopulation();
00174 
00182    bool Generation();
00183 
00185    Params::Size_t Fitness( int index ) const 
00186    { 
00187       return Fitness( m_individuals[index] ); 
00188    }
00189 
00194    Params::Size_t Fitness( const Individual& i ) const { return i.Fitness(); }
00195 
00197    int Select( int a, int b ) const { return Random::Int( a, b ); }
00198 
00200    int Select( int a, int b, int p ) const 
00201    { 
00202       int r = Select( a, b );
00203       
00204       // equals?
00205       if( r == p ) return r > a ? r - 1 : a + 1;
00206 
00207       return r; // Ok: 'b' not equal 'a'!
00208    }
00209 
00213    int Select( int a, int b, int p1, int p2 ) const 
00214    { 
00215       int r = Select( a, b );
00216 
00217       if( p1 > p2 ) std::swap( p1, p2 );
00218 
00219       if( r == p1 )
00220       {
00221          if( p1 == a ) return p1 + 1 == p2 ? r + 2 : r + 1;
00222          if( p1 > a ) return r - 1;
00223       }
00224 
00225       if( r == p2 )
00226       {
00227          if( p2 == b ) return p2 == p1 + 1 ? r - 2 : r - 1;
00228          if( p2 < b ) return r + 1;
00229       }
00230 
00231       return r;
00232    }
00233    
00252    bool Crossover( unsigned, unsigned, unsigned, unsigned );
00253 
00261    void Mutate( int i );
00262 
00269    std::pair<int,int> Tournament2( int, int ) const;
00270 
00277    std::pair<int,int> TournamentN( int, int ) const;
00278 
00283    std::pair<int,int> (GeneticAlgorithm::*Tournament)( int, int ) const;
00284 
00288    Individual& Individuals( int i ) { return m_individuals[i]; }
00292    const Individual& Individuals( int i ) const { return m_individuals[i]; }
00293 
00297    std::vector<Individual>& Individuals() { return m_individuals; }
00301    const std::vector<Individual>& Individuals() const { return m_individuals; }
00302    
00303    std::vector<Individual> m_individuals; 
00305    Individual m_best_individual; 
00307 public:
00314    void FirstFit( BinSet&, const std::vector<const SizeName*>& ) const;
00321    void FirstFitDecreasing( BinSet&, std::vector<const SizeName*>& ) const;
00332    void DominanceOptimizer( BinSet& bs, std::vector<const SizeName*>& 
00333                             unassigned ) const;
00334 private:
00338    int DominanceForOne( Bin& bin, std::vector<const SizeName*>& 
00339                         unassigned ) const;
00343    int DominanceForTwo( Bin& bin, std::vector<const SizeName*>& 
00344                         unassigned ) const;
00348    int DominanceForThree( Bin& bin, std::vector<const SizeName*>& 
00349                           unassigned ) const;
00350 protected:
00355    std::ostream& Write( std::ostream& ) const;
00356 
00357 private:
00358    int m_cur_gen; 
00359    unsigned m_tournament_size; 
00360 };
00361 
00362 // ---------------------------------------------------------------------------
00363 #endif