use crate::{
common::expression::LinearExpr,
solver::simplex::slack_dictionary::variable::DictionaryVariableKey,
};
use slotmap::new_key_type;
use std::{fmt, mem};
new_key_type! {
pub struct DictionaryRowKey;
}
impl fmt::Display for DictionaryRowKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DictionaryRowKey({:?})", self.0)
}
}
#[derive(Debug, Clone)]
pub struct DictionaryRow {
basic_var: DictionaryVariableKey,
non_basics_expr: LinearExpr<DictionaryVariableKey>,
}
impl DictionaryRow {
pub fn new(
basic_var: DictionaryVariableKey,
non_basics_expr: LinearExpr<DictionaryVariableKey>,
) -> Self {
DictionaryRow {
basic_var,
non_basics_expr,
}
}
pub fn add_non_basic(&mut self, var: DictionaryVariableKey, coefficient: f64) {
self.non_basics_expr.add_term(var, coefficient);
}
pub fn remove_non_basic(&mut self, var: DictionaryVariableKey) -> Option<f64> {
self.non_basics_expr.remove_term(&var)
}
pub fn non_basic_coefficient(&self, var: &DictionaryVariableKey) -> f64 {
self.non_basics_expr.coefficient(var)
}
pub fn replace_non_basic_with_expr(
&mut self,
var: DictionaryVariableKey,
replacement_expr: &LinearExpr<DictionaryVariableKey>,
) -> Option<f64> {
self.non_basics_expr
.replace_var_with_expr(var, replacement_expr)
}
pub fn switch_to_basic(&mut self, non_basic_var: DictionaryVariableKey) -> Option<f64> {
if let Some(coefficient) = self.non_basics_expr.remove_term(&non_basic_var) {
let old_basic_var = mem::replace(&mut self.basic_var, non_basic_var);
self.non_basics_expr.add_term(old_basic_var, -1.0);
self.non_basics_expr.scale(1.0 / -coefficient);
Some(coefficient)
} else {
None
}
}
pub fn basic_var(&self) -> DictionaryVariableKey {
self.basic_var
}
pub fn value(&self) -> f64 {
self.non_basics_expr.constant
}
pub fn expr(&self) -> LinearExpr<DictionaryVariableKey> {
self.non_basics_expr.clone()
}
}
impl fmt::Display for DictionaryRow {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} = {}", self.basic_var, self.non_basics_expr)
}
}