00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "CKGeneticAlgorithm1.h"
00014
00015 CKGeneticAlgorithm1::CKGeneticAlgorithm1(QMCObjectiveFunction * function,
00016 int populationsize,
00017 double mutationrate,
00018 double distributionwidth)
00019 {
00020 OF = function;
00021 PopulationSize = populationsize;
00022 MutationRate = mutationrate;
00023 InitialDistributionWidth = distributionwidth;
00024 }
00025
00026 void CKGeneticAlgorithm1::initializePopulation(Array1D<double> &initialguess)
00027 {
00028 Array1D < Array1D<double> > ParamArray(PopulationSize);
00029
00030
00031 ParamArray(0) = initialguess;
00032
00033
00034 for(int i=1; i<ParamArray.dim1(); i++)
00035 {
00036 Array1D<double> Parameters = initialguess;
00037 mutate(Parameters, InitialDistributionWidth);
00038 ParamArray(i) = Parameters;
00039 }
00040
00041
00042
00043 sw.reset();
00044 sw.start();
00045 Array1D <QMCObjectiveFunctionResult> OFresults = OF->evaluate( ParamArray );
00046 sw.stop();
00047
00048
00049 Population.clear();
00050 for(int i=0; i<ParamArray.dim1(); i++)
00051 {
00052 ParameterScorePair PSP(OFresults(i),ParamArray(i) );
00053
00054 Population.add( PSP );
00055 }
00056 }
00057
00058 void CKGeneticAlgorithm1::mutate(Array1D<double>& parameters, double width)
00059 {
00060
00061
00062
00063
00064 for(int i=0; i<parameters.dim1(); i++)
00065 {
00066 double change;
00067 do {
00068 change = width*ran.gasdev();
00069 } while(parameters(i) + change <= 5e-2);
00070 parameters(i) += change;
00071 }
00072 }
00073
00074 Array1D<double> CKGeneticAlgorithm1::crossover(Array1D<double> &Parent1,
00075 Array1D<double> &Parent2)
00076 {
00077 Array1D<double> result(Parent1.dim1());
00078
00079 for(int i=0; i<result.dim1(); i++)
00080 {
00081 double alpha = ran.unidev();
00082 result(i) = alpha * Parent1(i) + (1.0-alpha) * Parent2(i);
00083 }
00084
00085 return result;
00086 }
00087
00088 int CKGeneticAlgorithm1::selectParent()
00089 {
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 return int( Population.size() * ( 1-sqrt( 1-ran.unidev() ) ) );
00100 }
00101
00102 void CKGeneticAlgorithm1::generateNewPopulation()
00103 {
00104
00105
00106
00107 Array1D < Array1D<double> > NewParameters(PopulationSize);
00108
00109 for(int i=0; i<PopulationSize; i++)
00110 {
00111 ParameterScorePair Parent1 = Population.get( selectParent() );
00112 ParameterScorePair Parent2 = Population.get( selectParent() );
00113
00114
00115 Array1D<double> Child = crossover( *Parent1.getParameters(),
00116 *Parent2.getParameters());
00117
00118
00119
00120
00121
00122
00123 int numHigh = (int)(0.1 * PopulationSize);
00124 if(i < numHigh) mutate( Child, InitialDistributionWidth );
00125 else mutate( Child, MutationRate );
00126
00127 NewParameters(i) = Child;
00128 }
00129
00130
00131 sw.reset();
00132 sw.start();
00133 Array1D <QMCObjectiveFunctionResult> OFresults =
00134 OF->evaluate( NewParameters );
00135 sw.stop();
00136
00137
00138 for(int i=0; i<PopulationSize; i++)
00139 {
00140 ParameterScorePair PSP(OFresults(i),NewParameters(i) );
00141
00142 Population.add( PSP );
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152 int numToKeep = min(100,PopulationSize);
00153 Population.resize(numToKeep);
00154 }
00155
00156 Array1D<double> CKGeneticAlgorithm1::optimize(Array1D<double> & InitialGuess,
00157 QMCDerivativeProperties & dp,
00158 double misc, int optStep)
00159 {
00160 initializePopulation(InitialGuess);
00161
00162 bool done = false;
00163 int step = 0;
00164
00165 while( !done )
00166 {
00167 step++;
00168
00169
00170
00171 if(step > 1)
00172 generateNewPopulation();
00173
00174 cout << "\nIteration: " << step << " took (" << sw << ")" << endl;
00175
00176
00177
00178
00179
00180 int numToShow = 10;
00181 if(numToShow > min(100,PopulationSize))
00182 numToShow = min(100,PopulationSize);
00183
00184 for(int i=0; i<numToShow; i++)
00185 {
00186 printf("%3i) ",i);
00187 cout << Population.get(i);
00188 }
00189
00190
00191 if( step > 3 )
00192 {
00193 done = true;
00194 }
00195 }
00196
00197
00198
00199
00200
00201 return *Population.get(0).getParameters();
00202 }
00203