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}