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
//! Provides the [`Status`](crate::Status) enum
use num::Float;
use std::fmt::Debug;
/// Custom status function
///
/// It's a [`Box`]'ed [`FnMut`] trait (see why [here](https://stackoverflow.com/a/59035722)),
/// which allows you not only to access values of the signature variables, but also to bring
/// external variables and use them, too (for example, for storing results in an array).
///
/// See the [`print`](Status#method.print) method for the signature explanation.
pub type Custom<'a, F, const N: usize> = Box<dyn FnMut(usize, F, F, [F; N], F, [F; N]) + 'a>;
/// Status function
pub enum Status<'a, F: Float + Debug, const N: usize> {
/// Don't print status
None,
/// Print status when `k` is divisable by `nk`
Periodic {
/// A number of iterations between calls
nk: usize,
},
/// Custom: choose your own!
Custom {
/// Custom function
f: Custom<'a, F, N>,
},
}
impl<'a, F: Float + Debug, const N: usize> Status<'a, F, N> {
/// Print the status
///
/// Arguments:
/// * `k` --- Current iteration;
/// * `t` --- Current temperature;
/// * `f` --- Current solution;
/// * `p` --- Current point;
/// * `best_f` --- Current best solution;
/// * `best_p` --- Current point of the best solution.
pub fn print(&mut self, k: usize, t: F, f: F, p: [F; N], best_f: F, best_p: [F; N]) {
match self {
Status::None => (),
Status::Periodic { nk } => {
if k % *nk == 0 {
println!(
"k: {k}\nt: {t:#?}:\ncurrent: {f:#?} at {p:#?}\nbest: {best_f:#?} at {best_p:#?}\n"
);
}
}
Status::Custom { f: fun } => fun(k, t, f, p, best_f, best_p),
}
}
}