1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! # `duplicates` – Keeping the Gene Pool Diverse
//!
//! Excessive duplicates can cripple an evolutionary algorithm: the search
//! spends generations evaluating essentially the **same** individual, genetic
//! diversity drops, and the population risks converging to sub‑optimal regions
//! of the design space.
//!
//! The **`duplicates`** module provides pluggable strategies—called
//! [`PopulationCleaner`]s—to detect and discard repeated or near‑repeated
//! genomes before the next generation starts.
//!
//! | Cleaner | Suitable for | Criterion | Complexity |
//! |---------|--------------|-----------|-------------|
//! | [`ExactDuplicatesCleaner`] | Binary / discrete genomes <br>(e.g. 0/1 strings) | Two individuals are duplicates **iff** every gene is bit‑wise identical. | `O(N log N)` via hashing |
//! | [`CloseDuplicatesCleaner`] | Real‑valued or mixed genomes | Two individuals are duplicates if their **Euclidean distance ≤ ε** (configurable). | `O(N²)` naïve, but *N* is typically pruned first |
//!
//! Implementations must return a **new** `PopulationGenes` with duplicates
//! filtered out; they never mutate the input arrays in‑place, allowing the
//! caller to decide whether to reuse or drop the originals.
//!
//! ### Quick example
//!
//! ```rust, ignore
//! use moors::duplicates::ExactDuplicatesCleaner;
//! use moors::genetic::PopulationGenes;
//!
//! let population: PopulationGenes = /* ... */;
//! let cleaner = ExactDuplicatesCleaner::new();
//! let unique = cleaner.remove(&population, None);
//! println!("Removed {} duplicates", population.len() - unique.len());
//! ```
//!
//! In continuous domains you would choose `CloseDuplicatesCleaner` instead and
//! configure the `epsilon` threshold when you construct it.
//!
//! ### No‑op marker
//!
//! [`NoDuplicatesCleaner`] exists only as an *annotational* placeholder when no
//! cleaning is desired. Attempting to call its `remove` method will panic.
//!
//! ---
//!
//! **Tip:** Combine a `PopulationCleaner` with diversity‑aware selection and
//! survival operators to further reduce the risk of premature convergence.
pub use CloseDuplicatesCleaner;
pub use ExactDuplicatesCleaner;
use Array2;
/// A trait for removing duplicates (exact or close) from a population.
///
/// The `remove` method accepts an optional reference population.
/// If `None`, duplicates are computed within the population;
/// if provided, duplicates are determined by comparing each row in the population to all rows in the reference.
/// A no-op cleaner for the “default” case:
;