The problem of finding the global minimum or maximum of an arbitrary multi-parameter function, F(x, y, z, …), is a common one. The function F could represent the total yield of some system and you want to maximize it, or it could represent the lap-time of a race car and you want to minimize it. If the function F can be analytically expressed, it may be possible to take the derivative and solve F’ = 0 (since F is stationary at the minima and maxima). But in practice there are many optimization problems cannot be tackled analytically. For those cases there are several powerful numerical algorithms which can use. The genetic algorithm (GA) is one.
A quick look on CodeProject reveals some basic C# genetic algorithm offerings:
The above projects do implement a basic genetic algorithm, but they lack some features that I really wanted to see:
So I have extended Sacha Barber’s “Simple Genetic Algorithm” to include all these features. The library is called Optimera. It is free for download and use. Check out the included license file for details.
(Old versions: Optimera 14-04-2013.zip)
The download includes an example project “OptimeraTester” showing how to use it. Basically, you create a model that extends the included interface “IOptimizable”. The interface has 3 public methods you need to implement:
int NumberOfParameters(); double Fitness(double normalizedParameters); Object DeepClone();
Then you create a GA object (set calibration properties in the constructor), run it, and extract the results.
GA ga = new GA(model, UpdateProgress, threads, 0.8, 0.05, 100, 10, 0.001); ga.Go(); ga.GetBest(out bestGenes, out bestFitness);
Plans for the future? Maybe the GA could do with some additional mutation types. I don’t like the routlette method for parental selection, so maybe I’ll swap that out. Also, there is no reason that Optimera should only include a genetic algorithm, so maybe later I’ll end up adding other optimization algorithms too.
PS: There are some excellent (and free) external optimization tools. PEST is a particularly good one. External tools can be awkward to use though, especially if you want to take advantage of multiple processors. Furthermore, running a model from an external optimizer involves an amount of disk I/O. In comparison, a native C# optimizer is able modify a model’s parameters directly, and re-run it without any disk I/O.