genetic_algorithms 1.0.1

Library for solving genetic algorithm problems

RUST genetic algorithms library

Codacy Badge CircleCI Rust Unit Tests


This library provides a simple framework to implement genetic algorithms (GA) with Rust.

This library also supports multithreading.

Table of content





This version uses traits for generic implementations.

These traits are within the traits module:

  • GeneT: This trait must be implemented on your own gene representation.
    • new(): This is the constructor function.
    • get_id(): Optional. This function must return the id of the gene.
  • GenotypeT: This trait must be implemented on your own genotype representation.
    • Gene: This is the GeneT associated type.
    • new(): This is the constructor function.
    • new_gene(): Optional. Must return Self::Gene.
    • get_dna(): Must return the array of genes (GeneT).
    • set_dna(dna: &[Self::Gene]): Must set the array of genes (GeneT).
    • set_gene(gene_index: usize, gene: Self::Gene): Optional. This method will replace a gene in the defined gene_index position.
    • calculate_fitness(): Optional. This function must calculate the fitness of the indivudual (or the genotype) in f64.
    • get_fitness(): Returns the fitness previously calculated by calculate_fitness().
    • set_fitness(fitness: f64): Sets the fitness value.
    • get_age(): Returns the age of the genotype.
    • set_age(age: i32): Sets the age of the genotype.


Within the module operations we have the following operators:

  • Crossover
    • Cycle
    • Multipoint
    • Uniform
  • Mutation
    • Swap
    • Inversion
    • Scramble
  • Selection
    • Random
    • Roulette Wheel
    • Stochastic Universal Sampling
    • Tournament
  • Survivor
    • Fitness based
    • Age based


In genetic algorithms, operators are applied over a population of individuals, and over a set of rules (not yet implemented). Within the population module, Population structure will define the population.


Because genetic algorithms run over different generations, in this library there is a start function within module ga that facilitates the process. This function will need the GaConfiguration structure which contains the operators to use, the maximum number of generations, the problem solver (Maximization or Minimization), etc, and the Population structure, which is in the population module.

GA Configuration

Within this library you can configure the way to run genetic algorithms through the configuration structure GaConfiguration. This structure contains the following attributes:

  • number_of_threads: Optional. It indicates how many threads will be executed at the same time.
  • limit_configuration: It configures the limits of the Genetic Algorithms with the LimitConfiguration structure.
  • selection_configuration: It configures the selection method with the SelectionConfiguration structure.
  • crossover_configuration: It configures the crossover method with the CrossoverConfiguration structure.
  • mutation_configuration: It configures the mutation method with the MutationConfiguration structure.
  • survivor: Indicates what survivor operator to use.
  • log_level: Optional. It configures the maximum log level we want to have. If this value is none, logs are disabled.


  • number_of_couples: Optional. This attribute is only valid for stochastic universal sampling. It indicates the number of couples to select from the population.
  • method: Indicates what selection operator to use.


  • number_of_points: Optional. This attribute is only valid for crossover multipoint, and it indicates how many points will be made within the dna in crossover operations.
  • probability: Optional. Indicates the probability of two parents for being crossed. This number must be between 0.0 and 1.0 both inclusive.
  • method: Indicates what crossover operator to use.


  • probability: Optional. Indicates the probability for a given child to be mutated. This number must be between 0.0 and 1.0 both inclusive.
  • method: Indicates what mutation operator to use.


  • problem_solving: You can select from a Minimization problem or a Maximization problem.
  • max_generations: In case of not getting the optimal result, this attribute indicates the maximum number of generations to execute before stopping.
  • fitness_target: Optional. The fitness of the best individual.
  • get_best_individual_by_generation: Optional. Indicates to the runner to return the best individual by generation.


A simple example of use could be the minimization of a genotype whose gene has only an id.

Creation of the gene and genotype structure

Use the traits. use genetic_algorithms::{ga::run, operations::{Selection, Crossover, Mutation, Survivor}, population::Population, traits::GenotypeT, configuration::{GaConfiguration, ProblemSolving, LimitConfiguration}};

Define the gene structure.

