📄 pop.cc
字号:
// pop.cc
//--------------------------------------------------------------------------
// This code is a component of Genetic Programming in C++ (Version 0.40)
// Copyright Adam P. Fraser, 1993,1994
// This code is released for non-commercial use only.
// For comments, improvements, additions (or even money !?) contact:
// Adam Fraser, Postgraduate Section, Dept of Elec & Elec Eng,
// Maxwell Building, University Of Salford, Salford, M5 4WT, United Kingdom.
// Internet: a.fraser@eee.salford.ac.uk
// Tel: (UK) 061 745 5000 x3633
// Fax: (UK) 061 745 5999
//--------------------------------------------------------------------------
// Version 0.40 24 February 1994
// Initial code By Adam Fraser 16/11/93
// The Population class has most of the genetic programming operator applied to
// it. It inherits the GPVariable class and one of its members is a pointer to
// the GP system. Further work will probably allow the function and terminal set
// accessible through the population rather than as a global variables
// include pop class def'ns ( and also gpv, gp, gene therefore )
#include "pop.hpp"
#include <stdlib.h>
// Prints out the complete population (not used in gpcpp as it stands )
ostream& operator << ( ostream& os, Population *ppop )
{
// if population exists...
if ( ppop )
{
// point to the first member of population
GP *pgp = ppop->pgpHeader;
// pop = size of population
unsigned int pop = ppop->PopulationSize;
// while there are still members in the population keep printing and incrementing
while ( pop-- ) cout << pgp++;
}
// even though we send a reference to os it is good idea to return this
return os;
}
// Creation of the population................................................
// BugBug 16/11/93 possible infinite loop which cannot be gauged in this function
// the population is compared with every other member so pure diversity can
// be used BUT when using small depths the number of possible permutations
// drops severely. If using a small function and terminal set this could
// cause a loop. It is worth noting though is not a problem until the
// population you are trying to create becomes v.v. large...
// Fixed 06 June 1994 just loop ten times and if this doesn't create a
// genetic program which is viable then increase tree depth...
// Version 0.40 24 February 1994 using adf variables....
Population::Population( int pop, int gen ) : GPVariables( pop, gen )
{
int numbertocreate, j = 0, treedepth = 2;
// allocate memory for the population of gp headers.......
if ( !(pgpHeader = (GP *)calloc( pop, sizeof( GP ) ) ) ) ExitSystem( "Population::Population" );
// point to the first member of the population
GP *pgp = pgpHeader;
// number to create is the population for each depth to be created
numbertocreate = PopulationSize / ( MaximumDepthForCreation - 1 );
// loop through the whole population...................
for ( int i = 0; i < PopulationSize; i++, j++ )
{
// if j is greater than number for each depth reset j and increase tree depth
if ( j > numbertocreate )
{
j = 0;
if (treedepth < MaximumDepthForCreation) treedepth++;
}
// set up done boolean checks whether we have been around the next do ..while loop
unsigned int Done = 0;
do
{
// if we already have gone through this once delete old gp as we do not want memory wasted
if ( Done )
{
// check that we haven't done this ten times if so.......
if ( Done == 10 )
{
// .. then move on to the increase the maximum allowable depth
j = 0;
if (treedepth < MaximumDepthForCreation) treedepth++;
}
// setup pointer to correct area to delete
Gene **ppgDelete = pgp->ppgHeader;
// move through each adf gene header deleting as you go
for ( unsigned int adf = 0; adf < RootandADF; adf++, ppgDelete++ )
if ( *ppgDelete ) delete *ppgDelete;
// delete gene header block.................
free( pgp->ppgHeader );
}
// basically a switch statement is used to decide which type of gp creation we want...
switch (CreationType)
{
case RAMPEDHALF : // if odd create ramped grow else ramped variable
if ( i % 2 ) pgp->Create( GROW, treedepth );
else pgp->Create( VARIABLE, treedepth );
break;
case RAMPEDVARIABLE :
pgp->Create( VARIABLE, treedepth );
break;
case RAMPEDGROW :
pgp->Create( GROW, treedepth );
break;
// default is not to use ramped at all and just use either GROW or VARIABLE
default :
pgp->Create( CreationType, MaximumDepthForCreation );
break;
}
// set up boolean done to show we have been around do ..while loop before.
Done++;
// next block for ultimate diversity as it checks that each gp is different to every
// other created. As stated in the notes given above this can lead to an infinite loop
// if used with very large populations and small repetoire of functions and terminals
// the compare function returns a 1 if it finds an identical GP.
} while ( Compare( pgp ) );
// move to the next member of the population
pgp++;
}
}
// Deletes all the population ......................................................
Population::~Population()
{
// set up pgp to starting block and population size
GP *pgp = pgpHeader;
unsigned int pop = PopulationSize;
// loop through whole population
while ( pop-- )
{
// setup pointer to correct area to delete
Gene **ppgDelete = pgp->ppgHeader;
// move through each adf gene header deleting as you go
for ( unsigned int i = 0; i < RootandADF; i++, ppgDelete++ )
if ( *ppgDelete ) delete *ppgDelete;
// delete gene header block
free( pgp->ppgHeader );
// make the present the next and so on..
pgp++;
}
// clean up consecutive gp chunks....
free( pgpHeader );
}
// Returns the total summated fitness of population..........................
unsigned long Population::TotalFitness()
{
// set up starting gp, population size and summated fitness
GP *pgp = pgpHeader;
unsigned int pop = PopulationSize;
unsigned long sum = 0;
//neat, huh! The only bit of code which does anything impressive in one line...
// move through population adding up fitnesses
while ( pop-- ) sum += pgp++->iFitness;
// set population object variable to result....
uliFitness = sum;
// ....and also output result
return sum;
}
// Returns the total summated stuctural complexity of population...............
unsigned long Population::TotalLength()
{
// set up starting gp, population size and summated length
GP *pgp = pgpHeader;
unsigned int pop = PopulationSize;
unsigned long sum = 0;
// move through population adding up lengths
while ( pop-- ) sum += pgp++->iLength; // neat, huh ..2 !!!
// set population object variable to result....
uliLength = sum;
// ....and also output result
return sum;
}
// if you wish to use the depth function is some way you will have to place
// a new component in the GP class defn called iDepth....
// Why have I included this function the user cries well I have an intuitive feeling
// that some time in the future someone will say that depth is a measure of hierarchy
// and therefore a degree of complexity or **intelligence** will be produced soooo..
/*
unsigned long Population::TotalDepth()
{
GP *pgp = this;
unsigned int pop = PopulationSize;
unsigned long sum = 0;
while ( pop-- ) sum += pgp++->iDepth;
uliDepth = sum;
return sum;
}
*/
// pop.cc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -