metaheuristics_nature/algorithm.rs
1use crate::prelude::*;
2
3/// Algorithm configurations. A trait for preparing the algorithm.
4///
5/// The setting type is actually a builder of the [`AlgCfg::Algorithm`] type.
6///
7/// Please note that the setting should not overlap with the [`SolverBuilder`].
8pub trait AlgCfg {
9 /// Associated algorithm.
10 type Algorithm<F: ObjFunc>: Algorithm<F> + 'static;
11 /// Create the algorithm.
12 fn algorithm<F: ObjFunc>(self) -> Self::Algorithm<F>;
13 /// Default population number.
14 fn pop_num() -> usize {
15 200
16 }
17}
18
19/// The methods of the metaheuristic algorithms.
20///
21/// 1. Implement [`AlgCfg`] trait then indicate to a "method" type.
22/// 1. Implement `Algorithm` trait on the "method" type.
23///
24/// Usually, the "method" type that implements this trait will not leak from the
25/// API. All most common dataset is store in the [`Ctx`] type. So the "method"
26/// type is used to store the additional data if any.
27///
28/// ```
29/// use metaheuristics_nature::prelude::*;
30///
31/// /// A setting with fields.
32/// #[derive(Default)]
33/// pub struct MySetting1 {
34/// my_option: u32,
35/// }
36///
37/// /// The implementation of the structure with fields.
38/// impl AlgCfg for MySetting1 {
39/// type Algorithm<F: ObjFunc> = Method;
40/// fn algorithm<F: ObjFunc>(self) -> Self::Algorithm<F> {
41/// Method /* inherit setting */
42/// }
43/// }
44///
45/// /// No setting.
46/// #[derive(Default)]
47/// pub struct MySetting2;
48///
49/// /// The implementation of a tuple-like structure.
50/// impl AlgCfg for MySetting2 {
51/// type Algorithm<F: ObjFunc> = Method;
52/// fn algorithm<F: ObjFunc>(self) -> Self::Algorithm<F> {
53/// Method
54/// }
55/// }
56///
57/// /// The type implements our algorithm.
58/// pub struct Method;
59///
60/// impl<F: ObjFunc> Algorithm<F> for Method {
61/// fn generation(&mut self, ctx: &mut Ctx<F>, rng: &mut Rng) {
62/// /* implement the method */
63/// }
64/// }
65/// ```
66///
67/// The complete algorithm will be implemented by the [`Solver`](crate::Solver)
68/// type automatically. All you have to do is implement the "initialization"
69/// method and "generation" method, which are corresponded to the
70/// [`Algorithm::init()`] and [`Algorithm::generation()`] respectively.
71///
72/// The generic type `F: ObjFunc` is the objective function marker, which is
73/// used to allow storing the types that are related to the objective function
74/// for the implementor `Self`. An actual example is
75/// [`crate::methods::pso::Method`].
76pub trait Algorithm<F: ObjFunc>: MaybeParallel {
77 /// Initialization implementation.
78 ///
79 /// The information of the [`Ctx`] can be obtained or modified at this phase
80 /// preliminarily.
81 ///
82 /// The default behavior is do nothing.
83 #[inline]
84 #[allow(unused_variables)]
85 fn init(&mut self, ctx: &mut Ctx<F>, rng: &mut Rng) {}
86
87 /// Processing implementation of each generation.
88 fn generation(&mut self, ctx: &mut Ctx<F>, rng: &mut Rng);
89}
90
91/// Implement for `Box<dyn Algorithm<F>>`.
92///
93/// See also [`SolverBox`].
94impl<F: ObjFunc, T: Algorithm<F> + ?Sized> Algorithm<F> for alloc::boxed::Box<T> {
95 #[inline]
96 fn init(&mut self, ctx: &mut Ctx<F>, rng: &mut Rng) {
97 self.as_mut().init(ctx, rng);
98 }
99
100 #[inline]
101 fn generation(&mut self, ctx: &mut Ctx<F>, rng: &mut Rng) {
102 self.as_mut().generation(ctx, rng);
103 }
104}