lp_modeler/dsl/
problem.rs1extern crate uuid;
2
3use std::collections::HashMap;
4use std::ops::AddAssign;
5
6
7use self::uuid::Uuid;
8use dsl::*;
9
10#[derive(Debug, PartialEq)]
20pub enum LpObjective {
21 Minimize,
22 Maximize,
23}
24
25pub trait Problem {
26 fn add_objective_expression(&mut self, expr_arena: &mut LpExpression);
27 fn add_constraints(&mut self, contraint_expr: &LpConstraint);
28}
29
30#[derive(Debug)]
62pub struct LpProblem {
63 pub name: &'static str,
64 pub unique_name: String,
65 pub objective_type: LpObjective,
66 pub obj_expr_arena: Option<LpExpression>,
67 pub constraints: Vec<LpConstraint>,
68}
69
70impl LpProblem {
71 pub fn new(name: &'static str, objective: LpObjective) -> LpProblem {
73 let unique_name = format!("{}_{}", name, Uuid::new_v4());
74 LpProblem {
75 name,
76 unique_name,
77 objective_type: objective,
78 obj_expr_arena: None,
79 constraints: Vec::new(),
80 }
81 }
82
83
84 pub fn variables(&self) -> HashMap<String, (usize, usize)> {
87 let mut lst: HashMap<String, (usize, usize)> = HashMap::new();
88 for constraint_index in 0..self.constraints.len() {
89 let constraint = self.constraints.get(constraint_index).unwrap();
90 constraint.var(constraint.0.get_root_index(), constraint_index, &mut lst);
91 }
92 lst
93 }
94}
95
96impl Problem for LpProblem {
97 fn add_objective_expression(&mut self, expr_arena: &mut LpExpression) {
98 if let Some(e) = &self.obj_expr_arena {
99 let mut simple_expr = expr_arena
100 .merge_cloned_arenas(&e, LpExprOp::Addition);
101 let _ = simple_expr.simplify().split_off_constant();
102 self.obj_expr_arena = Some(simple_expr);
103 } else {
104 let mut simple_expr = expr_arena.clone();
105 let _ = simple_expr.simplify().split_off_constant();
106 self.obj_expr_arena = Some(simple_expr);
107 }
108 }
109
110 fn add_constraints(&mut self, constraint_expr: &LpConstraint) {
111 self.constraints.push(constraint_expr.clone());
112 }
113}
114
115macro_rules! impl_addassign_for_generic_problem {
116 ($problem: ty) => {
117 impl AddAssign<LpConstraint> for $problem {
119 fn add_assign(&mut self, _rhs: LpConstraint) {
120 self.add_constraints(&_rhs);
121 }
122 }
123 impl<T> AddAssign<T> for $problem
125 where
126 T: Into<LpExpression>,
127 {
128 fn add_assign(&mut self, _rhs: T) {
129 self.add_objective_expression(&mut _rhs.into());
130 }
131 }
132 };
133}
134impl_addassign_for_generic_problem!(LpProblem);