use super::*;
use crate::{v1, Constraint, ConstraintID, DecisionVariable, Function, VariableID};
use std::collections::BTreeMap;
impl Instance {
pub fn new(
sense: Sense,
objective: Function,
decision_variables: BTreeMap<VariableID, DecisionVariable>,
constraints: BTreeMap<ConstraintID, Constraint>,
) -> anyhow::Result<Self> {
Self::builder()
.sense(sense)
.objective(objective)
.decision_variables(decision_variables)
.constraints(constraints)
.build()
}
}
impl ParametricInstance {
pub fn new(
sense: Sense,
objective: Function,
decision_variables: BTreeMap<VariableID, DecisionVariable>,
parameters: BTreeMap<VariableID, v1::Parameter>,
constraints: BTreeMap<ConstraintID, Constraint>,
) -> anyhow::Result<Self> {
Self::builder()
.sense(sense)
.objective(objective)
.decision_variables(decision_variables)
.parameters(parameters)
.constraints(constraints)
.build()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
coeff,
constraint::{Constraint, ConstraintID},
linear, DecisionVariable, VariableID,
};
use maplit::btreemap;
#[test]
fn test_instance_new_fails_with_undefined_variable_in_objective() {
let decision_variables = btreemap! {
VariableID::from(1) => DecisionVariable::binary(VariableID::from(1)),
VariableID::from(2) => DecisionVariable::binary(VariableID::from(2)),
};
let objective = (linear!(999) + coeff!(1.0)).into();
let constraints = BTreeMap::new();
insta::assert_snapshot!(
Instance::new(
Sense::Minimize,
objective,
decision_variables,
constraints,
)
.unwrap_err(),
@r#"Undefined variable ID is used: VariableID(999)"#
);
}
#[test]
fn test_instance_new_fails_with_undefined_variable_in_constraint() {
let decision_variables = btreemap! {
VariableID::from(1) => DecisionVariable::binary(VariableID::from(1)),
VariableID::from(2) => DecisionVariable::binary(VariableID::from(2)),
};
let objective = (linear!(1) + coeff!(1.0)).into();
let constraints = btreemap! {
ConstraintID::from(1) => Constraint::equal_to_zero(ConstraintID::from(1), (linear!(999) + coeff!(1.0)).into()),
};
insta::assert_snapshot!(
Instance::new(
Sense::Minimize,
objective,
decision_variables,
constraints,
)
.unwrap_err(),
@r#"Undefined variable ID is used: VariableID(999)"#
);
}
#[test]
fn test_parametric_instance_new_succeeds() {
let decision_variables = btreemap! {
VariableID::from(1) => DecisionVariable::binary(VariableID::from(1)),
VariableID::from(2) => DecisionVariable::binary(VariableID::from(2)),
};
let parameters = btreemap! {
VariableID::from(100) => v1::Parameter { id: 100, name: Some("p1".to_string()), ..Default::default() },
VariableID::from(101) => v1::Parameter { id: 101, name: Some("p2".to_string()), ..Default::default() },
};
let objective = (linear!(1) + linear!(100) + coeff!(1.0)).into();
let constraints = btreemap! {
ConstraintID::from(1) => Constraint::equal_to_zero(ConstraintID::from(1), (linear!(2) + linear!(101) + coeff!(1.0)).into()),
ConstraintID::from(2) => Constraint::less_than_or_equal_to_zero(ConstraintID::from(2), (linear!(1) + linear!(100) + coeff!(2.0)).into()),
};
let parametric_instance = ParametricInstance::new(
Sense::Maximize,
objective,
decision_variables,
parameters,
constraints,
)
.unwrap();
assert_eq!(*parametric_instance.sense(), Sense::Maximize);
assert_eq!(parametric_instance.decision_variables().len(), 2);
assert_eq!(parametric_instance.parameters().len(), 2);
assert_eq!(parametric_instance.constraints().len(), 2);
}
#[test]
fn test_parametric_instance_new_fails_with_duplicated_variable_id() {
let decision_variables = btreemap! {
VariableID::from(1) => DecisionVariable::binary(VariableID::from(1)),
VariableID::from(2) => DecisionVariable::binary(VariableID::from(2)),
};
let parameters = btreemap! {
VariableID::from(1) => v1::Parameter { id: 1, name: Some("p1".to_string()), ..Default::default() },
VariableID::from(100) => v1::Parameter { id: 100, name: Some("p2".to_string()), ..Default::default() },
};
let objective = (linear!(1) + coeff!(1.0)).into();
let constraints = BTreeMap::new();
insta::assert_snapshot!(
ParametricInstance::new(
Sense::Minimize,
objective,
decision_variables,
parameters,
constraints,
)
.unwrap_err(),
@"Duplicated variable ID is found in definition: VariableID(1)"
);
}
#[test]
fn test_parametric_instance_new_fails_with_undefined_variable_in_objective() {
let decision_variables = btreemap! {
VariableID::from(1) => DecisionVariable::binary(VariableID::from(1)),
VariableID::from(2) => DecisionVariable::binary(VariableID::from(2)),
};
let parameters = btreemap! {
VariableID::from(100) => v1::Parameter { id: 100, name: Some("p1".to_string()), ..Default::default() },
};
let objective = (linear!(999) + coeff!(1.0)).into();
let constraints = BTreeMap::new();
insta::assert_snapshot!(
ParametricInstance::new(
Sense::Minimize,
objective,
decision_variables,
parameters,
constraints,
)
.unwrap_err(),
@r#"Undefined variable ID is used: VariableID(999)"#
);
}
#[test]
fn test_parametric_instance_new_fails_with_undefined_variable_in_constraint() {
let decision_variables = btreemap! {
VariableID::from(1) => DecisionVariable::binary(VariableID::from(1)),
VariableID::from(2) => DecisionVariable::binary(VariableID::from(2)),
};
let parameters = btreemap! {
VariableID::from(100) => v1::Parameter { id: 100, name: Some("p1".to_string()), ..Default::default() },
};
let objective = (linear!(1) + coeff!(1.0)).into();
let constraints = btreemap! {
ConstraintID::from(1) => Constraint::equal_to_zero(ConstraintID::from(1), (linear!(999) + coeff!(1.0)).into()),
};
insta::assert_snapshot!(
ParametricInstance::new(
Sense::Minimize,
objective,
decision_variables,
parameters,
constraints,
)
.unwrap_err(),
@r#"Undefined variable ID is used: VariableID(999)"#
);
}
}