scirs2_optimize/multiobjective/mod.rs
1//! Clean `Vec<f64>`-based multi-objective optimisation algorithms.
2//!
3//! This module provides self-contained, easy-to-use implementations of
4//! multi-objective evolutionary algorithms that work directly with Rust
5//! `Vec<f64>` slices — no ndarray wrappers required.
6//!
7//! # Modules
8//!
9//! | Module | Algorithm |
10//! |--------|-----------|
11//! | [`mod@nsga2`] | NSGA-II — Non-dominated Sorting Genetic Algorithm II (Deb 2002) |
12//! | [`mod@nsga3`] | NSGA-III — Many-objective NSGA with reference-point niching (Deb 2014) |
13//! | [`mod@moead`] | MOEA/D — Decomposition-based MOEA (Zhang 2007) |
14//! | [`pareto`] | Pareto dominance, ranking, hypervolume, and distance metrics |
15//! | [`indicators`] | Quality indicators: HV, IGD, IGD+, GD, ε-indicator, R2, spacing |
16//!
17//! # Quick start
18//!
19//! ```rust
20//! use scirs2_optimize::multiobjective::nsga2::{nsga2, Nsga2Config};
21//!
22//! // 2-variable, 2-objective ZDT1 benchmark
23//! let bounds = vec![(0.0_f64, 1.0_f64); 5];
24//! let mut cfg = Nsga2Config::default();
25//! cfg.population_size = 20;
26//! cfg.n_generations = 5;
27//!
28//! let result = nsga2(2, &bounds, |x| {
29//! let f1 = x[0];
30//! let g = 1.0 + 9.0 * x[1..].iter().sum::<f64>() / (x.len()-1) as f64;
31//! vec![f1, g * (1.0 - (f1 / g).sqrt())]
32//! }, cfg).expect("valid input");
33//!
34//! println!("Pareto front size: {}", result.pareto_front.len());
35//! ```
36//!
37//! # Many-objective (≥ 4 objectives) example
38//!
39//! ```rust
40//! use scirs2_optimize::multiobjective::nsga3::{nsga3, Nsga3Config};
41//!
42//! let n_obj = 4;
43//! let bounds: Vec<(f64, f64)> = vec![(0.0, 1.0); n_obj + 3];
44//! let mut cfg = Nsga3Config::default();
45//! cfg.population_size = 30;
46//! cfg.n_generations = 10;
47//! cfg.n_divisions = 3;
48//!
49//! let result = nsga3(n_obj, &bounds, |x| {
50//! let n = x.len();
51//! let k = n - n_obj + 1;
52//! let g: f64 = x[n-k..].iter().map(|&xi| (xi - 0.5).powi(2)).sum();
53//! let mut f = vec![0.0f64; n_obj];
54//! for i in 0..n_obj {
55//! let mut val = 1.0 + g;
56//! for j in 0..n_obj - 1 - i {
57//! val *= (x[j] * std::f64::consts::FRAC_PI_2).cos();
58//! }
59//! if i > 0 { val *= (x[n_obj - 1 - i] * std::f64::consts::FRAC_PI_2).sin(); }
60//! f[i] = val;
61//! }
62//! f
63//! }, cfg).expect("valid input");
64//!
65//! println!("Reference points: {}", result.reference_points.len());
66//! ```
67
68pub mod hypervolume;
69pub mod indicators;
70pub mod moead;
71pub mod nsga2;
72pub mod nsga3;
73pub mod pareto;
74
75// ── hypervolume module re-exports ────────────────────────────────────────────
76pub use hypervolume::{
77 exclusive_hypervolume, hypervolume_2d as hv_2d, hypervolume_3d, hypervolume_contribution_wfg,
78 hypervolume_wfg,
79};
80
81// ── indicators module re-exports ──────────────────────────────────────────────
82pub use indicators::{
83 additive_epsilon_indicator, delta_metric, dominates, generational_distance, hypervolume_2d,
84 hypervolume_contribution, hypervolume_mc, igd, igd_plus, non_dominated_sort, r2_indicator,
85 spacing_metric, spread, R2Utility,
86};
87
88// ── MOEA/D re-exports ─────────────────────────────────────────────────────────
89pub use moead::{
90 build_neighborhood, generate_weight_vectors, moead, tchebycheff_scalarization, MoeadConfig,
91 MoeadResult,
92};
93
94// ── NSGA-II re-exports ────────────────────────────────────────────────────────
95pub use nsga2::{nsga2, Individual, Nsga2Config, Nsga2Result};
96
97// ── NSGA-III re-exports ───────────────────────────────────────────────────────
98pub use nsga3::{
99 adapt_reference_points, associate_to_reference_points, generate_reference_points,
100 generate_reference_points_inner, nsga3, reference_line_distance, Nsga3Config, Nsga3Result,
101};
102
103// ── pareto module re-exports ──────────────────────────────────────────────────
104pub use pareto::{
105 crowding_distance, dominates as pareto_dominates, epsilon_indicator,
106 generational_distance as pareto_gd, hypervolume_2d as pareto_hv2d,
107 hypervolume_indicator as pareto_hv, igd as pareto_igd, non_dominated_sort as pareto_nds,
108 pareto_front, pareto_front_2d, pareto_rank, spread_metric,
109};