mod base_value;
mod coefficient;
mod evaluated_solution;
mod indicator;
mod linear_combination;
mod objective_value;
#[cfg(test)]
mod tests;
pub use base_value::BaseValue;
pub use coefficient::Coefficient;
pub use evaluated_solution::EvaluatedSolution;
pub use indicator::Indicator;
pub use linear_combination::LinearCombination;
pub use objective_value::ObjectiveValue;
pub struct Objective<S> {
hierarchy_levels: Vec<LinearCombination<S>>,
}
impl<S> Objective<S> {
pub fn evaluate(&self, solution: S) -> EvaluatedSolution<S> {
let objective_value_hierarchy: Vec<BaseValue> = self
.hierarchy_levels
.iter()
.map(|level| level.evaluate(&solution))
.collect();
EvaluatedSolution::new(solution, ObjectiveValue::new(objective_value_hierarchy))
}
pub fn zero(&self) -> ObjectiveValue {
ObjectiveValue::new(vec![BaseValue::Zero; self.hierarchy_levels.len()])
}
pub fn maximum(&self) -> ObjectiveValue {
ObjectiveValue::new(vec![BaseValue::Maximum; self.hierarchy_levels.len()])
}
pub fn print_objective_value(&self, objective_value: &ObjectiveValue) {
for (level, value) in self.hierarchy_levels.iter().zip(objective_value.iter()) {
println!(" * {}: {}", level, value);
}
}
pub fn print_objective_value_with_comparison(
&self,
objective_value: &ObjectiveValue,
comparison: &ObjectiveValue,
) {
for ((level, value), comparison_value) in self
.hierarchy_levels
.iter()
.zip(objective_value.iter())
.zip(comparison.iter())
{
println!(
" * {}: {} {}",
level,
value,
value.print_difference(*comparison_value)
);
}
}
pub fn objective_value_to_json(&self, objective_value: &ObjectiveValue) -> serde_json::Value {
let mut json_object = serde_json::json!({});
for (level, base_value) in self.hierarchy_levels.iter().zip(objective_value.iter()) {
match base_value {
BaseValue::Integer(value) => {
json_object[level.to_string()] = serde_json::json!(value);
}
BaseValue::Float(value) => {
json_object[level.to_string()] = serde_json::json!(value);
}
BaseValue::Duration(value) => {
json_object[level.to_string()] = serde_json::json!(value.to_string());
}
BaseValue::Zero => {
json_object[level.to_string()] = serde_json::json!("Zero");
}
BaseValue::Maximum => {
json_object[level.to_string()] = serde_json::json!("Maximum");
}
}
}
json_object
}
}
impl<S> Objective<S> {
pub fn new(hierarchy_levels: Vec<LinearCombination<S>>) -> Objective<S> {
Objective { hierarchy_levels }
}
pub fn new_single_level(linear_combination: LinearCombination<S>) -> Objective<S> {
Objective::new(vec![linear_combination])
}
pub fn new_single_indicator(indicator: Box<dyn Indicator<S>>) -> Objective<S> {
Objective::new_single_level(LinearCombination::new(vec![(
Coefficient::from(1),
indicator,
)]))
}
pub fn new_single_indicator_per_level(indicators: Vec<Box<dyn Indicator<S>>>) -> Objective<S> {
Objective::new(
indicators
.into_iter()
.map(|indicator| LinearCombination::new(vec![(Coefficient::from(1), indicator)]))
.collect(),
)
}
}