⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pop.cc

📁 genetic programming in C++ Adam Fraser University Of Salford, Salford, M5 4WT, United Kingdom
💻 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 + -