From 680b9bc88e2b2b3b236c38119e8a723a425374d2 Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Fri, 11 Jul 2025 09:52:21 +0100 Subject: [PATCH 1/3] Add `objective_value` method to `SolvedModel` Add a method to `SolvedModel` to retrieve the objective value for the solution. If the model failed to solve, this value may not be meaningful. Closes #25. --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ec3bd0b..8247ca9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -611,6 +611,13 @@ impl SolvedModel { self.highs.mut_ptr() } + /// Get the objective value for the solution. + /// + /// If the model failed to solve, this value may not be meaningful. + pub fn objective_value(&self) -> f64 { + unsafe { highs_sys::Highs_getObjectiveValue(self.as_ptr()) } + } + /// The status of the solution. Should be Optimal if everything went well. pub fn status(&self) -> HighsModelStatus { let model_status = unsafe { Highs_getModelStatus(self.highs.unsafe_mut_ptr()) }; From da908fbe9095d836d4e751bbe0848de0bde7bee1 Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Fri, 25 Jul 2025 07:54:32 +0100 Subject: [PATCH 2/3] Clarify that returned value is zero in case of error --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 8247ca9..6f96a98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -613,7 +613,7 @@ impl SolvedModel { /// Get the objective value for the solution. /// - /// If the model failed to solve, this value may not be meaningful. + /// If an error occurs (e.g. the model is infeasible) then the returned value may be zero. pub fn objective_value(&self) -> f64 { unsafe { highs_sys::Highs_getObjectiveValue(self.as_ptr()) } } From 238e193fe24d0b7be99950bbdf024cbc8eb4c44d Mon Sep 17 00:00:00 2001 From: Alex Dewar Date: Fri, 25 Jul 2025 07:59:19 +0100 Subject: [PATCH 3/3] Add tests --- src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 6f96a98..aa9b57a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -826,4 +826,26 @@ mod test { assert_eq!(solved.mip_gap(), f64::INFINITY); assert_eq!(solved.get_solution().columns(), &[50.0]); } + + #[test] + fn test_objective_value() { + use crate::status::HighsModelStatus::Optimal; + use crate::{Model, RowProblem, Sense}; + let mut p = RowProblem::default(); + p.add_column(1., 0..50); + let mut m = Model::new(p); + m.make_quiet(); + m.set_sense(Sense::Maximise); + let solved = m.solve(); + assert_eq!(solved.status(), Optimal); + assert_eq!(solved.objective_value(), 50.0); + } + + #[test] + fn test_objective_value_empty_model() { + use crate::{Model, RowProblem}; + let m = Model::new(RowProblem::default()); + let solved = m.solve(); + assert_eq!(solved.objective_value(), 0.0); + } }