moors/lib.rs
1//! # moors
2//!
3//! <div align="center">
4//! <strong>Multi‑Objective Optimization in Pure Rust</strong><br>
5//! Fast, extensible evolutionary algorithms with first‑class ndarray support.
6//! </div>
7//!
8//! ---
9//!
10//! ## Overview
11//!
12//! `moors` provides a battery of evolutionary algorithms for solving *multi‑objective*
13//! optimization problems. The core goals are:
14//!
15//! * **Performance** – minimal allocations, Rayon‑powered parallel loops where it matters.
16//! * **Extensibility** – every operator (sampling, crossover, mutation, selection,
17//! survival) is pluggable via pure Rust traits.
18//!
19//! Currently implemented algorithms
20//!
21//! | Family | Algorithms |
22//! |--------|------------|
23//! | NSGA | **NSGA‑II**, NSGA‑III, RNSGA‑II |
24//! | SPEA | SPEA‑2 |
25//! | Others | AGE‑MOEA, REVEA *(WIP)* |
26//!
27//! ## Quick start
28//!
29//! ```rust,no_run
30//! use ndarray::{Array1, Array2, Axis, stack};
31//!
32//! use moors::{
33//! algorithms::{AlgorithmError, Nsga2Builder},
34//! duplicates::ExactDuplicatesCleaner,
35//! operators::{SinglePointBinaryCrossover, BitFlipMutation, RandomSamplingBinary},
36//! };
37//!
38//! // ----- problem data (0/1 knapsack) -------------------------------------
39//! const WEIGHTS: [f64; 5] = [12.0, 2.0, 1.0, 4.0, 10.0];
40//! const VALUES: [f64; 5] = [ 4.0, 2.0, 1.0, 5.0, 3.0];
41//! const CAPACITY: f64 = 15.0;
42//!
43//! /// Multi‑objective fitness ⇒ [−total_value, total_weight]
44//! fn fitness(pop_genes: &Array2<f64>) -> Array2<f64> {
45//! let w = Array1::from_vec(WEIGHTS.into());
46//! let v = Array1::from_vec(VALUES.into());
47//! let total_v = pop_genes.dot(&v);
48//! let total_w = pop_genes.dot(&w);
49//! stack(Axis(1), &[(-&total_v).view(), total_w.view()]).unwrap()
50//! }
51//!
52//! /// Single inequality constraint ⇒ total_weight − CAPACITY ≤ 0
53//! fn constraints(pop_genes: &Array2<f64>) -> Array1<f64> {
54//! let w = Array1::from_vec(WEIGHTS.into());
55//! pop_genes.dot(&w) - CAPACITY
56//! }
57//!
58//! fn main() -> Result<(), AlgorithmError> {
59//! let mut algo = Nsga2Builder::default()
60//! .fitness_fn(fitness)
61//! .constraints_fn(constraints)
62//! .sampler(RandomSamplingBinary::new())
63//! .crossover(SinglePointBinaryCrossover::new())
64//! .mutation(BitFlipMutation::new(0.5))
65//! .duplicates_cleaner(ExactDuplicatesCleaner::new())
66//! .num_vars(5)
67//! .population_size(100)
68//! .crossover_rate(0.9)
69//! .mutation_rate(0.1)
70//! .num_offsprings(32)
71//! .num_iterations(200)
72//! .build()?;
73//!
74//! algo.run()?;
75//! Ok(())
76//! }
77//! ```
78//!
79//! ## Module layout
80//!
81//! * [`algorithms`](crate::algorithms) – high‑level algorithm builders
82//! * [`operators`](crate::operators) – sampling, crossover, mutation, selection, survival
83//! * [`genetic`](crate::genetic) – core data types (`Individual`, `Population`, …)
84//! * [`evaluator`](crate::evaluator) – fitness + constraints evaluation pipeline
85//! * [`random`](crate::random) – pluggable RNG abstraction
86//! * [`duplicates`](crate::duplicates) – duplicate‑handling strategies
87//!
88//! ---
89
90extern crate core;
91extern crate paste;
92
93pub mod algorithms;
94pub mod duplicates;
95pub mod evaluator;
96pub mod genetic;
97pub(crate) mod helpers;
98pub mod non_dominated_sorting;
99pub mod operators;
100mod private;
101pub mod random;
102pub use algorithms::{
103 AgeMoea, AgeMoeaBuilder, AlgorithmBuilder, AlgorithmBuilderError, AlgorithmError,
104 GeneticAlgorithm, Ibea, IbeaBuilder, InitializationError, Nsga2, Nsga2Builder, Nsga3,
105 Nsga3Builder, Revea, ReveaBuilder, Rnsga2, Rnsga2Builder, Spea2, Spea2Builder,
106};
107pub use duplicates::{
108 CloseDuplicatesCleaner, ExactDuplicatesCleaner, NoDuplicatesCleaner, PopulationCleaner,
109};
110pub use evaluator::{ConstraintsFn, EvaluatorError, FitnessFn, NoConstraints};
111pub use genetic::{
112 Individual, IndividualMOO, IndividualSOO, Population, PopulationMOO, PopulationSOO,
113};
114pub use helpers::linalg::cross_euclidean_distances;
115pub use operators::selection;
116pub use operators::survival;
117pub use operators::{
118 AgeMoeaSurvival, ArithmeticCrossover, BitFlipMutation, CrossoverOperator,
119 DanAndDenisReferencePoints, DisplacementMutation, ExponentialCrossover,
120 FrontsAndRankingBasedSurvival, GaussianMutation, InversionMutation, MutationOperator,
121 Nsga2RankCrowdingSurvival, Nsga3ReferencePointsSurvival, OrderCrossover, PermutationSampling,
122 RandomSamplingBinary, RandomSamplingFloat, RandomSamplingInt, RandomSelectionMOO,
123 RankAndScoringSelectionMOO, ReveaReferencePointsSurvival, Rnsga2ReferencePointsSurvival,
124 SamplingOperator, ScrambleMutation, SelectionOperator, SimulatedBinaryCrossover,
125 SinglePointBinaryCrossover, Spea2KnnSurvival, StructuredReferencePoints, SurvivalOperator,
126 SwapMutation, TwoPointBinaryCrossover, UniformBinaryCrossover, UniformBinaryMutation,
127 UniformRealMutation, evolve::EvolveError,
128};
129pub use random::{MOORandomGenerator, NoopRandomGenerator, RandomGenerator, TestDummyRng};