metaheuristics_nature/
lib.rs

1#![doc = include_str!("../README.md")]
2//! # Terminologies
3//!
4//! For unifying the terms, in this documentation,
5//!
6//! + "Iteration" is called "generation". (Avoid confusion with iterators)
7//! + "Function" that evaluates the design is called "objective function".
8//! + "Return value" of the objective function is called "fitness".
9//!
10//! # Algorithms
11//!
12//! There are two traits [`Algorithm`] and [`AlgCfg`].
13//! The previous is used to design the optimization method,
14//! and the latter is the setting interface.
15//!
16//! [`Solver`] is a simple interface for obtaining the solution, or analyzing
17//! the result. This type allows you to use the pre-defined methods without
18//! importing any traits.
19//!
20//! All provided methods are listed in the module [`methods`].
21//!
22//! For making your owned method, please see [`prelude`].
23//!
24//! # Objective Function
25//!
26//! For a quick demo with callable object, please see [`Fx`].
27//!
28//! You can define your question as an objective function through implementing
29//! [`ObjFunc`], and then the upper bound, lower bound, and an objective
30//! function [`ObjFunc::fitness()`] returns [`Fitness`] should be defined.
31//!
32//! # Random Function
33//!
34//! This crate uses a 64bit ChaCha algorithm ([`random::Rng`]) to generate
35//! uniform random values. Before that, a random seed is required. The seed is
36//! generated by `getrandom` crate, please see its support platform.
37//!
38//! # Features
39//!
40//! The crate features:
41//! + `std`: Default feature. Enable standard library function, such as timing
42//!   and threading. If `std` is disabled, crate "libm" will be enabled for the
43//!   math functions.
44//! + `rayon`: Enable parallel computation via `rayon`. Disable it for the
45//!   platform that doesn't supported threading, or if your objective function
46//!   is not complicate enough. This feature require `std` feature.
47//! + `clap`: Add CLI argument support for the provided algorithms and their
48//!   options.
49//!
50//! # Compatibility
51//!
52//! If you are using this crate for providing objective function,
53//! other downstream crates of yours may have some problems with compatibility.
54//!
55//! The most important thing is using a stable version, specifying the major
56//! version number. Then re-export (`pub use`) this crate for the downstream
57//! crates.
58//!
59//! This crate does the same things on `rand` and `rayon`.
60#![cfg_attr(doc_cfg, feature(doc_auto_cfg))]
61#![cfg_attr(not(feature = "std"), no_std)]
62extern crate alloc;
63#[cfg(not(feature = "std"))]
64extern crate core as std;
65pub use rand;
66#[cfg(feature = "rayon")]
67pub use rayon;
68
69pub use self::{
70    algorithm::*, ctx::*, fitness::*, fx_func::*, methods::*, obj_func::*, solver::*,
71    solver_builder::*,
72};
73
74/// A tool macro used to generate multiple builder functions (methods).
75///
76/// For example,
77///
78/// ```
79/// # use metaheuristics_nature::impl_builders;
80/// # type Ty = bool;
81/// # struct S {
82/// #     name1: Ty,
83/// #     name2: Ty,
84/// # }
85/// impl S {
86///     impl_builders! {
87///         /// Doc 1
88///         fn name1(Ty)
89///         /// Doc 2
90///         fn name2(Ty)
91///     }
92/// }
93/// ```
94///
95/// will become
96///
97/// ```
98/// # type Ty = bool;
99/// # struct S {
100/// #     name1: Ty,
101/// #     name2: Ty,
102/// # }
103/// impl S {
104///     /// Doc 1
105///     pub fn name1(mut self, name1: Ty) -> Self {
106///         self.name1 = name1;
107///         self
108///     }
109///     /// Doc 2
110///     pub fn name2(mut self, name2: Ty) -> Self {
111///         self.name2 = name2;
112///         self
113///     }
114/// }
115/// ```
116#[macro_export]
117macro_rules! impl_builders {
118    ($($(#[$meta:meta])* fn $name:ident($ty:ty))+) => {$(
119        $(#[$meta])*
120        pub fn $name(self, $name: $ty) -> Self {
121            Self { $name, ..self }
122        }
123    )+};
124}
125
126/// A prelude module for algorithm implementation.
127///
128/// This module includes all items of this crate, some hidden types,
129/// and external items from "ndarray" and "rayon" (if `rayon` feature enabled).
130pub mod prelude {
131    pub use super::*;
132    pub use crate::{pareto::*, random::*};
133
134    #[cfg(feature = "rayon")]
135    #[doc(no_inline)]
136    pub use crate::rayon::prelude::*;
137    #[cfg(not(feature = "std"))]
138    pub use num_traits::Float as _;
139}
140
141mod algorithm;
142mod ctx;
143mod fitness;
144mod fx_func;
145pub mod methods;
146mod obj_func;
147pub mod pareto;
148pub mod random;
149mod solver;
150mod solver_builder;
151pub mod tests;
152
153/// A marker trait for parallel computation.
154///
155/// Require `Sync + Send` if the `rayon` feature is enabled, otherwise require
156/// nothing.
157#[cfg(not(feature = "rayon"))]
158pub trait MaybeParallel {}
159#[cfg(not(feature = "rayon"))]
160impl<T> MaybeParallel for T {}
161
162/// A marker trait for parallel computation.
163///
164/// Require `Sync + Send` if the `rayon` feature is enabled, otherwise require
165/// nothing.
166#[cfg(feature = "rayon")]
167pub trait MaybeParallel: Sync + Send {}
168#[cfg(feature = "rayon")]
169impl<T: Sync + Send> MaybeParallel for T {}
170
171#[cfg(feature = "rayon")]
172macro_rules! maybe_send_box {
173    ($($traits:tt)+) => {
174        Box<dyn $($traits)+ + Send>
175    };
176}
177#[cfg(not(feature = "rayon"))]
178macro_rules! maybe_send_box {
179    ($($traits:tt)+) => {
180        Box<dyn $($traits)+ >
181    };
182}
183pub(crate) use maybe_send_box;