use std::fs::File;
use std::io::Write;
use forge_core::testfn::{Dtlz2, Zdt1};
use forge_core::{NsgaII, NsgaIII, ParetoFront, Termination};
fn write_csv(path: &str, front: &ParetoFront) {
let mut f = File::create(path).expect("create csv");
let m = front.solutions[0].objectives.len();
let header: Vec<String> = (0..m).map(|j| format!("f{}", j + 1)).collect();
writeln!(f, "{}", header.join(",")).unwrap();
for o in front.objective_vectors() {
let row: Vec<String> = o.iter().map(|v| format!("{v:.10}")).collect();
writeln!(f, "{}", row.join(",")).unwrap();
}
}
fn main() {
let args: Vec<String> = std::env::args().collect();
let zdt1_out = args.get(1).expect("arg1: nsga2 zdt1 csv path");
let dtlz2_out = args.get(2).expect("arg2: nsga3 dtlz2 csv path");
let zdt1 = Zdt1::new(30);
let f1 = NsgaII {
pop_size: 100,
seed: 1,
..NsgaII::default()
}
.optimize(&zdt1, &Termination::budget(20_000));
write_csv(zdt1_out, &f1);
eprintln!(
"NSGA-II/ZDT1: {} solutions, {} evals",
f1.len(),
f1.evaluations
);
let dtlz2 = Dtlz2::new(3, 12);
let f2 = NsgaIII {
pop_size: 92,
divisions: 12,
seed: 1,
..NsgaIII::default()
}
.optimize_within(&dtlz2, &Termination::budget(40_000));
write_csv(dtlz2_out, &f2);
eprintln!(
"NSGA-III/DTLZ2: {} solutions, {} evals",
f2.len(),
f2.evaluations
);
}