#遗传算法 #遗传 #算法 #rust

genetic-rs

一个用于快速启动遗传算法项目的轻量级crate。

9个版本 (4个重大更新)

0.5.3 2024年6月19日
0.5.1 2024年4月12日
0.4.0 2024年2月27日
0.3.0 2024年2月13日
0.1.1 2024年1月15日

算法 中排名第459

每月下载量39
neat 中使用

MIT许可证

42KB
540

genetic-rs

github crates.io docs.rs

一个用于快速启动遗传算法项目的轻量级crate。

使用方法

注意:如果您想用此实现NEAT,请尝试neat crate

特性

首先,此crate默认包含builtingenrand特性。如果您想添加内置的交叉繁殖扩展,可以通过添加crossover特性来实现。如果您想将其并行化,可以添加rayon特性。如果您想让交叉繁殖具有物种特性,可以添加speciation特性。

一旦您按需导入所有内容,您可以定义您的基因组并实现所需的特性

#[derive(Clone, Debug)] // clone is currently a required derive for pruning nextgens.
struct MyGenome {
    field1: f32,
}

// required in all of the builtin functions as requirements of `DivsionReproduction` and `CrossoverReproduction`
impl RandomlyMutable for MyGenome {
    fn mutate(&mut self, rate: f32, rng: &mut impl rand::Rng) {
        self.field1 += rng.gen::<f32>() * rate;
    }
}

// required for `division_pruning_nextgen`.
impl DivsionReproduction for MyGenome {
    fn divide(&self, rng: &mut impl rand::Rng) -> Self {
        let mut child = self.clone();
        child.mutate(0.25, rng); // use a constant mutation rate when spawning children in pruning algorithms.
        child
    }
}

// required for the builtin pruning algorithms.
impl Prunable for MyGenome {
    fn despawn(self) {
        // unneccessary to implement this function, but it can be useful for debugging and cleaning up genomes.
        println!("{:?} died", self);
    }
}

// helper trait that allows us to use `Vec::gen_random` for the initial population.
impl GenerateRandom for MyGenome {
    fn gen_random(rng: &mut impl rand::Rng) -> Self {
        Self { field1: rng.gen() }
    }
}

一旦您有了结构体,您必须创建您的适应度函数

fn my_fitness_fn(ent: &MyGenome) -> f32 {
    // this just means that the algorithm will try to create as big a number as possible due to fitness being directly taken from the field.
    // in a more complex genetic algorithm, you will want to utilize `ent` to test them and generate a reward.
    ent.field1
}

一旦您有了奖励函数,您就可以创建一个GeneticSim对象来管理和控制进化步骤

fn main() {
    let mut rng = rand::thread_rng();
    let mut sim = GeneticSim::new(
        // you must provide a random starting population. 
        // size will be preserved in builtin nextgen fns, but it is not required to keep a constant size if you were to build your own nextgen function.
        // in this case, you do not need to specify a type for `Vec::gen_random` because of the input of `my_fitness_fn`.
        Vec::gen_random(&mut rng, 100),
        my_fitness_fn,
        division_pruning_nextgen,
    );
 
    // perform evolution (100 gens)
    for _ in 0..100 {
        sim.next_generation(); // in a genetic algorithm with state, such as a physics simulation, you'd want to do things with `sim.genomes` in between these calls
    }
 
    dbg!(sim.genomes);
}

这就是基于修剪的遗传算法的最小代码。您可以通过阅读文档查看示例来了解更复杂的系统。

许可证

本项目适用于MIT许可证。

依赖项

~270–650KB
~12K SLoC