use normal distribution on initial random individual creation
initial default range tweaked way down rename "POP" template parameter to "POPSIZE" added RunOneGeneration() method - generations can now be run one at a time added SetRange(i,min,max) method added a decent amount of comments through main algorithm and class declaration
This commit is contained in:
1 parent
c194ae5fc5
commit
6f03c0b106
5 files changed
+267
-113
No files matched your search
@@ -8,9 +8,8 @@
|
||||
|
||||
namespace DE
|
||||
{
|
||||
|
||||
|
||||
template <unsigned int DIM, unsigned int POP=(DIM*10)>
|
||||
template <unsigned int DIM, unsigned int POPSIZE=(DIM*10)>
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
@@ -18,58 +17,69 @@ namespace DE
|
||||
Engine();
|
||||
virtual ~Engine();
|
||||
|
||||
void Reset();
|
||||
|
||||
const double* GetBest() const;
|
||||
|
||||
void SetRange(double minimum, double maximum);
|
||||
void SetRange(unsigned int i, double minimum, double maximum);
|
||||
void SetRange(const Vector<DIM>& minimum, const Vector<DIM>& maximum);
|
||||
|
||||
virtual double CalculateError(const double testcase[DIM], bool& stop) = 0;
|
||||
|
||||
void Reset();
|
||||
bool Solve(unsigned int maxgenerations = 1000000000);
|
||||
bool RunOneGeneration();
|
||||
|
||||
private:
|
||||
|
||||
void Select(unsigned int candidate, unsigned int *r1 = 0, unsigned int *r2 = 0, unsigned int *r3 = 0, unsigned int *r4 = 0, unsigned int *r5 = 0);
|
||||
// randomly select unique individuals
|
||||
void Select(
|
||||
unsigned int candidate,
|
||||
unsigned int *r1 = 0,
|
||||
unsigned int *r2 = 0,
|
||||
unsigned int *r3 = 0,
|
||||
unsigned int *r4 = 0,
|
||||
unsigned int *r5 = 0
|
||||
);
|
||||
|
||||
// print a single individual to stdout
|
||||
void Dump(const double& fitness, Vector<DIM>& individual) const;
|
||||
|
||||
void MakeTrial_best1exp(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand1exp(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_randtobest1exp(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_best2exp(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand2exp(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_best1bin(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand1bin(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_randtobest1bin(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_best2bin(unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand2bin(unsigned int candidate, Vector<DIM>& trial);
|
||||
|
||||
private:
|
||||
// DE algorithm
|
||||
void MakeTrial_best1exp (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand1exp (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_randtobest1exp (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_best2exp (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand2exp (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_best1bin (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand1bin (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_randtobest1bin (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_best2bin (unsigned int candidate, Vector<DIM>& trial);
|
||||
void MakeTrial_rand2bin (unsigned int candidate, Vector<DIM>& trial);
|
||||
|
||||
// constants, parameters
|
||||
static const double DEFAULTSCALE;
|
||||
static const double DEFAULTCROSSOVER;
|
||||
static const double DEFAULTRANGE;
|
||||
static const double BIGDOUBLE;
|
||||
double scale;
|
||||
double crossover;
|
||||
|
||||
// entropy source
|
||||
Random prng;
|
||||
|
||||
private:
|
||||
|
||||
Random prng;
|
||||
|
||||
// population
|
||||
Vector<DIM> best;
|
||||
Vector<DIM> minimum;
|
||||
Vector<DIM> maximum;
|
||||
Vector<DIM> population[POP];
|
||||
double fitness[POP];
|
||||
|
||||
double scale;
|
||||
double crossover;
|
||||
Vector<DIM> mean;
|
||||
Vector<DIM> variance;
|
||||
Vector<DIM> population[POPSIZE];
|
||||
double fitness[POPSIZE];
|
||||
double bestfitness;
|
||||
|
||||
};
|
||||
// algorithm state
|
||||
bool success;
|
||||
unsigned int generation;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -10,43 +10,44 @@
|
||||
#endif
|
||||
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
const double DE::Engine<DIM,POP>::DEFAULTSCALE = 0.85;
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
const double DE::Engine<DIM,POPSIZE>::DEFAULTSCALE = 0.85;
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
const double DE::Engine<DIM,POP>::DEFAULTCROSSOVER = 1.0;
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
const double DE::Engine<DIM,POPSIZE>::DEFAULTCROSSOVER = 1.0;
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
const double DE::Engine<DIM,POP>::DEFAULTRANGE= 100.0;
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
const double DE::Engine<DIM,POPSIZE>::DEFAULTRANGE= 0.1;
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
const double DE::Engine<DIM,POP>::BIGDOUBLE = 1.79e308; // close to max double
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
const double DE::Engine<DIM,POPSIZE>::BIGDOUBLE = 1.79e308; // close to max double
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline DE::Engine<DIM,POP>::Engine()
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline DE::Engine<DIM,POPSIZE>::Engine()
|
||||
{
|
||||
// set defaults
|
||||
scale = DEFAULTSCALE;
|
||||
crossover = DEFAULTCROSSOVER;
|
||||
|
||||
for ( unsigned int i=0;i<DIM;i++ )
|
||||
for ( unsigned int i=0;i<DIM;++i )
|
||||
{
|
||||
this->minimum[i] = -DEFAULTRANGE;
|
||||
this->maximum[i] = -(this->minimum[i]);
|
||||
this->mean[i] = 0.0;
|
||||
this->variance[i] = DEFAULTRANGE;
|
||||
}
|
||||
|
||||
// create an initial population
|
||||
Reset();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline DE::Engine<DIM,POP>::~Engine()
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline DE::Engine<DIM,POPSIZE>::~Engine()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::Reset()
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::Reset()
|
||||
{
|
||||
// reset our best
|
||||
bestfitness = BIGDOUBLE;
|
||||
@@ -56,7 +57,7 @@ inline void DE::Engine<DIM,POP>::Reset()
|
||||
}
|
||||
|
||||
// reset all vectors
|
||||
for ( unsigned int i=0;i<POP;i++ )
|
||||
for ( unsigned int i=0;i<POPSIZE;i++ )
|
||||
{
|
||||
// energy tied for worst
|
||||
fitness[i] = bestfitness;
|
||||
@@ -64,48 +65,72 @@ inline void DE::Engine<DIM,POP>::Reset()
|
||||
// make a new individual
|
||||
for ( unsigned int j=0;j<DIM;j++ )
|
||||
{
|
||||
population[i][j] = prng.RandDouble(minimum[j],maximum[j]);
|
||||
population[i][j] = prng.RandGaussian(mean[j],variance[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// reset state
|
||||
generation = 0;
|
||||
success = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::SetRange(double minimum, double maximum)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::SetRange(double minimum, double maximum)
|
||||
{
|
||||
for (unsigned int i=0;i<DIM;i++)
|
||||
{
|
||||
this->minimum[i] = minimum;
|
||||
this->maximum[i] = maximum;
|
||||
SetRange(i,minimum,maximum);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::SetRange(const Vector<DIM>& minimum, const Vector<DIM>& maximum)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::SetRange(unsigned int i, double minimum, double maximum)
|
||||
{
|
||||
this->minimum = minimum;
|
||||
this->maximum = maximum;
|
||||
if (i<DIM)
|
||||
{
|
||||
this->mean[i] = (maximum+minimum)/2.0;
|
||||
this->variance[i] = (maximum-minimum)/2.0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline const double* DE::Engine<DIM,POP>::GetBest() const
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::SetRange(const Vector<DIM>& minimum, const Vector<DIM>& maximum)
|
||||
{
|
||||
for (unsigned int i=0;i<DIM;i++)
|
||||
{
|
||||
SetRange(i,minimum[i],maximum[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline const double* DE::Engine<DIM,POPSIZE>::GetBest() const
|
||||
{
|
||||
return best;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::Select(unsigned int candidate, unsigned int *r1, unsigned int *r2, unsigned int *r3, unsigned int *r4, unsigned int *r5)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::Select(
|
||||
unsigned int candidate,
|
||||
unsigned int *r1,
|
||||
unsigned int *r2,
|
||||
unsigned int *r3,
|
||||
unsigned int *r4,
|
||||
unsigned int *r5
|
||||
)
|
||||
{
|
||||
if ( r1 )
|
||||
{
|
||||
do
|
||||
{
|
||||
*r1 = prng.RandU32(0,POP-1);
|
||||
*r1 = prng.RandU32(0,POPSIZE-1);
|
||||
}
|
||||
while ( *r1 == candidate );
|
||||
}
|
||||
@@ -114,7 +139,7 @@ inline void DE::Engine<DIM,POP>::Select(unsigned int candidate, unsigned int *r1
|
||||
{
|
||||
do
|
||||
{
|
||||
*r2 = prng.RandU32(0,POP-1);
|
||||
*r2 = prng.RandU32(0,POPSIZE-1);
|
||||
}
|
||||
while ( (*r2 == candidate) || (*r2 == *r1) );
|
||||
}
|
||||
@@ -123,7 +148,7 @@ inline void DE::Engine<DIM,POP>::Select(unsigned int candidate, unsigned int *r1
|
||||
{
|
||||
do
|
||||
{
|
||||
*r3 = prng.RandU32(0,POP-1);
|
||||
*r3 = prng.RandU32(0,POPSIZE-1);
|
||||
}
|
||||
while ( (*r3 == candidate) || (*r3 == *r2) || (*r3 == *r1) );
|
||||
}
|
||||
@@ -132,7 +157,7 @@ inline void DE::Engine<DIM,POP>::Select(unsigned int candidate, unsigned int *r1
|
||||
{
|
||||
do
|
||||
{
|
||||
*r4 = prng.RandU32(0,POP-1);
|
||||
*r4 = prng.RandU32(0,POPSIZE-1);
|
||||
}
|
||||
while ( (*r4 == candidate) || (*r4 == *r3) || (*r4 == *r2) || (*r4 == *r1) );
|
||||
}
|
||||
@@ -141,7 +166,7 @@ inline void DE::Engine<DIM,POP>::Select(unsigned int candidate, unsigned int *r1
|
||||
{
|
||||
do
|
||||
{
|
||||
*r5 = prng.RandU32(0,POP-1);
|
||||
*r5 = prng.RandU32(0,POPSIZE-1);
|
||||
}
|
||||
while ( (*r5 == candidate) || (*r5 == *r4) || (*r5 == *r3) || (*r5 == *r2) || (*r5 == *r1) );
|
||||
}
|
||||
@@ -149,49 +174,66 @@ inline void DE::Engine<DIM,POP>::Select(unsigned int candidate, unsigned int *r1
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: change this to run one generation at a time???
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline bool DE::Engine<DIM,POP>::Solve(unsigned int maxgenerations)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline bool DE::Engine<DIM,POPSIZE>::Solve(unsigned int maxgenerations)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// spawn a new generation
|
||||
Reset();
|
||||
|
||||
for (unsigned int generation=0;generation<maxgenerations && !success;generation++)
|
||||
// run generations until max or success
|
||||
while(!success && generation<maxgenerations)
|
||||
{
|
||||
printf("====== GENERATION %07d =============================================\n\n",generation);
|
||||
success = RunOneGeneration();
|
||||
}
|
||||
|
||||
for (int candidate=0;candidate<POP && !success;candidate++)
|
||||
// output
|
||||
printf("====== RUN COMPLETE =============================================\n\n");
|
||||
Dump(bestfitness,best);
|
||||
|
||||
// finished
|
||||
return success;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
bool DE::Engine<DIM,POPSIZE>::RunOneGeneration()
|
||||
{
|
||||
printf("====== GENERATION %07d =============================================\n\n",++generation);
|
||||
|
||||
// attempt to improve each individual in the population
|
||||
for (int candidate=0;candidate<POPSIZE && !success;candidate++)
|
||||
{
|
||||
// create a new trial individual to test
|
||||
Vector<DIM> trial;
|
||||
MakeTrial_randtobest1exp(candidate,trial);
|
||||
|
||||
// determine fitness of trial individual
|
||||
double trialfitness = CalculateError(trial,success);
|
||||
|
||||
// see if the trial improved current candidate in population
|
||||
if ( trialfitness < fitness[candidate] )
|
||||
{
|
||||
Vector<DIM> trial;
|
||||
MakeTrial_randtobest1exp(candidate,trial);
|
||||
// it did improve, save it
|
||||
fitness[candidate] = trialfitness;
|
||||
population[candidate] = trial;
|
||||
|
||||
double trialfitness = CalculateError(trial,success);
|
||||
|
||||
if ( trialfitness < fitness[candidate] )
|
||||
// see if it also improved upon our current best
|
||||
if ( trialfitness < bestfitness )
|
||||
{
|
||||
fitness[candidate] = trialfitness;
|
||||
population[candidate] = trial;
|
||||
// it's better than the best, save it
|
||||
bestfitness = trialfitness;
|
||||
best = trial;
|
||||
|
||||
if ( trialfitness < bestfitness )
|
||||
{
|
||||
bestfitness = trialfitness;
|
||||
best = trial;
|
||||
|
||||
Dump(bestfitness,best);
|
||||
}
|
||||
// output new best
|
||||
Dump(bestfitness,best);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("====== RUN COMPLETE =============================================\n\n");
|
||||
Dump(bestfitness,best);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::Dump(const double& fitness, DE::Vector<DIM>& individual) const
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::Dump(const double& fitness, DE::Vector<DIM>& individual) const
|
||||
{
|
||||
printf(" fitness = %24.16f\n",fitness);
|
||||
for (unsigned int i=0;i<DIM;i++)
|
||||
@@ -201,8 +243,8 @@ inline void DE::Engine<DIM,POP>::Dump(const double& fitness, DE::Vector<DIM>& in
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_best1exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_best1exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2;
|
||||
unsigned int n;
|
||||
@@ -220,8 +262,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_best1exp(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_rand1exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_rand1exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2, r3;
|
||||
unsigned int n;
|
||||
@@ -239,8 +281,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_rand1exp(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_randtobest1exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_randtobest1exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2;
|
||||
unsigned int n;
|
||||
@@ -258,8 +300,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_randtobest1exp(unsigned int candidate
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_best2exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_best2exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2, r3, r4;
|
||||
unsigned int n;
|
||||
@@ -277,8 +319,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_best2exp(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_rand2exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_rand2exp(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2, r3, r4, r5;
|
||||
unsigned int n;
|
||||
@@ -296,8 +338,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_rand2exp(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_best1bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_best1bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2;
|
||||
unsigned int n;
|
||||
@@ -318,8 +360,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_best1bin(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_rand1bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_rand1bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2, r3;
|
||||
unsigned int n;
|
||||
@@ -340,8 +382,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_rand1bin(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_randtobest1bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_randtobest1bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2;
|
||||
unsigned int n;
|
||||
@@ -362,8 +404,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_randtobest1bin(unsigned int candidate
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_best2bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_best2bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2, r3, r4;
|
||||
unsigned int n;
|
||||
@@ -384,8 +426,8 @@ inline void DE::Engine<DIM,POP>::MakeTrial_best2bin(unsigned int candidate, DE::
|
||||
return;
|
||||
}
|
||||
|
||||
template <unsigned int DIM, unsigned int POP>
|
||||
inline void DE::Engine<DIM,POP>::MakeTrial_rand2bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
template <unsigned int DIM, unsigned int POPSIZE>
|
||||
inline void DE::Engine<DIM,POPSIZE>::MakeTrial_rand2bin(unsigned int candidate, DE::Vector<DIM>& trial)
|
||||
{
|
||||
unsigned int r1, r2, r3, r4, r5;
|
||||
unsigned int n;
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace DE
|
||||
|
||||
double RandDouble();
|
||||
double RandDouble(double min, double max);
|
||||
|
||||
double RandGaussian(double mean, double variance);
|
||||
|
||||
u32 RandU32();
|
||||
u32 RandU32(u32 min, u32 max);
|
||||
|
||||
+10
@@ -50,6 +50,16 @@ inline double DE::Random::RandDouble(double min, double max)
|
||||
return ( RandDouble() * (max - min) + min );
|
||||
}
|
||||
|
||||
inline double DE::Random::RandGaussian(double mean, double variance)
|
||||
{
|
||||
double sum = 0.0;
|
||||
for (int i=0;i<12;++i)
|
||||
{
|
||||
sum += RandDouble();
|
||||
}
|
||||
return mean + ( variance * ( sum - 6.0 ) );
|
||||
}
|
||||
|
||||
inline DE::u32 DE::Random::RandU32()
|
||||
{
|
||||
return Rand();
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
|
||||
#include "de.h"
|
||||
|
||||
// the order of the polynomial (actually the number of coefficients, i.e. 1 = constant, 2 = line, etc.)
|
||||
#define NUM_COEFFICIENTS 7
|
||||
|
||||
// the function we're searching for
|
||||
double TargetFunction(double x)
|
||||
{
|
||||
//return 1.0 / (1.0 + exp(-4.9*x)); // Ken Stanley's NEAT activation
|
||||
return (1.0 / (1.0 + exp(-4.9*x)) - 0.5) * 2.0; // " " (signed version)
|
||||
//return (1.0 / (1.0 + exp(-x)) - 0.5) * 2.0; // signed sigmoid
|
||||
//return exp(-x*x); // gaussian
|
||||
//return tanh(x); // tanh
|
||||
//return (2.0/(1.0+exp(-x))-1.0); // tanh approximation
|
||||
//return (x<0.0 ? -1.0 : 1.0) * sqrt(abs(x)); // signed root
|
||||
//return sin(x); // sin
|
||||
}
|
||||
|
||||
|
||||
// a helper function used in calculating the polynomials
|
||||
double CalculatePiecewise(double x, int n_coeffs, const double coeffs[])
|
||||
{
|
||||
double abs_x = (x < 0.0 ? -x : x);
|
||||
const double* pcoeffs;
|
||||
if ( abs_x < coeffs[6] )
|
||||
pcoeffs = &coeffs[0];
|
||||
else
|
||||
pcoeffs = &coeffs[3];
|
||||
|
||||
return (pcoeffs[0] + pcoeffs[1]*abs_x + pcoeffs[2]*abs_x*abs_x) * (x < 0.0 ? -1.0 : 1.0);
|
||||
}
|
||||
|
||||
|
||||
// our DE implementation
|
||||
class PolySearch: public DE::Engine<NUM_COEFFICIENTS>
|
||||
{
|
||||
public:
|
||||
// this method is called by the DE::Engine::Solve() to test a single DE individual
|
||||
double CalculateError(const double testcase[NUM_COEFFICIENTS], bool& stop)
|
||||
{
|
||||
double error = 0.0;
|
||||
unsigned int test_count = 0;
|
||||
|
||||
// accumulate squared error
|
||||
for ( double i=-2.5;i<=2.5;i+=0.01 )
|
||||
{
|
||||
// test
|
||||
double test = CalculatePiecewise(i,NUM_COEFFICIENTS,testcase);
|
||||
double actual = TargetFunction(i);
|
||||
|
||||
// accumulate error^2
|
||||
double e = test - actual;
|
||||
error += e * e;
|
||||
|
||||
// inc test count (divisor to get from SE to MSE)
|
||||
test_count++;
|
||||
}
|
||||
|
||||
// convert SE to RMSE
|
||||
error = sqrt(error / (double)test_count);
|
||||
|
||||
// set stop flag if the error is really low
|
||||
if ( error < 0.0000001 )
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
|
||||
// done
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// main program
|
||||
int main()
|
||||
{
|
||||
PolySearch de;
|
||||
|
||||
// setup, adjust from default range
|
||||
//de.SetRange(-0.1,0.1);
|
||||
|
||||
// reset, and run the DE
|
||||
de.Solve(1000);
|
||||
|
||||
// done
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user