stack.cc

来自「标准的GP源代码,由Andy Singleton维护」· CC 代码 · 共 554 行

CC
554
字号
// stack.cc   File to demonstrate evolution of stack, build with GPQUICK-2.1// W. Langdon cs.ucl.ac.uk#define Version "12 Dec 1994 $Revision: 1.19 $"// Includes main function//Modifications// WBL 15 Mar 96 Add calling DisplayDupStats// WBL 13 Mar 96 Add command line handling, restore r1.13 (keep pTraceStatic)//               Add pTraceDStats, pTracePStats and pTraceStatic// WBL 28 Feb 96 Add crossfile// WBL 26 Feb 96 Make compatible with new (ha 2years old) AddF//               Ensure pMaxTreeExpr is ignored// WBL 14/12/94 Load seed from command line// WBL 25/5/94 Add write_Aux//requires MULTREE to be defined#include "pch.h"#include "chrome.h"#include "primitiv.h"#include <assert.h>//extern double difftime (time_t t2, time_t t1 );extern char scratch[100];#ifdef FASTEVAL	extern evalnode* IpGlobal;	extern Chrome* ChromeGlobal;#endifofstream temp("");ofstream& crossfile = temp;//**************************************************************************// Define your Problem classProblem* ThisProblem;class stack : public Problem {public:	stack(ChromeParams* p=NULL);   // Initialize primitives,	void WriteTreeName(int tree, ostream& ostr = cout );	                               // parameters, and data	float fitness(Chrome* chrome); // GP fitness function	void AddFall(Function* f);};//end class//**************************************************************************// static variables that make up the evaluation environment// Build your environment here as statics// where the evaluation functions can get to the data#define Num_test_seq       4#define num_tests        160//#define max_fitness      160 moved to stack.h#define Max_tests        (num_tests+Num_test_seq+1)#define test_stack_limit  10#define Max               10#define store_limit       64retval Arg1, Aux, store[store_limit];BOOL memory_error;int get_address(){int address = (EVAL)+(store_limit/2);if ( address <= 0 || address >= store_limit )  {	memory_error = TRUE;	return 0;             //safe buffer area  }else	return address;}//end get_address//**************************************************************************/////////////////// Problem specific functions and terminals// Use the OPDEF,EVAL,IP and CURCHROME defines// and the code will recompile for different eval methods// Problem Specific TerminalsOPDEF(zeroEval) {return 0;}OPDEF(oneEval) {return 1;}OPDEF(MaxEval) {return Max;}OPDEF(Arg1Eval) {return Arg1;}OPDEF(AuxEval) {return Aux;}OPDEF(inc_AuxEval) {return ++Aux;}OPDEF(dec_AuxEval) {return --Aux;}//Problem specific FunctionsOPDEF(readEval) {int address = get_address(); return store[address];}OPDEF(writeEval) {       int address = get_address();        retval old = store[address];       store[address] = EVAL;       return old;                // copy what Tesler does}OPDEF(write_AuxEval) {       retval old = Aux;       Aux = EVAL;       return old;                // copy what write (ie Tesler) does}//**************************************************************************///////////////////////// PROBLEM definitionvoid stack::AddFall(Function* f ){AddF(f);for ( int i = 0; i < NUM_TREES; i++ )	addtofuncbag(i, f);}stack::stack(ChromeParams* p) : Problem(){	AddF(new ConstFunc(0));    // REQUIRED as function 0	// Add some standard primitives	AddFall(new AddFunc(100));	AddFall(new SubFunc(100));	// Add the problem specific primitives	AddFall(new Function(0,0,100,zeroEval,"0"));	AddFall(new Function(0,0,100,oneEval,"1"));	AddFall(new Function(0,0,100,MaxEval,"max"));	AddFall(new Function(0,0,100,Arg1Eval,"arg1"));	AddFall(new Function(0,0,100,AuxEval,"aux"));	AddFall(new Function(0,0,100,inc_AuxEval,"inc_aux"));	AddFall(new Function(0,0,100,dec_AuxEval,"dec_aux"));	AddFall(new Function(1,0,100,readEval,"read"));	AddFall(new Function(2,0,100,writeEval,"write"));	AddFall(new Function(1,0,100,write_AuxEval,"write_Aux"));	// Set some parameters	p->params[pPopSize]=1000;	p->params[pGenerateLimit]=100000;	p->params[pMaxExpr]=250;	// Nb hold NUM_TREES trees	p->params[pMaxTreeExpr]=0;      // NOT USED	p->params[pRepeatEval]=0;	// Dont test again if copy chrome	p->params[pMuteShrinkWt]=0;	// No shrink mutation	p->params[pMuteWt]=0;	        // No muation	p->params[pCrossWt]=90;         // Use Koza value	p->params[pMuteRate]=0;         // No mutations	p->params[pAnnealCrossWt]=0;	// No annealing	p->params[pAnnealMuteWt]=0;	p->params[pTournSize]=4;	// try and see	p->params[pKillTourn]=4;	// try and see	p->params[pMateRadius]=0;	// whole population	p->params[pMaxAge]=0;     	// no age limit//	p->params[pFitnessCases]=;	// ?//	p->params[pTrace]=31;     	// everybody	// If you need to load problem specific data for evaluation	// Or load an environment (a map, a scenario)	// Do it here}//store for test casesenum{makenull,top,pop,push,empty,start_test,end_tests};int test[Max_tests];retval argument[Max_tests];retval ans[Max_tests];int sp;retval correct_stack [test_stack_limit];BOOL set_answer (int i){ans [i] = 0;argument [i] = 0;switch(test[i]){ case makenull:	sp = 0;	break; case top:	if (sp<=0)		return FALSE; //force new tested to be selected	else		ans [i] = correct_stack [sp];	break; case pop:	if (sp<=0)		return FALSE; //force new tested to be selected	else		{      ans [i] = correct_stack [sp];		       --sp;	       }	break; case push:	if (sp>=test_stack_limit)		return FALSE; //force new tested to be selected	else		{      argument [i] = rnd(2000)-1000;		       correct_stack [++sp] = argument [i];	       }	break; case empty:	ans [i] = (sp==0);	break; default:	return FALSE; //force new tested to be selected	break;}//end casereturn TRUE;}//end set_answer()void	generate_tests(){int i = 0;cout << "Generating test data\n";for (int j = 0; j < Num_test_seq; j++ ){test[i++] = start_test;for (int k=0; k<(Max_tests/Num_test_seq-1); k++)	{	do {		test[i] = makenull;		if (k != 0) 		  {       const int probablities [Num_test_seq][(empty+1)] =	                                       {  1, 20, 34, 25, 20,                                                 30, 10, 10, 40, 10,                                                 10, 10, 20, 30, 30,                                                 10, 40, 20, 20, 10 };#define ptotal 100			  int r = rnd(ptotal);			  for ( int m = makenull; m <= empty; m++)				  if (r <= probablities [j][m])				   {      test [i] = m;			                  break;				   }				  else 					  r -= probablities [j][m];		  }	   } while (set_answer(i)==FALSE);	i++;	}//endloop k}//endloop jtest[i++] = end_tests;}//end generate_tests()void write_tests ( ostream& fout = cout ){fout<<"Test cases\n";int test_cases [empty+1] = {0, 0, 0, 0, 0};{for (int i = 0; test[i] != end_tests; i++)   {  if ( test [i] == start_test )	      fout << "\nstart_test\n";      else	     {test_cases [test[i]]++;	      ThisProblem->WriteTreeName(test[i], fout);	      fout<< "(" << argument[i] << ")  \t" << ans[i] << endl;             }   }}{for ( int j = 0; j <= empty; j++ )	{	ThisProblem->WriteTreeName(j, fout);	fout<<" tested " << test_cases [ j ] << " times";	if ((j == pop ) || ( j == empty ))		fout<<endl;        else		fout<<", ";        }}fout<<"Min expected score " <<        test_cases [ makenull ] + test_cases [ push ];fout<<" Good score " <<        test_cases [ makenull ] + test_cases [ push ] + test_cases [ empty ];fout<<" Top score " <<        test_cases [ makenull ] + test_cases [ top ] + test_cases [ pop ] +        test_cases [ push ]     + test_cases [ empty ];fout<<endl;}//end write_tests()void stack::WriteTreeName(int tree, ostream& ostr) //= cout) gcc 2.6.3 patch{switch(tree)	 {	 case makenull: ostr<< "makenul"; break;	 case top:      ostr<< "top"; break;	 case pop:      ostr<< "pop"; break;	 case push:     ostr<< "push"; break;	 case empty:    ostr<< "empty"; break;	 default:       ostr<< "ERROR321"; break;	 }}//end stack::WriteTreeName()void update_score(int& score,		  int test_done, int actual_answer, int required_ans ){switch(test_done){ case makenull:	score++;	break; case top:	if ( actual_answer == required_ans ) score++;	break; case pop:	if ( actual_answer == required_ans ) score++;	break; case push:	score++;	break; case empty:	if ( (actual_answer>0) == required_ans ) score++;	break; default:	assert (0==1);   //catch internal error and terminate gp run        break;}//end case}//end update_score()void display_run (Chrome* chrome, ostream& fout = cout )// fitness function.{int i;int score = 0;chrome->SetupEval();for(i=0; test[i] != end_tests; i++){if (test[i] == start_test)	{fout<<"Initialise everything for new test\n";	 memory_error = FALSE;	 Aux = 0;	 memset(store,0,sizeof(store));        }else	{retval answer;	 Arg1 = argument[i];	 answer = chrome->evalAll ( test[i] );	 if (memory_error)   { break;  }         update_score( score, test[i], answer, ans[i]);	 fout<<"Test ["<<i<<"] ";	 ThisProblem->WriteTreeName(test[i], fout);	 fout<< "(" << argument[i] << ")  \tresult " << answer;	 fout << " (expected " << ans[i] << ")\n";        }//end iffout<<"score = " << score;fout<<" Aux = " << Aux <<endl;;for (int j = 0; j < store_limit; j++)   {	if ( store[j] != 0 )	   {	   fout<<"store " << j-(store_limit/2) << " = " << store [j] << endl;           }   }}//end loopfout<<"Final score = " << score << endl;assert (chrome->nfitness->fvalue == float (score)); //it should be!}//end display_run()float stack::fitness(Chrome* chrome)// fitness function.{int i;int score = 0;//cout << "Fitness of "<< chrome << flush;for(i=0; test[i] != end_tests; i++){if (test[i] == start_test)	{//initialise everything for new test	 memory_error = FALSE;	 Aux = 0;	 memset(store,0,sizeof(store));        }else	{retval answer;	 Arg1 = argument[i];	 answer = chrome->evalAll ( test[i] );	 if (memory_error)   { break;  }         update_score( score, test[i], answer, ans[i]);        }//end if}//end loopchrome->nfitness->fvalue= float (score);//cout<<"Final score = " << score << endl;return score;}//end stack::fitness//**************************************************************************int do_gens (Pop* pop, int number) //return if complete or not{    cout<<"Running, gpquick_seed "<<gpquick_seed<<endl;     pop->go_until(0,number,max_fitness);     // Display the best so far     cout << "\n\nAfter " << pop->gencount;     cout << " generates, BestFitness = ";     cout << pop->BestFitness->fvalue << "\n";     pop->pop[pop->BestMember]->write(PRETTY_NONE,cout);     cout << endl;     pop->DisplayStats();     if ( pop->params->params[pTrace] & pTraceDStats ) pop->DisplayDStats();     if ( pop->params->params[pTrace] & pTracePStats ) pop->DisplayPStats();     else                                      pop->DisplayLPStats();     pop->DisplayDupStats();     //	generate_tests(); //make sure its not learning the tests     // write_tests();//     display_run(pop->best()); //show what it does     return (pop->BestFitness->fvalue >=max_fitness);}//end do_gens()///////////////////////////////  MAINint main(int argc, char * argv[])// Run stack{	time_t start, end;	cout << "\nGP Program to evolve a Stack, version "<<Version;	time (&start);	cout << ", " << ctime(&start) <<endl;	ChromeParams* params = new ChromeParams();	ThisProblem=new stack(params);	Pop* pop;	generate_tests();    //Must be done before create pop or change seed	write_tests();        for(int i=0; i<argc;i++) {		params->Load(argv[i]); }	if ( params->params[pPopSeed] > 0 )		gpquick_seed = params->params[pPopSeed];  //dirty I know	else	      { rndomize();  //Cheat, use seed=1 to create tests but			     //randomise population		params->params[pPopSeed] = gpquick_seed; //record seed used	      }	int pop_size = params->params[pPopSize];	int gen_max  = params->params[pGenerateLimit];	cout << "Creating new population of " << pop_size<< " individuals\n";	pop = new Pop(ThisProblem,params,pop_size);	cout << "new Pop -- completed\n";	params->Save();	cout << "Setting each fitness value\n";	int done = do_gens (pop, pop_size-1);	cout << "Initial fitness values calculated,\n";	if ( params->params[pTrace] & pTraceStatic )		{  cout << "\n\nInitial Population";		   pop->Write();	   }	cout << "Creating a total of " << gen_max << " individuals\n";	                         // kbhit IS NOT PORTABLE (Borland specific)	while (pop->gencount<gen_max && !done && !kbhit())  	{		done = do_gens (pop, pop_size);		if ( params->params[pTrace] & pTraceStatic )			{  cout << "\n\nCurrent Population";			   pop->Write();		   }	}	// Display the best	cout << "\n\nFINAL RESULTS. After " << pop->gencount;        cout << " generates, BestFitness = ";        cout << pop->BestFitness->fvalue << "\n";	// Display the final population	if ( params->params[pTrace] & pTraceStatic )	  {  cout << "\n\nFINAL Population";	     pop->Write();          }	pop->pop[pop->BestMember]->write(PRETTY_NONE,cout);        display_run(pop->best()); //show what it does	time (&end);	cout << "\nGP Stack Finished "<< ctime(&end);//	cout << " took "<< difftime(end, start) <<" seconds elapse, ";//	cout << clock() << " ticks cpu";	cout << endl;	delete pop;	delete ThisProblem;	delete params;	return done? 1 : 0;}

⌨️ 快捷键说明

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