From b766b294bf37ee8d2e400544e2a3814d9baa6c31 Mon Sep 17 00:00:00 2001 From: Mohammed Ghannam Date: Wed, 13 Mar 2024 08:20:27 +0100 Subject: [PATCH] Support SCIPfreeTransform (#129) * Support SCIPfreeTransform * Cargo fmt --- CHANGELOG.md | 1 + src/model.rs | 34 ++++++++++++++++++++++++++++++++++ src/scip.rs | 5 +++++ 3 files changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e13e0d3..92ad026 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ # Unreleased ### Added +- Support `SCIPfreeTransform` to allow for iterated solving. ### Fixed ### Changed ### Remove diff --git a/src/model.rs b/src/model.rs index b359217..d0180f2 100644 --- a/src/model.rs +++ b/src/model.rs @@ -454,6 +454,21 @@ impl Model { pub fn n_lp_iterations(&self) -> usize { self.scip.n_lp_iterations() } + + /// Frees the transformed problem and returns the model the ProblemCreated state where you + /// can add variables and constraints, useful for iterated solving + pub fn free_transform(self) -> Model { + self.scip + .free_transform() + .unwrap_or_else(|retcode| panic!("SCIP returned unexpected retcode {:?}", retcode)); + Model { + scip: self.scip, + state: ProblemCreated { + vars: self.state.vars, + conss: self.state.conss, + }, + } + } } /// A trait for optimization models with a problem created. @@ -1753,4 +1768,23 @@ mod tests { .set_int_param("display/verblevel", 0) .unwrap(); } + + #[test] + fn free_transform() { + let model = create_model(); + let solved_model = model.solve(); + let obj_val = solved_model.obj_val(); + + let mut second_model = solved_model.free_transform(); + + let x3 = second_model.add_var(0.0, f64::INFINITY, 1.0, "x3", VarType::Integer); + + let bound = 2.0; + second_model.add_cons(vec![x3], &[1.0], 0.0, bound, "x3-cons"); + + let second_solved = second_model.solve(); + let expected_obj = obj_val + bound; + assert_eq!(second_solved.status(), Status::Optimal); + assert!((second_solved.obj_val() - expected_obj).abs() <= 1e-6); + } } diff --git a/src/scip.rs b/src/scip.rs index a37d769..a066c78 100644 --- a/src/scip.rs +++ b/src/scip.rs @@ -983,6 +983,11 @@ impl ScipPtr { let stored = unsafe { stored.assume_init() }; Ok(stored != 0) } + + pub(crate) fn free_transform(&self) -> Result<(), Retcode> { + scip_call!(ffi::SCIPfreeTransform(self.raw)); + Ok(()) + } } impl Drop for ScipPtr {