#[derive(Debug, Copy, Clone, Default, PartialEq)]
pub struct Gene{
    pub id: i32,
impl GeneT for Gene{
    fn new()->Gene{
        return Gene{id: -1};
    fn get_id(&self) -> &i32{
        return &;

Define the genotype structure, and the fitness calculation.

#[derive(Debug, Clone, Default, PartialEq)]
pub struct Genotype{
    pub dna: Vec<Gene>,
    pub fitness: f64,
    pub age: i32,
impl GenotypeT for Genotype{
    type Gene = Gene;
    fn get_dna(&self) -> &[Self::Gene] {
    fn get_fitness(&self) -> f64 {
    fn set_fitness(&mut self, fitness: f64) { = fitness;
    fn set_age(&mut self, age:i32){
        self.age = age;
    fn get_age(&self) -> i32 {
    fn calculate_fitness(&mut self) {
        = 0.0;
        let mut position = 0;

        for i in &self.dna{
            let fitness = f64::from(i.get_id()*position);
   += fitness;
            position += 1;
    fn new() -> Self {
        return Genotype{
            dna: Vec::new(),
            fitness: 0.0,
            age: 0,
    fn set_dna(&mut self, dna: &[Self::Gene]){
        self.dna = dna.to_vec();

Define the configuration of the GA.

let configuration = GaConfiguration{
        number_of_threads: Some(2),
        limit_configuration: LimitConfiguration{max_generations: 100, fitness_target: None, problem_solving: ProblemSolving::Maximization, get_best_individual_by_generation: Some(true)},
        selection_configuration: SelectionConfiguration{number_of_couples: Some(10), method:Selection::Tournament},
        crossover_configuration: CrossoverConfiguration{probability:Some(1.0), method: Crossover::Cycle, number_of_points: None},
        mutation_configuration: MutationConfiguration { probability: Some(0.2), method: Mutation::Swap },
        survivor: Survivor::Fitness,
        log_level: Some(log::LevelFilter::Info),

Define the DNA, the individuals and the population.

let dna_1 = vec![Gene{id:1}, Gene{id:2}, Gene{id:3}, Gene{id:4}];
    let dna_2 = vec![Gene{id:2}, Gene{id:3}, Gene{id:4}, Gene{id:1}];
    let dna_3 = vec![Gene{id:3}, Gene{id:4}, Gene{id:1}, Gene{id:2}];
    let dna_4 = vec![Gene{id:4}, Gene{id:1}, Gene{id:2}, Gene{id:3}];
    let dna_5 = vec![Gene{id:2}, Gene{id:1}, Gene{id:3}, Gene{id:4}];
    let dna_6 = vec![Gene{id:1}, Gene{id:3}, Gene{id:4}, Gene{id:2}];
    let dna_7 = vec![Gene{id:3}, Gene{id:4}, Gene{id:2}, Gene{id:1}];
    let dna_8 = vec![Gene{id:4}, Gene{id:2}, Gene{id:1}, Gene{id:3}];
    let dna_9 = vec![Gene{id:2}, Gene{id:1}, Gene{id:4}, Gene{id:3}];
    let dna_10 = vec![Gene{id:1}, Gene{id:4}, Gene{id:3}, Gene{id:2}];

let individuals = vec![Genotype{dna: dna_1, fitness: 1.0, age: 0}, Genotype{dna: dna_2, fitness: 2.0, age: 0},
    Genotype{dna: dna_3, fitness: 3.0, age: 0}, Genotype{dna: dna_4, fitness: 4.0, age: 0}, Genotype{dna: dna_5, fitness: 5.0, age: 0}, Genotype{dna: dna_6, fitness: 6.0, age: 0}, Genotype{dna: dna_7, fitness: 7.0, age: 0}, Genotype{dna: dna_8, fitness: 8.0, age: 0}, Genotype{dna: dna_9, fitness: 9.0, age: 0}, Genotype{dna: dna_10, fitness: 10.0, age: 0}];

    let mut population = Population::new(individuals);

Finally, run the GA.

population = genetic_algorithms::ga::run(population, configuration);

Other examples


Add this to your Cargo.toml:

genetic_algorithms = "1.0.1"