Skip to content

Commit

Permalink
Merge pull request #175 from scipopt/separator-test
Browse files Browse the repository at this point in the history
Add minimal model fn, extra test for separator
  • Loading branch information
mmghannam authored Dec 15, 2024
2 parents d9cbda0 + c7f4ed2 commit 7eb4904
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,14 @@ impl HasScipPtr for ModelSolving {
}
}

/// Creates a minimal `Model` instance and sets off a lot of SCIP plugins, useful for writing tests.
pub fn minimal_model() -> Model<ProblemCreated> {
Model::default()
.set_presolving(ParamSetting::Off)
.set_heuristics(ParamSetting::Off)
.set_separating(ParamSetting::Off)
}

impl<T> Model<T> {
/// Returns the status of the optimization model.
pub fn status(&self) -> Status {
Expand Down
6 changes: 5 additions & 1 deletion src/scip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,15 @@ impl ScipPtr {
lhs,
rhs,
) };
let scip_cons = unsafe { scip_cons.assume_init() };
let mut scip_cons = unsafe { scip_cons.assume_init() };
for (i, var) in vars.iter().enumerate() {
scip_call! { ffi::SCIPaddCoefLinear(self.raw, scip_cons, var.raw, coefs[i]) };
}
scip_call! { ffi::SCIPaddCons(self.raw, scip_cons) };
let stage = unsafe { ffi::SCIPgetStage(self.raw) };
if stage == ffi::SCIP_Stage_SCIP_STAGE_SOLVING {
scip_call! { ffi::SCIPreleaseCons(self.raw, &mut scip_cons) };
}
Ok(scip_cons)
}

Expand Down
51 changes: 50 additions & 1 deletion src/separator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ impl From<SeparationResult> for SCIP_Result {
#[cfg(test)]
mod tests {
use super::*;
use crate::Model;
use crate::{
minimal_model, Model, ModelSolving, ModelWithProblem, ObjSense, ProblemOrSolving, VarType,
};

struct NotRunningSeparator;

Expand Down Expand Up @@ -96,4 +98,51 @@ mod tests {
)
.solve();
}

struct ConsAddingSeparator {
model: ModelSolving,
}

impl Separator for ConsAddingSeparator {
fn execute_lp(&mut self) -> SeparationResult {
// adds a row representing the sum of all variables >= 1
let vars = self.model.vars();
let varlen = vars.len();

self.model
.add_cons(vars, &vec![1.0; varlen], 5.0, 5.0, "cons_added");
SeparationResult::ConsAdded
}
}

#[test]
fn cons_adding_separator() {
let mut model = minimal_model()
.hide_output()
.set_obj_sense(ObjSense::Maximize);

let x = model.add_var(0.0, 1.0, 1.0, "x", VarType::Binary);
let y = model.add_var(0.0, 1.0, 1.0, "y", VarType::Binary);

model.add_cons(vec![x, y], &[1.0, 1.0], 1.0, 1.0, "cons1");

let sep = ConsAddingSeparator {
model: model.clone_for_plugins(),
};

let solved = model
.include_separator(
"ConsAddingSeparator",
"",
1000000,
1,
1.0,
false,
false,
Box::new(sep),
)
.solve();

assert_eq!(solved.status(), crate::Status::Infeasible);
}
}

0 comments on commit 7eb4904

Please sign in to comment.