4 个版本
0.1.3 | 2023年5月22日 |
---|---|
0.1.2 | 2023年5月21日 |
0.1.1 | 2023年5月17日 |
0.1.0 | 2023年5月16日 |
1026 在 算法 中
每月 51 次下载
150KB
2K SLoC
rusty_genes
rusty_genes 是一个 Rust 库,旨在简化进化算法的实现和实验,特别是针对基于排列的问题。此库不适用于简单的即插即用,而是提供一系列可定制和组装的模块,以匹配您特定问题的需求。它鼓励用户积极参与算法的构建,以促进灵活性和可扩展性。
rusty_genes 的一个关键特性是支持通过实现一些核心方法来创建自定义算法。这种可扩展性允许用户尝试新的进化策略和技术,推动遗传算法的可能性的边界。
rusty_genes 通过独立的模块提供进化算法的基本组件,允许高度定制。这些组件包括各种选择策略、交叉策略和变异策略,以及定义进化模型和个体的结构。
该库仅支持最大化问题。如果您的用例涉及最小化,您需要通过调整适应度函数或问题表示将其转换为最大化问题。
特性
该库目前实现了两种进化算法
- 标准遗传算法 (GA)
- 自适应遗传算法:该算法根据计算出的多样性值动态调整交叉和变异率。这通过交叉操作在多样性高时促进现有多样性的利用,并在多样性低时通过引入和维持更多的多样性来鼓励探索。
rusty_genes 支持以下选择策略
- 锦标赛选择
- 轮盘赌选择
- 玻尔兹曼选择
- 排名选择
- 线性选择
- 精英选择
它还提供各种交叉策略
- 广义分区交叉 2 (GPX2)
- 顺序构造交叉 (SCX)
- 边缘重组交叉 (ERX)
- 部分映射交叉 (PMX)
- 订单交叉(OX)
- 循环交叉(CX)
- 单点交叉(SPX)
RustyGenes支持以下变异策略:
- 交换变异
- 洗牌变异
- 倒置变异
- 插入变异
- 重复变异
用法
以下是如何使用库解决OneMax问题的示例
use rusty_genes::*;
use rand::{distributions::Standard, prelude::*};
/// Represents an individual in the OneMax problem.
///
/// The `genome` is a binary string represented as a vector of booleans. Each boolean
/// represents a bit, and the fitness of an individual is the ratio of 'true' bits to
/// the total number of bits in this binary string.
#[derive(Debug, Clone, PartialEq)]
pub struct OneMax {
genome: Vec<bool>,
fitness: f64,
}
impl OneMax {
// Returns the binary string of the individual.
pub fn genome(&self) -> &[bool] {
&self.genome
}
}
/// Conversion from a `Vec<bool>` to a `OneMax` individual.
///
/// This allows a binary string to be directly converted into an individual.
impl From<Vec<bool>> for OneMax {
fn from(genome: Vec<bool>) -> Self {
Self {
genome,
fitness: 0.0,
}
}
}
/// Implements the method required by the [`Individual`] trait for the OneMax problem.
impl Individual for OneMax {
/// Returns the fitness of the individual.
fn fitness(&self) -> f64 {
self.fitness
}
}
/// Allows the creation of a new random individual for the OneMax problem.
impl RandomIndividual<usize> for OneMax {
/// Generates a new random individual for the OneMax problem.
///
/// The `length` parameter determines the length of the binary string (i.e., the genome),
/// and the `rng` parameter is a random number generator used to generate the binary string.
fn new_random<R: Rng>(length: &usize, rng: &mut R) -> Self {
let bits = rng.sample_iter(Standard);
let genome = Vec::from_iter(bits.take(*length));
Self::from(genome)
}
}
/// The evolutionary model for the OneMax problem.
///
/// This struct provides methods for crossover, mutation, and evaluation operations specific
/// to the OneMax problem.
#[derive(Debug, Default)]
pub struct OneMaxEvolutionModel;
/// Implements the methods required by the [`EvolutionModel`] trait for the OneMax problem.
impl EvolutionModel for OneMaxEvolutionModel {
type Individual = OneMax;
type Rng = SmallRng;
/// Creates a new random number generator from entropy.
fn rng() -> Self::Rng {
SmallRng::from_entropy()
}
/// Performs a single point crossover on the parents' genomes to create a new individual.
fn crossover(
&self,
parent1: &Self::Individual,
parent2: &Self::Individual,
rng: &mut Self::Rng,
) -> Self::Individual {
CrossoverStrategy::SinglePoint
.crossover(&parent1.genome, &parent2.genome, rng)
.into()
}
/// Mutates the individual's genome by using the duplicate mutation strategy.
fn mutate(&self, individual: &mut Self::Individual, rng: &mut Self::Rng) {
MutationStrategy::Duplicate.mutate(&mut individual.genome, rng);
}
/// Evaluates the individual's fitness by calculating the ratio of `true` bits to the total
/// number of bits in its genome.
fn evaluate(&self, individual: &mut Self::Individual) {
let one_bits = individual.genome.iter().filter(|&&one| one).count();
let total_bits = individual.genome.len();
individual.fitness = one_bits as f64 / total_bits as f64;
}
}
// Create an instance of the evolutionary model.
let one_max = OneMaxEvolutionModel;
// Use the Genetic Algorithm to solve the problem.
let ga = GeneticAlgorithm::build_evolution(one_max);
// Use default parameters of the Genetic Algorithm.
let ga_params = GeneticAlgorithmParameters::default();
// Run the algorithm until the fitness of the fittest individual is close to 1 or
// the number of generations exceeds 100.
let solution = ga.run(&ONE_MAX_LENGTH, &ga_params, |population| {
population.fittest().fitness() < 0.999999 && population.generation() <= 100
});
// Verify that the solution is correct.
assert!(solution.genome().iter().all(|&one| one == true));
致谢
该项目是合作努力的结果。OpenAI的AI,ChatGPT-4,在文档和实现方面都提供了帮助。
许可证
RustyGenes遵循MIT许可证。
该项目处于早期阶段,欢迎贡献。请随时提出问题或提交pull请求。
免责声明
这是初始版本,随着项目的演变可能会发生变化。请自行承担使用风险。
依赖项
~4.5MB
~43K SLoC