Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / artificial-intelligence

GALib

5.00/5 (10 votes)
24 Jan 2010GPL35 min read 65.1K   1.4K  
A small C# library that provides scaffolding for genetic algorithm based functionality.

Introduction

GALib is a small C# library that provides scaffolding for genetic algorithm based functionalities. It's completely Open Source, and is available under the GNU General Public License.

Background

I created this library while working on an application to solve the Travelling Salesman Problem. The idea for creating that application came to me after reading the first part of Bio-Inspired Artificial Intelligence by Dario Floreano and Claudio Mattiussi. I figured I needed to do an implementation of what I've read to test myself. All work was done in my free time.

Using the code

This section explains how to create your own GA implementations using GALib. If you are not familiar with how genetic algorithms work, you are advised to first have a good look at this Wikipedia article and related pages, or one of the many awesome articles here on CP. This section will first introduce you to how the actual evolution is done, and then how to create your own specific implementation by specifying an individual type.

Class diagram

Image 1

Population class

The Population class is the core of GALib. It is a collection of individuals of a type you specify on which evolution (selection and reproduction) can be done. The evolution of the population is done on a background thread, and can be done with rank based selection, truncated rank based selection, roulette wheel selection, and tournament selection. Events are fired every time a new generation is created, a new fittest individual has been found, or the evolution is complete.

Constructor

The constructor allows you to specify some general properties that are likely to be different in multiple Use Cases. These are:

  • size - Optional. Int32. The size of the population (# of individuals). Defaults to 100.
  • generations - Optional. Int64. The maximum number of generations in the evolution. Defaults to 100000.
  • stagnationLimit - Optional. Int64. The maximum number of generations with no fitness improvement. Defaults to 10000.

Population will automatically populate itself with size amount of new individuals. Since Population is a list of individuals, you can add, remove, and manipulate members yourself. This is, however, highly discouraged once the evolution is running.

Evolution methods

You can choose between several selection algorithms:

  • Rank based selection
  • Rank based selection allocates reproduction slots to individuals based on their fitness rank. You can initiate rank based selection with the DoRankBasedSelection method. Similarly, you can do truncated rank selection, a rank selection that only holds into account the first n individuals, by calling the DoTruncatedRankSelection method, which accepts an Int32 parameter indicating n.

  • Roulette wheel based selection
  • Roulette wheel selection allocates reproduction slots to individuals proportional to their fitness. You can initiate roulette wheel selection with the DoRouletteWheelSelection method.

  • Tournament based selection
  • Tournament based selection consists of allocating reproduction slots to the best individuals of a randomly chosen subset. Population contains several overloaded DoTournamentBasedSelection methods, allowing you to hold tournaments of a fixed size, or a variable size between two bounds, both specified either as the amount of individuals, or as a percentage of the population size.

You can stop the evolution by calling the CancelEvolution method. The worker thread on which evolution is done will finish after the current generation has been completed.

After every generation, the individuals will be sorted according to their fitness, fittest first. This means that populationInstance[0] will yield you the fittest individual for that generation, and populationInstance[populationInstance.Count - 1] will get you the least fit member. You can also use GetFittest to get a range of fittest individuals. It accepts an Int32 indicating the size of the range, and a boolean indicating whether elites should be included.

Events

The Population class contains three events that will be fired at various points through the evolutionary process:

  • GenerationComplete (Object sender, GenerationCompleteEventArgs<IndividualType> e)
  • Occurs every time a generation is complete. This means selection, reproduction, and fitness determination have happened, in that order. GenerationCompleteEventArgs contains the current generation number and the fittest individual of the generation.

  • NewFittest (Object sender, NewFittestEventArgs<IndividualType> e)
  • Occurs when a new overall fittest individual is found. NewFittestEventArgs contains the current generation number and the overall fittest individual.

  • EvolutionComplete (Object sender, EvolutionCompleteEventArgs<IndividualType> e)

Properties

The list below contains the most important properties of the Population class, which allow you to drastically change the working of the algorithm.

Image 2

Individuals

For your own implementation, you need to specify your own individual type(s). The definitions for these types contain initialization, mutation, and crossover methods, as well as the genotype specification and fitness function. GALib provides scaffolding in the form of an IIndividual interface and an Individual abstract class. You must implement the interface in your individual type definition to be able to create a population of your type. You can (most likely should) inherit from Individual, which will spare you some basic work, and implement IIndividual for you.

Individual class

Inheriting Individual forces you to implement some abstract methods:

  • void doBaseInitialization()
  • void doRandomInitialization()
  • void doMutation()
  • void doCrossover(IIndividual mother, IIndividual father)
  • Double determineFitness()

For details on other work done by Individual, see the source of the class itself.

Points of interest

Since my main motivation for creating this library was exercise, I learned a lot from building it. This is the first C# library I've ever written, as well as the first time I've done any GA programming (or AI in general). Abstracting the library in a way so that it can be used for GA in general was very interesting, and required me to expanded my knowledge of how to use interfaces and inheritance and use Generics in a non-basic way for the first time.

See also

History

  • Version 0.1: 2010-01-24: Initial release.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)