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

📄 create.cc

📁 genetic programming in C++ Adam Fraser University Of Salford, Salford, M5 4WT, United Kingdom
💻 CC
字号:
// create.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
//--------------------------------------------------------------------------


//   Creates a GP oddly enough...
// Version 0.40 23 February 1994 Adam Fraser

#include "gp.hpp"
#include "function.hpp"
#include "terminal.hpp"
// for random number generator
#include "gprand.hpp"

// for memory allocation
#include <stdlib.h>


// two more naughty global variables just used in this function basically
// because at the moment it was too fiddly to change and I knew the old
// create functions work so I just bolted adf stuff on top. There are more
// elegant methods without global var. I am sure answers on a postcard.....
FS *FunctionSet;
TS *TerminalSet;

// This block of code creates a GP GP::Create is called within the population
// constructor function with the correct creation type and depth. GP::Create
// then calls one of two type of created gene tree Gene::CreateVariable
// and Gene::CreateGrow which have their respective createchildren block.

// RECENT IMPROVEMENTS

// Automatically defined functions the rest has been kept the same....

// Added a new random number generator to guarantee portability....


// MAIN CODE....
										

//  Notes: This code makes a function the first node this is in line with
// Koza's LISP code and does make the trees more interesting but it is not
//  necessary....
// Version 0.40 incorporating adf's
void GP::Create( unsigned int ctype, int allowabledepth )
{
	int newallowabledepth;  // as allowabledepth value is changed by program...

// allocate memory for pointer to the adf gene headers......................
	if ( !(ppgHeader = (Gene **)calloc( RootandADF, sizeof(Gene*) ) ) )
		ExitSystem( "GP::Create" );              // set up pointer of pointer to Gene

// point to the starting tree................................................
	Gene **ppg = ppgHeader;

// loop through each adf
	for ( unsigned int adf = 0; adf < RootandADF; adf++, ppg++ )
	{
// set the function and terminal set to correct ADF (most interesting work is when
// these are different for each aff );
		FunctionSet = FunctionSets[adf];   
		TerminalSet = TerminalSets[adf];  

// set up newallowabledepth
		newallowabledepth = allowabledepth;

// choose a function from function set complies with Genetic Programming book or code
		Function *tempfunc = FunctionSet->Choose();

// create a new gene and copy this function into it setting next member to NULL
// ie that it is not a function argument................
		if ( !(*ppg = new Gene) ) ExitSystem("GP::Create");
		(*ppg)->iValue = function( tempfunc );
		(*ppg)->pgNext = NULL;

// child is allocated some memory
		if ( !((*ppg)->pgChild = new Gene) ) ExitSystem("GP::Create");


// switch statement calls the correct function corresponding to the creation type
// defined by the user to create gene function  child
		switch ( ctype )
		{
// GROW fills up all tree down to 0 depth
			case GROW :
				(*ppg)->pgChild->CreateGrowChildren( arguments(tempfunc),--newallowabledepth );
				break;

// variable does whatever it likes with depth limits this is default...
			default :
				(*ppg)->pgChild->CreateVariableChildren( arguments(tempfunc),   --newallowabledepth );
				break;
		}
	}

// calculate the length on newly created genetic program...
	Length();
}

// Variable GPs can be function and terminal at any point up to the maximum depth
// when they must be terminals
void Gene::CreateVariable( int allowabledepth )
{
// if at maximum depth...................
	if ( allowabledepth == 0 )
	{
// ...........choose from the terminal set
		iValue = terminal( TerminalSet->Choose() );
// if the value you have chosen is RandomReal make iValue = random value in the range
// of 0 -> NumberOfDifferentValues set by user  these numbers go above 32768......
		if ( iValue == RandomReal ) iValue = gp_rand() % NumberOfDifferentValues + 32768;
// set child == NULL
		pgChild = NULL;
	}
// otherwise...
	else
	{
// ...choose from function and terminal with 50% chance of either.....
		if ( gp_rand() % 2 )        // 50/50 chance of getting func or term
		{
// ................choose from function set..
			Function *tempfunc = FunctionSet->Choose();
// set gene value to that of selected function
			iValue = function( tempfunc );
// create a new child as we have a function
			if ( !(pgChild = new Gene) )    ExitSystem( "Gene::CreateVariable" );
// and set child up to create new function group with correct number of arguments
			pgChild->CreateVariableChildren( arguments( tempfunc ), --allowabledepth );
		}
		else
		{
// ...........choose from the terminal set
			iValue = terminal( TerminalSet->Choose() );
// if the value you have chosen is RandomReal make iValue = random value in the range
// of 0 -> NumberOfDifferentValues set by user  these numbers go above 32768......
			if ( iValue == RandomReal )     iValue = gp_rand() % NumberOfDifferentValues + 32768;
			pgChild = NULL;
		}
	}
}

// create the children when CreateVariable has selected function
// value is the number of arguments of the function
void Gene::CreateVariableChildren( int value, int allowabledepth )
{
// create a new branch of the tree.
	CreateVariable( allowabledepth );
// if there are any more arguments......
	if ( value > 1 )
	{
// create next members
		if ( !(pgNext = new Gene) ) ExitSystem( "GP::CreateVariableChildren" );
// and create new children.
		pgNext->CreateVariableChildren( --value, allowabledepth );
	}
}

// Grow GPs have to select functions until maximum depth has been reached when they
// must then select terminals
void Gene::CreateGrow( int allowabledepth )
{
	// if at maximum depth...................
	if ( allowabledepth == 0 )
	{
// ...........choose from the terminal set
		iValue = terminal( TerminalSet->Choose() );
// if the value you have chosen is RandomReal make iValue = random value in the range
// of 0 -> NumberOfDifferentValues set by user  these numbers go above 32768......
		if ( iValue == RandomReal ) iValue = gp_rand() % NumberOfDifferentValues + 32768;
// set child == NULL
		pgChild = NULL;
	}
	else
	{
// ................choose from function set..
			Function *tempfunc = FunctionSet->Choose();
// set gene value to selected function
			iValue = function( tempfunc );
// create a new child as we have a function
			if ( !(pgChild = new Gene) )    ExitSystem( "Gene::CreateGrow" );
// and set child up to create new function group with correct number of arguments
			pgChild->CreateGrowChildren( arguments( tempfunc ), --allowabledepth );
		}
}

// create the children when CreateGrow has selected function
// value is the number of arguments of the function
void Gene::CreateGrowChildren( int value, int allowabledepth )
{
// create a new branch of the tree.
	CreateGrow( allowabledepth );
// if there are any more arguments......
	if ( value > 1 )
	{
// create next members
		if ( !(pgNext = new Gene) ) ExitSystem( "GP::CreateGrowChildren" );
// and create new children.
		pgNext->CreateGrowChildren( --value, allowabledepth );
	}
}

// create.cc

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -