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}