Custom Selection Scheme

This tutorial introduces the use of custom selection schemes.

By default the CGP-Library uses the select fittest selection schemes which simply selects the mu best members of the candidate chromosomes to become the parents.  This tutorial will demonstrate how to define and use alternative custom selection schemes.

Summary
Custom Selection SchemeThis tutorial introduces the use of custom selection schemes.
The ProgramA simple program showing how to uses a custom tournament selection scheme.
Stepping Through the CodeA close look at each line of the example code.

The Program

A simple program showing how to uses a custom tournament selection scheme.

The program below is provided in the CGP-Library download within /examples/customSelectionScheme.c and is included in the code::blocks project.

#include <stdio.h>
#include <stdlib.h>
#include "../src/cgp.h"

void tournament(struct parameters *params, struct chromosome **parents, struct chromosome **candidateChromos, int numParents, int numCandidateChromos){

    int i;

    struct chromosome *candidateA;
    struct chromosome *candidateB;

    for(i=0; i<numParents; i++){

        candidateA = candidateChromos[rand() % numCandidateChromos];
        candidateB = candidateChromos[rand() % numCandidateChromos];

        if(getChromosomeFitness(candidateA) <= getChromosomeFitness(candidateB)){
            copyChromosome(parents[i], candidateA);
        }
        else{
            copyChromosome(parents[i], candidateB);
        }
    }
}

int main(void){

    struct parameters *params = NULL;
    struct dataSet *trainingData = NULL;
    struct chromosome *chromo = NULL;

    int numInputs = 1;
    int numNodes = 50;
    int numOutputs = 1;
    int arity = 2;

    double targetFitness = 0.1;
    int updateFrequency = 1000;
    int numGens = 10000;

    params = initialiseParameters(numInputs, numNodes, numOutputs, arity);

    addNodeFunction(params, "add,sub,mul,div,sin");

    setTargetFitness(params, targetFitness);

    setUpdateFrequency(params, updateFrequency);

    setCustomSelectionScheme(params, tournament, "tournament");

    trainingData = initialiseDataSetFromFile("./dataSets/symbolic.data");

    chromo = runCGP(params, trainingData, numGens);

    freeChromosome(chromo);
    freeDataSet(trainingData);
    freeParameters(params);

    return 0;
}

Stepping Through the Code

A close look at each line of the example code.

First standard headers and cgp.h are included.

#include <stdio.h>
#include <stdlib.h>
#include "../src/cgp.h"

Next we defined our custom selection scheme to be used.

The custom selection scheme prototype must take the following form.  Where params is a pointer to an initialised parameters structure, parents is a pointer to an array of chromosomes which will contain the parents when the selection scheme terminates, candidateChromos is a pointer to an array of chromosomes which contains the chromosomes from which the parents will be selected, numParents give the number of parent chromosomes to be selected and numCandidateChromos gives the number of candidate chromosomes to select from.

void selectionSchemeName(struct parameters *params, struct chromosome **parents, struct chromosome **candidateChromos, int numParents, int numCandidateChromos);

Here a tournament selection scheme is defined which uses a tournament size of two. candidateA and candidateB are used to point to two randomly selected chromosomes from the candidate chromosomes.  The fitter of the two randomly selected chromosomes is then copied into the array of parent chromosomes using copyChromosome.

void tournament(struct parameters *params, struct chromosome **parents, struct chromosome **candidateChromos, int numParents, int numCandidateChromos){

    int i;

    struct chromosome *candidateA;
    struct chromosome *candidateB;

    for(i=0; i<numParents; i++){

        candidateA = candidateChromos[rand() % numCandidateChromos];
        candidateB = candidateChromos[rand() % numCandidateChromos];

        if(getChromosomeFitness(candidateA) <= getChromosomeFitness(candidateB)){
            copyChromosome(parents[i], candidateA);
        }
        else{
            copyChromosome(parents[i], candidateB);
        }
    }
}

Much of the main function has been introduced in the Getting Started tutorial and is not re-described here.

In order to use our new tournament selection scheme it must be set in the parameters structure using setCustomSelectionScheme.  Where the first variable is a parameters structure, the second is our custom selection scheme and the third is a user defined name for the selection scheme.

Now when runCGP or repeatCGP is called the this custom selection scheme will be used in place of the default select fittest.

setCustomSelectionScheme(params, tournament, "tournament");

And that’s it, in order to use a custom selection scheme it must be defined using the specific prototype and then added as the selection scheme to be used using by calling setCustomSelectionScheme.  To revert back to the default selection scheme simply call setCustomSelectionScheme with the selection scheme variable set as NULL.

struct parameters
Stores general evolutionary and chromosome parameters used by the CGP-Library.
struct chromosome
Stores a CGP chromosome instances used by the CGP-Library.
DLL_EXPORT void copyChromosome(struct chromosome *chromoDest,
struct chromosome *chromoSrc)
Copies the contents of one chromoosme into the other.
This tutorial introduces and steps through a simple program which uses the CGP-Library to solve a symbolic regression problem.
DLL_EXPORT void setCustomSelectionScheme(
   struct parameters *params,
   void (*selectionScheme)(struct parameters *params, struct chromosome **parents, struct chromosome **candidateChromos, int numParents, int numCandidateChromos),
   char const *selectionSchemeName
)
Sets custom selection scheme.
DLL_EXPORT struct chromosome* runCGP(struct parameters *params,
struct dataSet *data,
int numGens)
Applies CGP to the given task.
DLL_EXPORT struct results* repeatCGP(struct parameters *params,
struct dataSet *data,
int numGens,
int numRuns)
Repeatedly applies CGP to the given task.
Close