use super::Optimizer;
use crate::problem::Problem;
use crate::rng::mix_seed;
use crate::solution::Report;
use crate::termination::Termination;
pub fn ensemble<O: Optimizer>(
algo: &O,
problem: &(dyn Problem + Sync),
term: &Termination,
islands: usize,
seed: u64,
) -> Report {
let n = islands.max(1);
let run = |id: usize| -> (usize, Report) {
let island = algo.with_seed(mix_seed(seed, id as u64));
(id, island.optimize(problem, term))
};
#[cfg(feature = "rayon")]
let results: Vec<(usize, Report)> = {
use rayon::prelude::*;
(0..n).into_par_iter().map(run).collect()
};
#[cfg(not(feature = "rayon"))]
let results: Vec<(usize, Report)> = (0..n).map(run).collect();
results
.into_iter()
.reduce(|best, cand| {
if cand.1.best_value() < best.1.best_value()
|| (cand.1.best_value() == best.1.best_value() && cand.0 < best.0)
{
cand
} else {
best
}
})
.map(|(_, report)| report)
.expect("at least one island always runs")
}