feat(algorithms): add PesaII (Pareto Envelope-based Selection Algorithm II)

Corne, Jerram, Knowles & Oates 2001: divides objective space into a
hyperbox grid and uses per-box population counts to drive selection
toward sparsely-populated regions.

Each generation:
- Maintain an external archive of non-dominated members
- Build a hyperbox grid (`grid_divisions` per axis on the archive's
  current axis ranges); count members per box
- Selection picks two parents by region-based tournament: choose two
  random non-empty boxes and take a uniform-random member from the
  one with fewer occupants
- Variation produces an offspring; insert into archive, dropping
  dominated members and (if archive overflows) the most-crowded
  occupant of the most-occupied box

Tests cover non-empty front on Schaffer N.1, deterministic reruns,
and panic on `archive_size == 0`.
This commit is contained in:
2026-05-05 09:51:11 -06:00
parent 283d7429bb
commit f8fd3880ac
6 changed files with 331 additions and 23 deletions
-4
View File
@@ -4,7 +4,6 @@ use rand::Rng as _;
use crate::algorithms::parallel_eval::evaluate_batch;
use crate::core::candidate::Candidate;
use crate::core::objective::ObjectiveSpace;
use crate::core::population::Population;
use crate::core::problem::Problem;
use crate::core::result::OptimizationResult;
@@ -250,9 +249,6 @@ fn smallest_neighbor_angle(references: &[Vec<f64>]) -> f64 {
if !min_angle.is_finite() { std::f64::consts::FRAC_PI_4 } else { min_angle }
}
#[allow(unused_imports)]
use crate::core::objective::Objective;
#[cfg(test)]
mod tests {
use super::*;