00001 #include "stdafx.h" 00002 #include <cfloat> 00003 #include <cmath> 00004 #include <algorithm> 00005 00006 #include "GAOptimizer.h" 00007 #include "Random.h" 00008 00009 namespace GAOptimizer 00010 { 00011 00012 bool genotypeCompare( IGenotype* elem1, IGenotype* elem2 ) 00013 { 00014 return (elem1->m_fitness > elem2->m_fitness); 00015 } 00016 00017 TestGenoType::TestGenoType() 00018 { 00019 random(); 00020 } 00021 00022 void TestGenoType::derive( IGenotype * parent1, IGenotype * parent2 ) 00023 { 00024 m_x = ((TestGenoType*)parent1)->m_x + 0.05 * Random::nextGaussian(); 00025 } 00026 00027 void TestGenoType::random() 00028 { 00029 m_x = Random::nextDouble(); 00030 } 00031 00032 IGenotype * TestProblem::createRandomSolution() 00033 { 00034 return new TestGenoType(); 00035 } 00036 00037 double TestProblem::evaluteSolution( IGenotype * solution ) 00038 { 00039 double x = ((TestGenoType*)solution)->m_x; 00040 return sin(10*x)+0.4*sin(5*(x+4)); 00041 } 00042 00043 Optimizer::Optimizer() 00044 { 00045 m_problem = NULL; 00046 m_bestSolution = NULL; 00047 } 00048 00049 Optimizer::~Optimizer() 00050 { 00051 clear(); 00052 } 00053 00054 void Optimizer::clear() 00055 { 00056 for( unsigned int i=0; i<m_population.size(); ++i ) 00057 delete m_population[i]; 00058 m_population.clear(); 00059 m_subPopulation.clear(); 00060 m_problem = NULL; 00061 m_bestSolution = NULL; 00062 } 00063 00064 00065 void Optimizer::init( IProblem * problem, int populationSize, int subPopulationSize ) 00066 { 00067 clear(); 00068 00069 m_problem = problem; 00070 m_populationSize = populationSize; 00071 m_subPopulationSize = subPopulationSize; 00072 00073 // initialize population with random solutions, find the best individal 00074 m_maxFitness = -DBL_MAX; 00075 m_population.resize( m_populationSize ); 00076 for( int i=0; i<m_populationSize; ++i ) 00077 { 00078 m_population[i] = m_problem->createRandomSolution(i); 00079 m_population[i]->m_fitness = m_problem->evaluteSolution(m_population[i]); 00080 if( m_population[i]->m_fitness > m_maxFitness ) 00081 { 00082 m_maxFitness = m_population[i]->m_fitness; 00083 m_bestSolution = m_population[i]; 00084 } 00085 } 00086 00087 // create subpopulation 00088 m_subPopulation.resize( m_subPopulationSize ); 00089 00090 m_bestIndNum = (int)floor(0.2 * m_subPopulationSize + 0.5); 00091 m_firstBadInd = m_subPopulationSize - m_bestIndNum; 00092 } 00093 00094 void Optimizer::step() 00095 { 00096 int i; 00097 00098 // select random subpopulation 00099 for( i=0; i<m_subPopulationSize; ++i ) 00100 m_subPopulation[i] = m_population[Random::nextInt(m_populationSize)]; 00101 00102 // sort subpopulation 00103 std::sort( m_subPopulation.begin(), m_subPopulation.end(), genotypeCompare ); 00104 00105 // generate new individuals 00106 for( i=m_firstBadInd; i<m_subPopulationSize; ++i ) 00107 { 00108 IGenotype * parent1 = m_subPopulation[Random::nextInt(m_bestIndNum)]; 00109 IGenotype * parent2 = m_subPopulation[Random::nextInt(m_bestIndNum)]; 00110 IGenotype * child = m_subPopulation[i]; 00111 00112 if( child != m_bestSolution && child != parent1 && child != parent2 && parent1 != parent2 ) 00113 { 00114 child->derive( parent1, parent2 ); 00115 m_subPopulation[i]->m_fitness = m_problem->evaluteSolution( m_subPopulation[i] ); 00116 00117 if( m_subPopulation[i]->m_fitness > m_maxFitness ) 00118 { 00119 m_maxFitness = m_subPopulation[i]->m_fitness; 00120 m_bestSolution = m_subPopulation[i]; 00121 } 00122 } 00123 } 00124 } 00125 00126 void Optimizer::step( int n ) 00127 { 00128 for( int i=0; i<n; ++i ) 00129 step(); 00130 } 00131 00132 IGenotype * Optimizer::getBest() 00133 { 00134 return m_bestSolution; 00135 } 00136 00137 GenotypeVec& Optimizer::getPopulation() 00138 { 00139 return m_population; 00140 } 00141 00142 double Optimizer::getMaxFitness() 00143 { 00144 return m_maxFitness; 00145 } 00146 00147 }