This tutorial introduces the use of repeatCGP to assess the average behaviour of CGP towards a given application rather than a one-off instance.
This tutorial closely follows the Getting Started tutorial and it is recommended that you read that tutorial first.
Average Behaviour | This tutorial introduces the use of repeatCGP to assess the average behaviour of CGP towards a given application rather than a one-off instance. |
The Program | A simple symbolic regression solving program used to illustrate the use of repeatCGP. |
Stepping Through the Code | A close look at the code. |
A simple symbolic regression solving program used to illustrate the use of repeatCGP.
The program below is provided in the CGP-Library download within /examples/averageBehaviour.c and is included in the code::blocks project.
#include <stdio.h> #include "../src/cgp.h" int main(void){ struct parameters *params = NULL; struct dataSet *trainingData = NULL; struct results *rels = NULL; struct chromosome *chromo = NULL; int numInputs = 1; int numNodes = 15; int numOutputs = 1; int nodeArity = 2; int numGens = 10000; int numRuns = 10; double targetFitness = 0.1; int updateFrequency = 500; double averageFitness; params = initialiseParameters(numInputs, numNodes, numOutputs, nodeArity); addNodeFunction(params, "add,sub,mul,div,sin"); setTargetFitness(params, targetFitness); setUpdateFrequency(params, updateFrequency); trainingData = initialiseDataSetFromFile("./dataSets/symbolic.data"); rels = repeatCGP(params, trainingData, numGens, numRuns); averageFitness = getAverageFitness(rels); printf("The average chromosome fitness is: %f\n", averageFitness); chromo = getChromosome(rels, 4); printf("The best chromosome found on run 4:\n"); printChromosome(chromo, 0); saveResults(rels, "results.csv"); freeDataSet(trainingData); freeChromosome(chromo); freeResults(rels); freeParameters(params); return 0; }
A close look at the code.
The above code is very similar to gettingStarted.c seen in the Getting Started tutorial and shall not be explained again. Here the specifics relating to assessing the average behaviour of CGP towards a given task shall be highlighted.
When CGP is repeatedly applied to a given task using repeatCGP the results are stored in a returned results structure. Therefore we need to define a results structure variable to store the returned results. An averageFitness variable is also defined which will later store the average fitness achieved when repeatedly applying CGP to the given task multiple times.
struct results *rels = NULL; ... double averageFitness;
When assessing the average behaviour of CGP towards a given task CGP must be applied to that task a number of times. Each instance of applying CGP towards the task is called a run. Here the numRuns variable stores the number of runs CGP will be applied towards the given task.
int numRuns = 10;
In the Getting Started tutorial we applied CGP to the given task once using runCGP. Here we are repeatedly applying CGP to a give task using repeatCGP. The parameters of repeatCGP are the same as for runCGP except we must also specify the number of runs.
When repeatCGP is called it prints high level information relating to each run to the terminal and returns an initialised results structure.
rels = repeatCGP(params, trainingData, numGens, numRuns);
In order to access the result of applying CGP to a given task multiple times the returned results structure must be queried for information. For instance, getAverageFitness, getAverageActiveNodes and getAverageGenerations can be used to get the average fitness, average number of active nodes and average number of generations respectively.
In the example code getAverageFitness is used to get the average fitness of all the runs which is then printed to the terminal.
averageFitness = getAverageFitness(rels); printf("The average chromosome fitness is: %f\n", averageFitness);
As well as getting average statistics the best chromosome found on any given run can be accessed using getChromosome.
In the example code getChromosome is used to get the best chromosome found on run four which is then printed to the terminal using printChromosome.
chromo = getChromosome(rels, 4); printf("The best chromosome found on run 4:\n"); printChromosome(chromo, 0);
In cases where the results need to be saved to be inspected later the saveResults function can be used. saveResults saves the given results structure to the given file. The format of the results is comma separated in the same form as is displayed to the terminal during repeatCGP; except the averages are not included.
saveResults(rels, "results.csv");
Finally all of the initialised structures should be free’d including the results using freeResults and the chromosome returned from getChromosome using freeChromosome.
freeDataSet(trainingData); freeChromosome(chromo); freeResults(rels); freeParameters(params);
And that’s it, running CGP multiple times to assess its average performance is not that much more complicated that running it once.
Repeatedly applies CGP to the given task.
DLL_EXPORT struct results* repeatCGP( struct parameters * params, struct dataSet * data, int numGens, int numRuns )
Stores the best chromosome found on each run when using repeatCGP
struct results
Applies CGP to the given task.
DLL_EXPORT struct chromosome* runCGP( struct parameters * params, struct dataSet * data, int numGens )
Gets the average fitness of the best chromosome found for each run in results.
DLL_EXPORT double getAverageFitness( struct results * rels )
Gets the average number of active nodes of the best chromosome found for each run in results.
DLL_EXPORT double getAverageActiveNodes( struct results * rels )
Gets the average number generations required to find the best best chromosome for each run in results.
DLL_EXPORT double getAverageGenerations( struct results * rels )
Gets a copy of the best chromosome found on the given run in an initialised results structure.
DLL_EXPORT struct chromosome* getChromosome( struct results * rels, int run )
Displays the given chromosome to the terminal / command prompt in a human readable format.
DLL_EXPORT void printChromosome( struct chromosome * chromo, int weights )
Saves the given results to a csv file.
DLL_EXPORT void saveResults( struct results * rels, char const * fileName )
Frees results instance.
DLL_EXPORT void freeResults( struct results * rels )
Stores a CGP chromosome instances used by the CGP-Library.
struct chromosome
Frees chromosome instance.
DLL_EXPORT void freeChromosome( struct chromosome * chromo )