1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
//! A collection of nature-inspired metaheuristic algorithms.
//! ```ignore
//! use metaheuristics_nature::{Report, RGA, RGASetting, Setting, Solver, Task};
//!
//! fn main() {
//!     let mut a = RGA::new(
//!         MyObj::new(),
//!         RGASetting::default().task(Task::MinFit(1e-20)),
//!     );
//!     let ans = a.run();  // Run and get the final result
//!     let (x, y): (Vec<f64>, f64) = a.result();  // Get the optimized XY value of your function
//!     let reports: Vec<Report> = a.history();  // Get the history reports.
//! }
//! ```
pub use crate::{de::*, fa::*, pso::*, rga::*, tlbo::*, utility::*};

/// Generate random values between [0., 1.) or by range.
#[macro_export]
macro_rules! rand {
    ($lb:expr, $ub:expr) => {{
        use rand::Rng;
        rand::thread_rng().gen_range($lb..$ub)
    }};
    () => {
        rand!(0., 1.)
    };
}

/// Generate random boolean by positive factor.
#[macro_export]
macro_rules! maybe {
    ($v:expr) => {{
        use rand::Rng;
        rand::thread_rng().gen_bool($v)
    }};
}

/// Define a data structure and its builder functions.
///
/// Use `@` to denote the base settings, such as population number, task category
/// or reporting interval.
/// ```
/// use metaheuristics_nature::setting_builder;
///
/// setting_builder! {
///     /// Real-coded Genetic Algorithm settings.
///     #[derive(Default)]
///     pub struct GASetting {
///         @base,
///         @pop_num = 500,
///         cross: f64 = 0.95,
///         mutate: f64 = 0.05,
///         win: f64 = 0.95,
///         delta: f64 = 5.,
///     }
/// }
/// fn test() {
///     let s = GASetting::default().pop_num(300).cross(0.9);
/// }
/// ```
#[macro_export]
macro_rules! setting_builder {
    (
        $(#[$attr:meta])*
        $v:vis struct $name:ident {
            $(@$base:ident, $(@$base_field:ident = $base_default:expr,)*)?
            $($(#[$field_attr:meta])* $field:ident: $field_type:ty = $field_default:expr,)+
        }
    ) => {
        $(#[$attr])*
        $v struct $name {
            $($base: $crate::Setting,)?
            $($field: $field_type,)+
        }
        impl $name {
            $(setting_builder! {
                @$base,
                task: $crate::Task,
                pop_num: usize,
                rpt: u32,
            })?
            $($(#[$field_attr])* pub fn $field(mut self, $field: $field_type) -> Self {
                self.$field = $field;
                self
            })+
        }
        impl Default for $name {
            fn default() -> Self {
                Self {
                    $($base: $crate::Setting::default()$(.$base_field($base_default))*,)?
                    $($field: $field_default,)+
                }
            }
        }
    };
    (@$base:ident, $($field:ident: $field_type:ty,)+) => {
        $(pub fn $field(mut self, $field: $field_type) -> Self {
            self.$base = self.$base.$field($field);
            self
        })+
    }
}

mod de;
mod fa;
mod pso;
mod rga;
#[cfg(test)]
mod tests;
mod tlbo;
mod utility;