1pub mod cmaes;
24pub mod dds;
25pub mod de;
26pub mod nsga2;
27pub mod nsga3;
28pub mod parallel;
29pub mod pso;
30pub mod pt;
31pub mod sa;
32pub mod sce;
33
34pub use cmaes::CmaEs;
35pub use dds::Dds;
36pub use de::De;
37pub use nsga2::NsgaII;
38pub use nsga3::NsgaIII;
39pub use parallel::ensemble;
40pub use pso::Pso;
41pub use pt::{ParallelTempering, TemperingResult};
42pub use sa::{Anneal, Sa, SaResult, Schedule};
43pub use sce::Sce;
44
45use crate::problem::{Bound, Problem};
46use crate::rng::Rng;
47use crate::solution::{Report, Solution, StopReason};
48use crate::termination::Termination;
49
50pub trait Optimizer: Sync {
56 fn optimize(&self, problem: &dyn Problem, term: &Termination) -> Report;
58
59 fn with_seed(&self, seed: u64) -> Self
61 where
62 Self: Sized;
63}
64
65#[derive(Debug, Clone, Copy)]
68pub enum Algorithm {
69 Dds(Dds),
70 Sce(Sce),
71 De(De),
72 Pso(Pso),
73 CmaEs(CmaEs),
74}
75
76impl Optimizer for Algorithm {
77 fn optimize(&self, problem: &dyn Problem, term: &Termination) -> Report {
79 match self {
80 Algorithm::Dds(c) => c.optimize(problem, term),
81 Algorithm::Sce(c) => c.optimize(problem, term),
82 Algorithm::De(c) => c.optimize(problem, term),
83 Algorithm::Pso(c) => c.optimize(problem, term),
84 Algorithm::CmaEs(c) => c.optimize(problem, term),
85 }
86 }
87
88 fn with_seed(&self, seed: u64) -> Self {
89 match self {
90 Algorithm::Dds(c) => Algorithm::Dds(c.with_seed(seed)),
91 Algorithm::Sce(c) => Algorithm::Sce(c.with_seed(seed)),
92 Algorithm::De(c) => Algorithm::De(c.with_seed(seed)),
93 Algorithm::Pso(c) => Algorithm::Pso(c.with_seed(seed)),
94 Algorithm::CmaEs(c) => Algorithm::CmaEs(c.with_seed(seed)),
95 }
96 }
97}
98
99pub(crate) fn sample(bounds: &[Bound], rng: &mut Rng) -> Vec<f64> {
101 bounds
102 .iter()
103 .map(|&(lo, hi)| rng.uniform_in(lo, hi))
104 .collect()
105}
106
107#[inline]
109pub(crate) fn clamp(x: f64, lo: f64, hi: f64) -> f64 {
110 x.max(lo).min(hi)
111}
112
113pub(crate) struct Evaluator<'a> {
116 problem: &'a dyn Problem,
117 term: &'a Termination,
118 pub evaluations: usize,
119 pub best: Solution,
120}
121
122impl<'a> Evaluator<'a> {
123 pub fn new(problem: &'a dyn Problem, term: &'a Termination, first: Solution) -> Self {
125 Evaluator {
126 problem,
127 term,
128 evaluations: 1,
129 best: first,
130 }
131 }
132
133 pub fn eval(&mut self, x: &[f64]) -> f64 {
136 let v = self.problem.objective(x);
137 self.evaluations += 1;
138 if v.is_finite() && v < self.best.value {
139 self.best = Solution {
140 x: x.to_vec(),
141 value: v,
142 };
143 }
144 v
145 }
146
147 #[inline]
149 pub fn done(&self) -> bool {
150 self.term
151 .reason(self.evaluations, self.best.value)
152 .is_some()
153 }
154
155 pub fn finish(self) -> Report {
157 let stop = self
158 .term
159 .reason(self.evaluations, self.best.value)
160 .unwrap_or(StopReason::BudgetExhausted);
161 Report {
162 solution: self.best,
163 stop,
164 evaluations: self.evaluations,
165 }
166 }
167}