test(sms_emoa,pesa2,paes,random_search): pin remaining algorithm helpers
Phase 1, final algorithm batch: - sms_emoa: pick_drop_index returns the singleton worst front, and finds the least-HV-contributor at a non-zero index. - pesa2: build_grid empty/corner-point boxing; region_tournament prefers the less-crowded grid box (statistical majority). - paes: deterministic non-empty front + archive cap. - random_search: evaluation count = iterations*batch; best is no worse than any sampled candidate.
This commit is contained in:
@@ -305,4 +305,26 @@ mod tests {
|
||||
let r = opt.run(&Sphere1D);
|
||||
assert!(r.best.is_some());
|
||||
}
|
||||
|
||||
/// PAES must return a non-empty Pareto archive on a 2-objective problem
|
||||
/// and be deterministic with a fixed seed. Pins the run-loop
|
||||
/// bookkeeping against degenerate / comparison mutants.
|
||||
#[test]
|
||||
fn produces_deterministic_nonempty_front() {
|
||||
let make = || {
|
||||
Paes::new(
|
||||
PaesConfig { iterations: 40, archive_size: 10, seed: 5 },
|
||||
RealBounds::new(vec![(-5.0, 5.0)]),
|
||||
GaussianMutation { sigma: 0.3 },
|
||||
)
|
||||
};
|
||||
let r1 = make().run(&SchafferN1);
|
||||
let r2 = make().run(&SchafferN1);
|
||||
assert!(!r1.pareto_front.is_empty());
|
||||
let f1: Vec<Vec<f64>> = r1.pareto_front.iter().map(|c| c.evaluation.objectives.clone()).collect();
|
||||
let f2: Vec<Vec<f64>> = r2.pareto_front.iter().map(|c| c.evaluation.objectives.clone()).collect();
|
||||
assert_eq!(f1, f2);
|
||||
// Archive never exceeds its configured cap.
|
||||
assert!(r1.pareto_front.len() <= 10);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user