gentle-ga

Crates.iogentle-ga
lib.rsgentle-ga
version0.1.0
created_at2025-10-31 13:34:53.358255+00
updated_at2025-10-31 13:34:53.358255+00
descriptionErgonomic, strongly-typed genetic algorithm framework (static dispatch).
homepage
repositoryhttps://github.com/MatthewScholefield/gentle-ga
max_upload_size
id1910034
size18,615
Matthew D. Scholefield (MatthewScholefield)

documentation

README

gentle-ga

Ergonomic, strongly-typed genetic algorithm framework for Rust. The core goal: make it dead-simple to plug in your domain logic (genome + fitness) with a single trait, while the engine handles population orchestration, selection, mutation/crossover rates, seeding, and elitism — all with zero-cost static dispatch.

  • One trait to implement: Problem (your genome and fitness).
  • Sensible defaults: tournament selection, no-op mutation/crossover/repair.
  • Deterministic runs via seeds, ergonomic GA::builder(...) API.
  • No runtime type-erasure or downcasting; compile-time safety and speed.

A tiny example

This example evolves a single f64 to maximize cos(x) - x^2 using tournament selection, crossover-as-average, and small uniform mutation. It showcases the minimal surface area you implement and the ergonomic builder.

use gentle_ga::prelude::*;

struct Hill;

impl Problem for Hill {
    type Genome = f64;
    type Fitness = f64;

    fn random_genome<R: rand::Rng + ?Sized>(&mut self, rng: &mut R) -> Self::Genome {
        rand::Rng::gen_range(rng, -5.0..5.0)
    }

    fn fitness(&self, x: &Self::Genome) -> Self::Fitness {
        x.cos() - x * x
    }

    fn mutate<R: rand::Rng + ?Sized>(&mut self, x: &mut Self::Genome, rng: &mut R) {
        *x += rand::Rng::gen_range(rng, -0.2..0.2);
    }

    fn crossover<R: rand::Rng + ?Sized>(
        &mut self,
        a: &Self::Genome,
        b: &Self::Genome,
        _rng: &mut R,
    ) -> Self::Genome {
        0.5 * (*a + *b)
    }
}

fn main() {
    // Build and run the GA with ergonomic configuration.
    let mut ga = GA::builder(Hill)
        .pop_size(200)
        .mutation_rate(0.2)
        .crossover_rate(0.7)
        .elitism(2)
        .seed(42)
        .build();

    let result = ga.run_for(200);
    println!(
        "gen={} best x={:.4} fitness={:.6} avg_fitness={:.6}",
        result.generations, result.best.genome, result.best.fitness, result.average_fitness
    );
}

Installation

Using Cargo Add:

cargo add gentle-ga

Or add to your Cargo.toml:

[dependencies]
gentle-ga = "0.1"
Commit count: 0

cargo fmt