-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Breaking out the model.rs file into smaller files
- Loading branch information
Showing
12 changed files
with
217 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use pest::iterators::Pairs; | ||
|
||
use crate::{ | ||
common::{AsFloat, RuleExt}, | ||
Rule, | ||
}; | ||
|
||
#[derive(Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct Coefficient { | ||
pub var_name: String, | ||
pub coefficient: f64, | ||
} | ||
|
||
impl TryFrom<Pairs<'_, Rule>> for Coefficient { | ||
type Error = anyhow::Error; | ||
|
||
#[allow(clippy::unreachable, clippy::wildcard_enum_match_arm)] | ||
fn try_from(values: Pairs<'_, Rule>) -> anyhow::Result<Self> { | ||
let (mut value, mut var_name) = (1.0, String::new()); | ||
for item in values { | ||
match item.as_rule() { | ||
r if r.is_numeric() => { | ||
value *= item.as_float()?; | ||
} | ||
Rule::VARIABLE => { | ||
var_name = item.as_str().to_string(); | ||
} | ||
_ => unreachable!("Unexpected rule encountered"), | ||
} | ||
} | ||
Ok(Self { var_name, coefficient: value }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use super::{coefficient::Coefficient, sos::SOSClass}; | ||
|
||
#[derive(Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub enum Constraint { | ||
Standard { name: String, coefficients: Vec<Coefficient>, sense: String, rhs: f64 }, | ||
SOS { name: String, kind: SOSClass, coefficients: Vec<Coefficient> }, | ||
} | ||
|
||
impl Constraint { | ||
#[must_use] | ||
pub fn name(&self) -> String { | ||
match self { | ||
Self::Standard { name, .. } | Self::SOS { name, .. } => name.to_string(), | ||
} | ||
} | ||
|
||
#[must_use] | ||
pub fn coefficients(&self) -> &[Coefficient] { | ||
match self { | ||
Self::Standard { coefficients, .. } | Self::SOS { coefficients, .. } => coefficients, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use std::collections::{hash_map::Entry, HashMap}; | ||
|
||
use crate::model::{constraint::Constraint, objective::Objective, sense::Sense, variable::VariableType}; | ||
|
||
#[derive(Debug, Default)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct LPProblem { | ||
pub problem_name: String, | ||
pub problem_sense: Sense, | ||
pub variables: HashMap<String, VariableType>, | ||
pub objectives: Vec<Objective>, | ||
pub constraints: HashMap<String, Constraint>, | ||
} | ||
|
||
impl LPProblem { | ||
#[must_use] | ||
pub fn with_problem_name(self, problem_name: &str) -> Self { | ||
Self { problem_name: problem_name.to_string(), ..self } | ||
} | ||
|
||
#[must_use] | ||
pub fn with_sense(self, problem_sense: Sense) -> Self { | ||
Self { problem_sense, ..self } | ||
} | ||
|
||
pub fn add_variable(&mut self, name: &str) { | ||
if !name.is_empty() { | ||
self.variables.entry(name.to_string()).or_default(); | ||
} | ||
} | ||
|
||
pub fn set_var_bounds(&mut self, name: &str, kind: VariableType) { | ||
if !name.is_empty() { | ||
match self.variables.entry(name.to_string()) { | ||
Entry::Occupied(k) if matches!(kind, VariableType::SemiContinuous) => { | ||
k.into_mut().set_semi_continuous(); | ||
} | ||
Entry::Occupied(k) => *k.into_mut() = kind, | ||
Entry::Vacant(k) => { | ||
k.insert(kind); | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn add_objective(&mut self, objectives: Vec<Objective>) { | ||
for ob in &objectives { | ||
ob.coefficients.iter().for_each(|c| { | ||
self.add_variable(&c.var_name); | ||
}); | ||
} | ||
self.objectives = objectives; | ||
} | ||
|
||
pub fn add_constraints(&mut self, constraints: Vec<Constraint>) { | ||
for con in constraints { | ||
let name = if con.name().is_empty() { format!("UnnamedConstraint:{}", self.constraints.len()) } else { con.name() }; | ||
con.coefficients().iter().for_each(|c| { | ||
self.add_variable(&c.var_name); | ||
}); | ||
self.constraints.entry(name).or_insert(con); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
pub mod coefficient; | ||
pub mod constraint; | ||
pub mod lp_problem; | ||
pub mod objective; | ||
pub mod sense; | ||
pub mod sos; | ||
pub mod variable; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
use crate::model::coefficient::Coefficient; | ||
|
||
#[derive(Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct Objective { | ||
pub name: String, | ||
pub coefficients: Vec<Coefficient>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#[derive(Debug, Default, PartialEq, Eq)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub enum Sense { | ||
#[default] | ||
Minimize, | ||
Maximize, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use std::str::FromStr; | ||
|
||
#[derive(Debug)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub enum SOSClass { | ||
S1, | ||
S2, | ||
} | ||
|
||
impl FromStr for SOSClass { | ||
type Err = anyhow::Error; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
match s { | ||
"s1" | "s1::" => Ok(Self::S1), | ||
"s2" | "s2::" => Ok(Self::S2), | ||
_ => Err(anyhow::anyhow!("Invalid SOS class: {}", s)), | ||
} | ||
} | ||
} |
Oops, something went wrong.