1pub mod cmaes;
28pub mod dds;
29pub mod de;
30pub mod glue;
31pub mod lshade;
32pub mod lsrtde;
33pub mod nsga2;
34pub mod nsga3;
35pub mod parallel;
36pub mod pso;
37pub mod pt;
38pub mod sa;
39pub mod sce;
40pub mod sms_emoa;
41
42pub use cmaes::CmaEs;
43pub use dds::Dds;
44pub use de::De;
45pub use glue::{Behavioral, Glue, GlueResult, GlueSample};
46pub use lshade::LShade;
47pub use lsrtde::LSrtde;
48pub use nsga2::NsgaII;
49pub use nsga3::NsgaIII;
50pub use parallel::ensemble;
51pub use pso::Pso;
52pub use pt::{ParallelTempering, TemperingResult};
53pub use sa::{Anneal, Sa, SaResult, Schedule};
54pub use sce::Sce;
55pub use sms_emoa::SmsEmoa;
56
57use crate::problem::{Bound, Problem};
58use crate::rng::Rng;
59use crate::solution::{Report, Solution, StopReason};
60use crate::termination::Termination;
61
62pub trait Optimizer: Sync {
68 fn optimize(&self, problem: &dyn Problem, term: &Termination) -> Report;
70
71 fn with_seed(&self, seed: u64) -> Self
73 where
74 Self: Sized;
75}
76
77#[derive(Debug, Clone, Copy)]
80pub enum Algorithm {
81 Dds(Dds),
82 Sce(Sce),
83 De(De),
84 LShade(LShade),
85 LSrtde(LSrtde),
86 Pso(Pso),
87 CmaEs(CmaEs),
88}
89
90impl Optimizer for Algorithm {
91 fn optimize(&self, problem: &dyn Problem, term: &Termination) -> Report {
93 match self {
94 Algorithm::Dds(c) => c.optimize(problem, term),
95 Algorithm::Sce(c) => c.optimize(problem, term),
96 Algorithm::De(c) => c.optimize(problem, term),
97 Algorithm::LShade(c) => c.optimize(problem, term),
98 Algorithm::LSrtde(c) => c.optimize(problem, term),
99 Algorithm::Pso(c) => c.optimize(problem, term),
100 Algorithm::CmaEs(c) => c.optimize(problem, term),
101 }
102 }
103
104 fn with_seed(&self, seed: u64) -> Self {
105 match self {
106 Algorithm::Dds(c) => Algorithm::Dds(c.with_seed(seed)),
107 Algorithm::Sce(c) => Algorithm::Sce(c.with_seed(seed)),
108 Algorithm::De(c) => Algorithm::De(c.with_seed(seed)),
109 Algorithm::LShade(c) => Algorithm::LShade(c.with_seed(seed)),
110 Algorithm::LSrtde(c) => Algorithm::LSrtde(c.with_seed(seed)),
111 Algorithm::Pso(c) => Algorithm::Pso(c.with_seed(seed)),
112 Algorithm::CmaEs(c) => Algorithm::CmaEs(c.with_seed(seed)),
113 }
114 }
115}
116
117pub(crate) fn sample(bounds: &[Bound], rng: &mut Rng) -> Vec<f64> {
119 bounds
120 .iter()
121 .map(|&(lo, hi)| rng.uniform_in(lo, hi))
122 .collect()
123}
124
125#[inline]
127pub(crate) fn clamp(x: f64, lo: f64, hi: f64) -> f64 {
128 x.max(lo).min(hi)
129}
130
131pub(crate) struct Evaluator<'a> {
134 problem: &'a dyn Problem,
135 term: &'a Termination,
136 pub evaluations: usize,
137 pub best: Solution,
138}
139
140impl<'a> Evaluator<'a> {
141 pub fn new(problem: &'a dyn Problem, term: &'a Termination, first: Solution) -> Self {
143 Evaluator {
144 problem,
145 term,
146 evaluations: 1,
147 best: first,
148 }
149 }
150
151 pub fn eval(&mut self, x: &[f64]) -> f64 {
154 let v = self.problem.objective(x);
155 self.evaluations += 1;
156 if v.is_finite() && v < self.best.value {
157 self.best = Solution {
158 x: x.to_vec(),
159 value: v,
160 };
161 }
162 v
163 }
164
165 #[inline]
167 pub fn done(&self) -> bool {
168 self.term
169 .reason(self.evaluations, self.best.value)
170 .is_some()
171 }
172
173 pub fn finish(self) -> Report {
175 let stop = self
176 .term
177 .reason(self.evaluations, self.best.value)
178 .unwrap_or(StopReason::BudgetExhausted);
179 Report {
180 solution: self.best,
181 stop,
182 evaluations: self.evaluations,
183 }
184 }
185}