permu_rs/
lib.rs

1//! # permu-rs
2//!
3//! `permu-rs` is a collection of utilities for permutations. It contains useful tools to
4//! experiment with permutations, different permutation based problems and
5//! bijective-transformations.
6
7use std::fmt;
8
9// Import modules
10pub mod permutation;
11pub mod inversion;
12pub mod rim;
13pub mod problems;
14
15// Import errors
16pub mod errors;
17use errors::Error;
18
19use std::fmt::Debug;
20
21/// Contains the methods a `Population` should have.
22pub trait Population<T> : Debug {
23
24    // TODO: Document errors
25    
26    /// Returns a `Distribution` learned from the current population.
27    fn learn(&self) -> Distribution;
28
29    /// Fills the current population with samples sampled from a given `Distribution`. 
30    fn sample(&mut self, distr: &mut Distribution) -> Result<(), Error>;
31    
32    /// Fills the given `PermuPopulation` with the permutation vector 
33    /// representation of the current population .
34    fn to_permus(&self, permus: &mut permutation::PermuPopulation<T>) -> Result<(), Error>;
35    
36    /// Maps a given `PermuPopulation` into the current `Population`'s representation.
37    fn from_permus(&mut self, permus: &permutation::PermuPopulation<T>) -> Result<(), Error>;
38}
39
40/// Enum for different probability distribution types. 
41#[derive(Debug)]
42#[derive(PartialEq)]
43pub enum Distribution {
44    /// Probability distribution for permutation populations
45    PermuDistribution(Vec<Vec<usize>>, bool),
46    /// Probability distribution for inversion vector populations
47    InversionDistribution(Vec<Vec<usize>>, bool),
48    /// Probability distribution for RIM vector populations
49    RimDistribution(Vec<Vec<usize>>, bool),
50}
51
52impl fmt::Display for Distribution {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54
55        let (distr, soften, distr_type) = match self {
56            Distribution::PermuDistribution(v, s) => (v, s, "PermuDistribution"),
57            Distribution::InversionDistribution(v, s) => (v, s, "InversionDistribution"),
58            Distribution::RimDistribution(v, s) => (v, s, "RimDistribution"),
59        };
60
61        // For empty distibutions
62        if distr.len() == 0 {
63            return write!(f, "[]\n");
64        }
65
66        let mut formatted = String::from("[");
67        distr.iter()
68            .take(distr.len() -1) // Do not take the last item
69            .for_each(|row| {
70                formatted.push_str(format!("{:?},\n", row).as_str());
71            });
72
73        // Now, take the last item and write the buffer
74        formatted.push_str(format!("{:?}]", 
75                                   distr[distr.len()-1]).as_str());
76        write!(f, "{}\n{}, soften: {}\n", formatted, distr_type, soften)
77    }
78}