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

📄 gplawn.cc

📁 genetic programming in C++ Adam Fraser University Of Salford, Salford, M5 4WT, United Kingdom
💻 CC
字号:
// gplawn.cpp

//--------------------------------------------------------------------------
// 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
//--------------------------------------------------------------------------



// The definitions of code to map the LawnMower problem developed by John Koza
// (& James Rice ??) into gpcpp by Adam Fraser, 1 March 1994

// Uses ADFs and is the first paper (and hence the best) on this subject I have seen.

// The paper which has this information has been submitted to Kim Kinnear (Ed)
// 'Advances in Genetic Programming' as a chapter called 'Scalable Learning in
// Genetic Programming using Automatic Function Definition' by John Koza.

// I would like to thank John Koza and James Rice for the copy of the paper
// from which I have developed the code (in one evening! Sad getalife that I am).

// and now an explanation....a paraphrasing of the introduction bit of paper

// Imagine, if you will, a lawn upon which we have placed a robot who wishes to
// evolve the ability to mow the lawn. The lawn is a sixty four grid toriodal
// world . Using standard GP the robot would have to
// evolve sixty four different moves but with new improved ADF GP its a different
// story........ and ADF GP washes whiter and is lighter than ordinary chocolate


// The function and terminals are explained in their chunks of code.....

// F(main) ={ ADF1  , 1 argument }
// T(main) = { ADF0 }

// F(adf0) = { V8A, PROG2, 2 argument each }
// T(adf0) = { LEFT, MOW, Real }

// F(adf1) = { V8A, FROG, PROG2 , 2,1,2 arguments respectively }
//NB Koza includes ADF0 in function set withargs = 0 this is a terminal, surely ??
// T(adf1) = { ARG0, LEFT, MOW, Real }

// The return values in all cases are a vector of the form (i,j) where i and j are
//  integers modulus 8. (Note this changes somewhat when Koza discusses slightly larger
// or smaller worlds which I dont deal with in this code for that reason).

#include "pop.hpp"
#include "function.hpp"
#include "terminal.hpp"

#include "lawn.hpp"
#include "mower.hpp"


FS *FunctionSets[3];       // 3 Function sets, one for root, two for ADFs
TS *TerminalSets[3];       // 3 Terminal set   ''                ''


#define FITNESS Vector
Robot Mower;

unsigned int EvaluateFitness( GP*,int );   /* These four functions MUST be included */
ostream& (*TranslatePrint)( ostream&, Gene* );
void InitialiseGPS();
void CleanUpGPS();


FITNESS (*Translate)( Gene* );

FITNESS TranslateROOT( Gene* );
FITNESS TranslateADF0( Gene* );
FITNESS TranslateADF1( Gene* );
ostream& TranslatePrintROOT( ostream&, Gene* );
ostream& TranslatePrintADF0( ostream&, Gene* );
ostream& TranslatePrintADF1( ostream&, Gene* );


// global variables both for ADFs

FITNESS glbADF0;
GP  *pgpGlobal;

// macros of how to use ADF structure
#define ROOT *(pgpGlobal->ppgHeader)
#define ADF0 *(pgpGlobal->ppgHeader + 1)
#define ADF1 *(pgpGlobal->ppgHeader + 2)



unsigned int EvaluateFitness( GP *pgp, int Evals )
{
	pgpGlobal = pgp;               // set up global variable for start of gene programs
																//  necessary to get at ADF structure, an unfortunate
															// addition to the code in my opinion....
	Mower.x = 4;
	Mower.y = 4;
	Mower.Moving = 1;                                                       // thats north
	Mower.Energy = Evals;

	CreateLawn();                                                           // grow some more grass. Quite a small lawn (8x8)

	Translate = TranslateROOT;
	while ( Mower.Energy )
	{
		Translate( ROOT );
		if ( Mower.Energy == 100 ) return 0;  // gets nought if it don't move
																					//and also stop infinite loops v.important 
	}
	return ( 64 - CheckLawn() );
}


FITNESS TranslateROOT( Gene *pg )
{
	switch ( pg->iValue )
	{
		case 1:                                                                                                  // ADF1 ->one args
		{
 // note I send the variable to ADF1 through glbADF0
      Vector vReturn;
			Translate = TranslateADF1;      
			vReturn = Translate( ADF1 );
			Translate = TranslateROOT;
      return vReturn;
    }
		case 2:
		{
			Translate = TranslateADF0;
			glbADF0 = Translate( ADF0 );   // set up global variable...
      Translate = TranslateROOT;
			return glbADF0;
		}
		default:{
							ExitSystem("TranslateMAIN" );
 // need to return something to stop warning though this will nerver be called
							return glbADF0;  
						}
	}
}

ostream& TranslatePrintROOT( ostream& os, Gene *pg )
{
	switch ( pg->iValue )
	{
		case 1:         os << " ( ADF1";       /* functions */
					break;
		case 2:         os << " ADF0";
					break;
		default:        os << "ERROR: TranslateMAIN";
							break;
	}
  return os;
}

