This project is maintained by DesignEngrLab

Here is a example that showcases different files for creating objective function and constraint classes as well as the setup required for a Genetic Algorithm. There are many GA’s on the web, but this is my own – specifically created for use in OOOT.
Read why I decided to write another one.

The following code (with verbose commenting) is found in the Source Code under:

Examples->Example2 Genetic Algorithm->Program.cs

/* first a new optimization method in the form of a genetic algorithm is created. */

var optMethod = new GeneticAlgorithm();

/* then an objective function and constraints are added. Since these inherit from

* type OptimizationToolbox.objectiveFunction and OptimizationToolbox.inequality

* the Add function knows where to store them so that they will be invoked by the

* fitness evaluation section of the GA. */

optMethod.Add(new efficiencyMeasurement());

optMethod.Add(new lessThanManifoldVolume());

/* GA's cannot explicitly handle inequalities, so a merit function must be added

* so that the fitness evaluation knows how to combine the constraint with the

* objective function. */

optMethod.Add(new squaredExteriorPenalty(optMethod, 50));

/* Now a number of convergerence criteria are added. Again, since these all

* inherit from the abstractConvergence class, the Add method knows to where

* to store them. */

optMethod.Add(new MaxIterationsConvergence(500)); /* stop after 500 iteration (i.e. generations) */

optMethod.Add(new MaxAgeConvergence(20, 0.000000001)); /*stop after 20 generations of the best not changing */

optMethod.Add(new MaxSpanInPopulationConvergence(100)); /*stop if the largest distance is only one unit. */

optMethod.NumConvergeCriteriaNeeded = 2; /* two of these three criteria are needed to stop the process. */

/* The genetic algorithm is for discrete problems. Therefore we need to provide the optimization algorithm

* and the subsequent generators with the details of the space. The first variable represents the number of

* passes in our fictitious problem. We set the lower bound to 1 and the upper bound to 20. The third argument

* is the delta and since only integers are possible we set this to 1. The second and third variables are

* really continous, but for the purpose of the GA we set a discretization at one-ten-thousandth for the second

* and one-hundredth in the third. **Note that you can provide either the delta or the number of steps. Here**

* 36,001 steps will make increments of one-hundredth. */

var SpaceDescriptor = new DesignSpaceDescription

{

new VariableDescriptor(1, 20, 1.0),

new VariableDescriptor(0, 100, 0.0001),

new VariableDescriptor(-180, 180, (long) 36000)

};

optMethod.Add(SpaceDescriptor);

/* the genetic algorithm requires some more values to be fully specified. These include initial,

* crossover, and mutation generators, as well as a selector. A Latin Hyper Cube initial sample is

* first created to assure the population covers the space well. */

optMethod.Add(new LatinHyperCube(SpaceDescriptor, VariablesInScope.BothDiscreteAndReal));

/* the typical bit-string approach to mutation and crossover are adopted here. **Note that the**

* mutation rate (per candidate) is increased to 0.4 from the default of 0.1. Which means that

* 4 in 10 candidates should experience at least one mutation. No new crossover rate is provided

* therefore the default of 1.7 will be used. This means that between two parents there will likely

* be 1.7 locations of crossover between them. */

optMethod.Add(new GAMutationBitString(SpaceDescriptor, 0.4));

optMethod.Add(new GACrossoverBitString(SpaceDescriptor));

/* Finally, the selector is added to the population. This RandomPairwiseCompare is often referred to

* as tournament selection wherein a random selection of two candidates results in the inferior one

* being removed from the population. It requires the optimization direction: are lower values better

* (minimize) or larger (maximize)? */

optMethod.Add(new RandomPairwiseCompare(optimize.minimize));

/* for output statements (points in the code where the SearchIO.output(...) function is called, the

* verbosity is set to 4 which is high. Typical values are between 0 and 4 but higher values (>4)

* may be used, but this will likely cut into the speed of the search process. */

SearchIO.verbosity = 4;

/* everything is set, we can now run the algorithm and retrieve the f* and x* values. */

double[] xOptimal;

var fOptimal = optMethod.Run(out xOptimal);

/* since we are curious how the process completed we now output some details. */

SearchIO.output("f* = " + fOptimal, 0); /* the 0 indicates that this statement has high priority

* and shouldn't be skipped in printing to the console. */

SearchIO.output("x* = " + StarMath.MakePrintString(xOptimal), 0);

SearchIO.output("The process converged by criteria: " + optMethod.ConvergenceDeclaredByTypeString, 0);