Skip to main content

cnvx_core/
model.rs

1use crate::*;
2use std::ops::AddAssign;
3
4/// Represents an optimization model containing variables, constraints, and an objective.
5///
6/// The [`Model`] struct is the central container for defining a linear (or eventually more general)
7/// optimization problem. Users add variables, set an objective function, and add constraints.
8/// Solvers then operate on a [`Model`] to produce a [`Solution`].
9///
10/// # Examples
11///
12/// ```rust
13/// # use cnvx_core::*;
14/// let mut model = Model::new();
15///
16/// // Add variables
17/// let x1 = model.add_var().finish();
18/// let x2 = model.add_var().finish();
19///
20/// // Define objective: maximize x1 + 2*x2
21/// model.add_objective(Objective::maximize(x1 + 2.0 * x2).name("Z"));
22///
23/// // Add constraints
24/// model += (x1 + x2).leq(10.0);
25/// model += x1.geq(0.0);
26/// model += x2.geq(0.0);
27/// ```
28#[derive(Debug, Default)]
29pub struct Model {
30    /// List of variables in the model.
31    pub vars: Vec<Var>,
32
33    /// List of constraints in the model.
34    pub constraints: Vec<Constraint>,
35
36    /// Optional objective function. Currently supports only a single objective.
37    /// TODO: Replace with `Vec<Objective>` for multi-objective optimization.
38    pub objective: Option<Objective>,
39}
40
41impl Model {
42    /// Creates a new model with logging enabled by default.
43    pub fn new() -> Self {
44        Self { ..Default::default() }
45    }
46
47    pub fn shape(&self) -> (usize, usize) {
48        (self.constraints.len(), self.vars.len())
49    }
50
51    /// Adds a new variable to the model and returns a [`VarBuilder`] for ergonomic configuration.
52    ///
53    /// # Example
54    ///
55    /// ```rust
56    /// # use cnvx_core::*;
57    /// let mut model = Model::new();
58    /// let x = model.add_var().integer().finish();
59    /// ```
60    pub fn add_var(&mut self) -> VarBuilder<'_> {
61        let id = VarId(self.vars.len());
62        self.vars.push(Var {
63            id,
64            lb: Some(0.0),
65            ub: None,
66            is_integer: false,
67            is_artificial: false,
68        });
69        VarBuilder { model: self, var: id }
70    }
71
72    /// Sets the objective function of the model.
73    ///
74    /// # Example
75    ///
76    /// ```rust
77    /// # use cnvx_core::*;
78    /// let mut model = Model::new();
79    /// let x = model.add_var().finish();
80    /// model.add_objective(Objective::maximize(1.0 * x).name("Profit"));
81    /// ```
82    pub fn add_objective(&mut self, obj: Objective) {
83        self.objective = Some(obj);
84    }
85
86    /// Returns a read-only slice of variables.
87    pub fn vars(&self) -> &[Var] {
88        &self.vars
89    }
90
91    /// Returns a read-only slice of constraints.
92    pub fn constraints(&self) -> &[Constraint] {
93        &self.constraints
94    }
95
96    /// Returns a reference to the model's objective function, if set.
97    pub fn objective(&self) -> Option<&Objective> {
98        self.objective.as_ref()
99    }
100}
101
102/// Allows adding constraints to the model using the `+=` operator.
103///
104/// # Example
105///
106/// ```rust
107/// # use cnvx_core::*;
108/// let mut model = Model::new();
109/// let x = model.add_var().finish();
110/// model += x.geq(0.0);
111/// ```
112impl AddAssign<Constraint> for Model {
113    fn add_assign(&mut self, rhs: Constraint) {
114        self.constraints.push(rhs);
115    }
116}