Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.

Genetic Algorithm

Sam edited this page Aug 2, 2021 · 5 revisions

main.py

Presently, this file just runs the genetic algorithm for as many times (generations) as specified in the config file.

gaclass.py

gaclass.py defines the GeneticAlgorithm class.

Attributes

max_generation_number

Stores the maximum number of generations to be tested.

Data Type is int, exclusively.

Methods

run(self)

Runs the genetic algorithm.

For the number of generations specified, the system first tests if the generation number is 0: in other words, the original generation. If so, it goes forward with creating the first generation, using the populate method of the Generation class. It is within this generation that the Individual class is instantiated, and the individuals tested.

Data are also saved and plotted on calling data_saver and data_plotter respectively. The metadata of all generations are also saved and plotted.

data_saver(self)

Saves the data from the genetic algorithm to lists.

Relevant data that is saved is the individual and their corresponding merit value.

data_plotter(self)

Plots data onto a new figure, and saves the figure.

This method will attempt to clear the previous figure, if one exists.

individualclass.py

generationclass.py

Defines the Generation class.

Attributes

GenerationNum

The current generation number. Data type is int.

MutationRate

The mutation rate for the generation. Data type is float in the interval [0,1).

Methods

populate(self,History)

Creates the first generation (gen 0).

It loops over the number of individuals (num_of_individuals) as specified in the config file, creating a new one for each loop, writing it to a list called population.

After creating the individuals, it runs merit_calc on each to write the merit value to each individual. The population is then appended to a list, History, which is used later on to reduce the amount of computation required as it prevents individuals being retested.

output_current_status(self)

Does what it says on the tin: outputs the present simulation status in the format

Simulation n+1
Parameter 1: ...
Parameter 2: ...
................

Can be removed without any negative consequences.

repopulate(self,NewPop,History)

Creates all generations past the progenitor (gen 0).

It simply assigns the NewPop to the generation's population attribute. It then checks whether or not the individuals have an assigned merit value, and creates one if they do not.

mating_stage(self,History)

This is the meat of the code, the heart of the algorithm.

The population is sorted by merit value, and the top 50% of performers are cloned into the next generation. The parameters associated with each of these individuals are copied into a 'gene pool' list. Then, for the remaining spaces in the new population, the new individuals are generated either via crossover_stage or mutation_stage. These branch with a fixed probability.

crossover_stage(self,History)

Creates a new individual.

Given the gene pool created in mating_stage, the genes are shuffled, and then a new individual is created by choosing the last element of the list. The individual is checked against the History list, and if it already exists, we just use the existing data, since it will already have a calculated merit value.

mating_stage(self,History)

Creates a new individual, but a parameter is mutated.

Given the gene pool created in mating_stage, the genes are shuffled. Then, one parameter is randomly chosen to be mutated, and by mutated, we simply mean changed to another valid value.

The individual is checked against the History list, and if it already exists, we just use the existing data, since it will already have a calculated merit value.