test(pareto,metrics,selection): pin shared-utility comparisons and arithmetic
Phase 1, tier 3 of the mutation-testing campaign — the shared Pareto / metric / selection utilities used by every multi-objective algorithm. A scoped cargo-mutants run found 75 survivors across these files; the tests below target them. - metrics/hypervolume.rs: dominates() boundary cases, non_dominated_ projection retained-set pins, hso_recursive 1-D/2-D base cases, hypervolume_nd_from_evaluations empty/non-dominating skips. - selection/tournament.rs: challenger_wins across the full feasibility cross-product + equal-objective tie; better_by_objective and better_by_feasibility branch pins; stochastic_ranking_select pf=0 feasibility ordering and count-wraps-modulo-population. - pareto/crowding.rs: exact interior crowding distance on symmetric and asymmetric fronts (pins the (next-prev)/span arithmetic). - pareto/sort.rs: three-non-dominated-then-one-dominated and a strict 3-chain producing three singleton fronts. - pareto/dominance.rs: trade-off → NonDominated, better-on-one-equal- on-other → Dominates, identical → Equal. - pareto/archive.rs: truncate boundary, trade-off kept alongside, equal candidate rejected, smaller-violation infeasible eviction. - pareto/front.rs: best_candidate keeps the first of tied minima. - metrics/spacing.rs: exact spacing for a varying-NN-distance front. src/core/problem.rs's lone survivor (decision_schema default body 'replace with vec![]') is an equivalent mutant — Vec::new() and vec![] are identical — and is left in the residue.
This commit is contained in:
@@ -180,4 +180,18 @@ mod tests {
|
||||
];
|
||||
assert!(best_candidate(&pop, &s).is_none());
|
||||
}
|
||||
|
||||
/// `best_candidate` keeps the *first* minimum on a tie — pins the strict
|
||||
/// `v < best_min` (a `<=` mutant would keep the last tied candidate).
|
||||
#[test]
|
||||
fn best_candidate_keeps_first_on_tie() {
|
||||
use crate::core::objective::Objective;
|
||||
let s = ObjectiveSpace::new(vec![Objective::minimize("f")]);
|
||||
let pop = [
|
||||
Candidate::new(1u32, Evaluation::new(vec![1.0])),
|
||||
Candidate::new(2u32, Evaluation::new(vec![1.0])),
|
||||
];
|
||||
let best = best_candidate(&pop, &s).unwrap();
|
||||
assert_eq!(best.decision, 1, "should keep the first of two tied minima");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user