use crate::{ATol, Bound, DecisionVariable, DecisionVariableError, Instance, Kind, VariableID};
impl Instance {
pub fn decision_variable_names(&self) -> std::collections::BTreeSet<String> {
self.decision_variables
.values()
.filter_map(|var| var.metadata.name.clone())
.collect()
}
pub fn get_decision_variable_by_name(
&self,
name: &str,
subscripts: Vec<i64>,
) -> Option<&DecisionVariable> {
self.decision_variables.values().find(|var| {
var.metadata.name.as_deref() == Some(name) && var.metadata.subscripts == subscripts
})
}
pub fn next_variable_id(&self) -> VariableID {
self.decision_variables
.last_key_value()
.map(|(id, _)| VariableID::from(id.into_inner() + 1))
.unwrap_or(VariableID::from(0))
}
pub fn new_decision_variable(
&mut self,
kind: Kind,
bound: Bound,
substituted_value: Option<f64>,
atol: ATol,
) -> Result<&mut DecisionVariable, DecisionVariableError> {
let id = self.next_variable_id();
let dv = DecisionVariable::new(id, kind, bound, substituted_value, atol)?;
self.decision_variables.insert(id, dv);
Ok(self.decision_variables.get_mut(&id).unwrap())
}
pub fn new_binary(&mut self) -> &mut DecisionVariable {
self.new_decision_variable(Kind::Binary, Bound::of_binary(), None, ATol::default())
.unwrap()
}
pub fn new_integer(&mut self) -> &mut DecisionVariable {
self.new_decision_variable(Kind::Integer, Bound::default(), None, ATol::default())
.unwrap()
}
pub fn new_continuous(&mut self) -> &mut DecisionVariable {
self.new_decision_variable(Kind::Continuous, Bound::default(), None, ATol::default())
.unwrap()
}
pub fn new_semi_integer(&mut self) -> &mut DecisionVariable {
self.new_decision_variable(Kind::SemiInteger, Bound::default(), None, ATol::default())
.unwrap()
}
pub fn new_semi_continuous(&mut self) -> &mut DecisionVariable {
self.new_decision_variable(
Kind::SemiContinuous,
Bound::default(),
None,
ATol::default(),
)
.unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{coeff, linear, Sense};
use maplit::btreemap;
use std::collections::BTreeMap;
#[test]
fn test_next_variable_id() {
let decision_variables = BTreeMap::new();
let objective = coeff!(1.0).into();
let instance = Instance::new(
Sense::Minimize,
objective,
decision_variables,
BTreeMap::new(),
)
.unwrap();
assert_eq!(instance.next_variable_id(), VariableID::from(0));
let decision_variables = btreemap! {
VariableID::from(5) => DecisionVariable::binary(VariableID::from(5)),
VariableID::from(8) => DecisionVariable::binary(VariableID::from(8)),
VariableID::from(100) => DecisionVariable::binary(VariableID::from(100)),
};
let objective = (linear!(5) + coeff!(1.0)).into();
let instance = Instance::new(
Sense::Minimize,
objective,
decision_variables,
BTreeMap::new(),
)
.unwrap();
assert_eq!(instance.next_variable_id(), VariableID::from(101));
}
#[test]
fn test_next_variable_id_with_new_binary() {
let decision_variables = BTreeMap::new();
let objective = coeff!(1.0).into();
let mut instance = Instance::new(
Sense::Minimize,
objective,
decision_variables,
BTreeMap::new(),
)
.unwrap();
let var1 = instance.new_binary();
assert_eq!(var1.id(), VariableID::from(0));
let var2 = instance.new_binary();
assert_eq!(var2.id(), VariableID::from(1));
assert_eq!(instance.next_variable_id(), VariableID::from(2));
}
}