ddo/
common.rs

1// Copyright 2020 Xavier Gillard
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of
4// this software and associated documentation files (the "Software"), to deal in
5// the Software without restriction, including without limitation the rights to
6// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7// the Software, and to permit persons to whom the Software is furnished to do so,
8// subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20//! This module defines the most basic data types that are used throughout all
21//! the code of our library (both at the abstraction and implementation levels).
22//! These are also the types your client library is likely to work with.
23
24use std::sync::Arc;
25
26// ----------------------------------------------------------------------------
27// --- VARIABLE ---------------------------------------------------------------
28// ----------------------------------------------------------------------------
29/// This type denotes a variable from the optimization problem at hand.
30/// In this case, each variable is assumed to be identified with an integer
31/// ranging from 0 until `problem.nb_vars()`
32#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
33pub struct Variable(pub usize);
34impl Variable {
35    #[inline]
36    /// This function returns the id (numeric value) of the variable.
37    ///
38    /// # Examples:
39    /// ```
40    /// # use ddo::Variable;
41    /// assert_eq!(0, Variable(0).id());
42    /// assert_eq!(1, Variable(1).id());
43    /// assert_eq!(2, Variable(2).id());
44    /// assert_eq!(3, Variable(3).id());
45    /// ```
46    pub fn id(self) -> usize {
47        self.0
48    }
49}
50
51// ----------------------------------------------------------------------------
52// --- DECISION ---------------------------------------------------------------
53// ----------------------------------------------------------------------------
54/// This denotes a decision that was made during the search. It affects a given
55/// `value` to the specified `variable`. Any given `Decision` should be
56/// understood as ```[[ variable = value ]]````
57#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
58pub struct Decision {
59    pub variable : Variable,
60    pub value    : isize
61}
62
63
64// ----------------------------------------------------------------------------
65// --- SUBPROBLEM -------------------------------------------------------------
66// ----------------------------------------------------------------------------
67/// A subproblem is a residual problem that must be solved in order to complete the
68/// resolution of the original problem which had been defined. 
69/// 
70/// # Note:
71/// Sub-problems are automatically instantiated from nodes in the exact cut-sets 
72/// of relaxed decision diagrams. If you are only discovering the API, rest 
73/// assured.. you don't need to implement any subproblem yourself.
74#[derive(Debug, Clone, PartialEq, Eq)]
75pub struct SubProblem<T> {
76    /// The root state of this sub problem
77    pub state: Arc<T>,
78    /// The root value of this sub problem
79    pub value: isize,
80    /// The path to traverse to reach this subproblem from the root
81    /// of the original problem
82    pub path: Vec<Decision>,
83    /// An upper bound on the objective reachable in this subproblem
84    pub ub: isize,
85    /// The depth of the subproblem with respect to the root problem
86    pub depth: usize,
87}
88
89// ----------------------------------------------------------------------------
90// --- THRESHOLD --------------------------------------------------------------
91// ----------------------------------------------------------------------------
92/// A threshold is a value that can be stored during the execution of a branch
93/// and bound algorithm. It is associated with a single exact state and is used
94/// to determine whether a new node with the same state is worth exploring.
95#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
96pub struct Threshold {
97    /// The value of the threshold
98    pub value: isize,
99    /// Whether a node with the given value has already been explored
100    pub explored: bool,
101}
102
103// ----------------------------------------------------------------------------
104// --- Results ----------------------------------------------------------------
105// ----------------------------------------------------------------------------
106/// A reason explaining why the mdd stopped developing
107#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
108pub enum Reason {
109    /// It stopped because the configured cutoff criterion was met
110    CutoffOccurred
111}
112
113/// The outcome of an mdd development
114#[derive(Debug, Clone)]
115pub struct Completion {
116    /// is the given solution exact (proved optimal for the given [sub-]problem)?
117    /// or is it an approximation ?
118    pub is_exact: bool,
119    /// if present the value of the best solution derived from this mdd
120    pub best_value: Option<isize>,
121}
122
123
124// ############################################################################
125// #### TESTS #################################################################
126// ############################################################################
127
128#[cfg(test)]
129mod test_var {
130    use crate::Variable;
131
132    #[test]
133    fn test_var_id() {
134        assert_eq!(0, Variable(0).id());
135        assert_eq!(1, Variable(1).id());
136        assert_eq!(2, Variable(2).id());
137        assert_eq!(3, Variable(3).id());
138    }
139}