📄 create.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 + -