FITNESS TranslateADF0( Gene *pg )
{
	switch ( pg->iValue )
	{
		case 1: return V8A( pg->pgChild );              // two args
		case 2: return PROG2( pg->pgChild );            // two args
		case 3: return LEFT();
		case 4: return MOW();
		default:
		{
//      and now the real number business, hope you like the way I have done it.....
			unsigned char ch = pg->iValue - 32768;  //set to begin at 0;
			Vector v_harvey;

			v_harvey.i = ch % 8;    // set the number of real numbers to 64 and then % 8
			v_harvey.j = ch / 8;    //  / 8 to get the two sets of values.

      return v_harvey;
		}
	}
}

ostream& TranslatePrintADF0( ostream& os, Gene *pg )
{
	switch ( pg->iValue )
	{
		case 1:         os << " ( V8A";       /* functions */
					break;
		case 2:         os << " ( PROG2";
					break;
		case 3:         os << " LEFT";
							break;
		case 4:         os << " MOW";
					break;
		default:
		  {
			  unsigned char ch = pg->iValue - 32768;  //set to begin at 0;
			Vector v_harvey;

			  v_harvey.i = ch % 8;    // set the number of real numbers to 64 and then % 8
			  v_harvey.j = ch / 8;    //  / 8 to get the two sets of values.

	os << " [" << (int)v_harvey.i << "," << (int)v_harvey.j << "]";
			}
			break;
	}
	return os;
}

FITNESS TranslateADF1( Gene *pg )
{
	switch ( pg->iValue )
	{
		case 1: return V8A( pg->pgChild );              // two args
		case 2: return FROG( pg->pgChild );                                                     // one arg
		case 3: return PROG2( pg->pgChild );            // two args
		case 4: return LEFT();
		case 5: return MOW();
		case 6: return glbADF0;
		default:
		{
//      and now the real number business, hope you like the way I have done it.....
			unsigned char ch = pg->iValue - 32768;  //set to begin at 0;
			Vector vector;

			vector.i = ch % 8;    // set the number of real numbers to 64 and then % 8
			vector.j = ch / 8;    //  / 8 to get the two sets of values.

			return vector;
		}
	}
}

ostream& TranslatePrintADF1( ostream& os, Gene *pg )
{
	switch ( pg->iValue )
	{
		case 1:         os << " ( V8A";       /* functions */
					break;
		case 2:         os << " ( FROG";
					break;
		case 3:         os << " ( PROG2";
					break;
		case 4:         os << " LEFT";
							break;
		case 5:         os << " MOW";
							break;
		case 6:         os << " ADF0";
					break;
		default:
		  {
			  unsigned char ch = pg->iValue - 32768;  //set to begin at 0;
			Vector v_harvey;

			  v_harvey.i = ch % 8;    // set the number of real numbers to 64 and then % 8
			  v_harvey.j = ch / 8;    //  / 8 to get the two sets of values.

	os << " [" << (int)v_harvey.i << "," << (int)v_harvey.j << "]";
			}
			break;
	}
	return os;
}




ostream& operator <<(ostream& os, GP *pgp )
{
	if ( pgp )
	{
		pgpGlobal = pgp;   // set up global variable so you can use MACRO's

		TranslatePrint = TranslatePrintROOT;
		os << "Main: (" << ROOT << endl;
		TranslatePrint = TranslatePrintADF0;
		os << "ADF0: (" << ADF0 << endl;
		TranslatePrint = TranslatePrintADF1;
    os << "ADF1: (" << ADF1 << endl;
	}

	return os; // must return this value or hell breaks loose..
}

void InitialiseGPS()
{
// F(main) = { ADF1  , 1 argument }
// T(main) = { ADF0 }
	if (!(FunctionSets[0] = new FS( 1, 1, 1 )) ) ExitSystem( "Initialise");
	if (!(TerminalSets[0] = new TS( 1, 2 )) ) ExitSystem( "Initialise" );

// F(adf0) = { V8A, PROG2, 2 argument each }
// T(adf0) = { LEFT, MOW, Real }
	if (!(FunctionSets[1] = new FS( 2, 1,2, 2,2 )) ) ExitSystem( "Initialise");
	if (!(TerminalSets[1] = new TS( 3, 3,4,RandomReal, 64 )) ) ExitSystem( "Initialise" );

// F(adf1) = { V8A, FROG, PROG2 , 2,1,2 arguments respectively }
// T(adf1) = { ARG0, LEFT, MOW, Real }
	if (!(FunctionSets[2] = new FS( 3, 1,2,3, 2,1,2 )) ) ExitSystem( "Initialise");
	if (!(TerminalSets[2] = new TS( 4, 4,5,6,RandomReal, 64 )) ) ExitSystem( "Initialise" );
}

void CleanUpGPS()
{
  for ( int i= 0; i < 3; i++ )
	{
		delete FunctionSets[i];
		delete TerminalSets[i];
	}
}








   

⌨️ 快捷键说明

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