Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 47 additions & 82 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl Model<ProblemCreated> {
delay: bool,
pricer: Box<dyn Pricer>,
) -> Self {
self.scip()
self.scip
.include_pricer(name, desc, priority, delay, pricer)
.expect("Failed to include pricer at state ProblemCreated");
self
Expand Down Expand Up @@ -391,12 +391,12 @@ impl Model<Solving> {
var_type: VarType,
) -> Rc<Variable> {
let var = self
.scip()
.scip
.create_var_solving(lb, ub, obj, name, var_type)
.expect("Failed to create variable in state ProblemCreated");
let var = Variable {
raw: var,
scip: self.scip().clone(),
scip: self.scip.clone(),
};

Rc::new(var)
Expand All @@ -408,7 +408,7 @@ impl Model<Solving> {
///
/// This method panics if not called in the `Solving` state, it should only be used from plugins implementations.
pub fn focus_node(&self) -> Node {
self.scip().focus_node()
self.scip.focus_node()
}

/// Creates a new child node of the current node and returns it.
Expand All @@ -417,7 +417,7 @@ impl Model<Solving> {
///
/// This method panics if not called from plugins implementations.
pub fn create_child(&mut self) -> Node {
self.scip()
self.scip
.create_child()
.expect("Failed to create child node in state ProblemCreated")
}
Expand All @@ -444,12 +444,12 @@ impl Model<Solving> {
var_type: VarType,
) -> Rc<Variable> {
let var = self
.scip()
.scip
.create_priced_var(lb, ub, obj, name, var_type)
.expect("Failed to create variable in state ProblemCreated");
let var = Variable {
raw: var,
scip: self.scip().clone(),
scip: self.scip.clone(),
};

Rc::new(var)
Expand All @@ -464,9 +464,9 @@ impl Model<Solving> {
/// A reference-counted pointer to the variable.
pub fn var_in_prob(&self, var_prob_id: usize) -> Option<Variable> {
unsafe {
ScipPtr::var_from_id(self.scip().raw, var_prob_id).map(|v| Variable {
ScipPtr::var_from_id(self.scip.raw, var_prob_id).map(|v| Variable {
raw: v,
scip: self.scip().clone(),
scip: self.scip.clone(),
})
}
}
Expand All @@ -480,7 +480,7 @@ impl Model<Solving> {
/// # Returns
/// A boolean indicating whether the row is infeasible from the local bounds.
pub fn add_cut(&mut self, cut: Row, force_cut: bool) -> bool {
self.scip()
self.scip
.add_row(cut, force_cut)
.expect("Failed to add row in state ProblemCreated")
}
Expand Down Expand Up @@ -547,25 +547,25 @@ macro_rules! impl_ModelWithProblem {

/// Returns a vector of all variables in the optimization model.
fn vars(&self) -> Vec<Rc<Variable>> {
let scip_vars = self.scip().vars(false);
let scip_vars = self.scip.vars(false);
scip_vars
.into_iter()
.map(|(_i,v)| Variable {
raw: v,
scip: self.scip().clone(),
scip: self.scip.clone(),
})
.map(Rc::new)
.collect()
}

/// Returns the variable with the given ID, if it exists.
fn var(&self, var_id: VarId) -> Option<Rc<Variable>> {
let vars = self.scip().vars(false);
let vars = self.scip.vars(false);
for (i, v) in vars {
if i == var_id {
return Some(Rc::new(Variable {
raw: v,
scip: self.scip().clone(),
scip: self.scip.clone(),
}));
}
}
Expand All @@ -575,30 +575,30 @@ macro_rules! impl_ModelWithProblem {

/// Returns the number of variables in the optimization model.
fn n_vars(&self) -> usize {
self.scip().n_vars()
self.scip.n_vars()
}

/// Returns the number of constraints in the optimization model.
fn n_conss(&self) -> usize {
self.scip().n_conss()
self.scip.n_conss()
}

/// Returns a vector of all constraints in the optimization model.
fn conss(&self) -> Vec<Rc<Constraint>> {
let scip_conss = self.scip().conss(false);
let scip_conss = self.scip.conss(false);
scip_conss
.into_iter()
.map(|c| Constraint {
raw: c,
scip: self.scip().clone(),
scip: self.scip.clone(),
})
.map(Rc::new)
.collect()
}

/// Writes the optimization model to a file with the given path and extension.
fn write(&self, path: &str, ext: &str) -> Result<(), Retcode> {
self.scip().write(path, ext)?;
self.scip.write(path, ext)?;
Ok(())
}

Expand Down Expand Up @@ -800,11 +800,11 @@ macro_rules! impl_ProblemOrSolving {

/// Creates a new solution initialized to zero.
fn create_sol(&self) -> Solution {
let sol_ptr = self.scip()
let sol_ptr = self.scip
.create_sol()
.expect("Failed to create solution in state ProblemCreated");
Solution {
scip_ptr: self.scip().clone(),
scip_ptr: self.scip.clone(),
raw: sol_ptr,
}
}
Expand All @@ -814,7 +814,7 @@ macro_rules! impl_ProblemOrSolving {
/// # Returns
/// A `Result` indicating whether the solution was added successfully.
fn add_sol(&self, sol: Solution) -> Result<(), SolError> {
let succesfully_stored = self.scip().add_sol(sol).expect("Failed to add solution");
let succesfully_stored = self.scip.add_sol(sol).expect("Failed to add solution");
if succesfully_stored {
Ok(())
} else {
Expand All @@ -834,7 +834,7 @@ macro_rules! impl_ProblemOrSolving {
/// This method panics if the variable cannot be added in the current state, or if the variable is not binary.
fn add_cons_coef_setppc(&mut self, cons: Rc<Constraint>, var: Rc<Variable>) {
assert_eq!(var.var_type(), VarType::Binary);
self.scip()
self.scip
.add_cons_coef_setppc(cons, var)
.expect("Failed to add constraint coefficient in state ProblemCreated");
}
Expand All @@ -852,7 +852,7 @@ macro_rules! impl_ProblemOrSolving {
///
/// This method panics if the coefficient cannot be added in the current state.
fn add_cons_coef(&mut self, cons: Rc<Constraint>, var: Rc<Variable>, coef: f64) {
self.scip()
self.scip
.add_cons_coef(cons, var, coef)
.expect("Failed to add constraint coefficient in state ProblemCreated");
}
Expand Down Expand Up @@ -892,7 +892,7 @@ macro_rules! impl_ProblemOrSolving {
assert_eq!(quad_vars_1.len(), quad_vars_2.len());
assert_eq!(quad_vars_1.len(), quad_coefs.len());
let cons = self
.scip()
.scip
.create_cons_quadratic(
lin_vars,
lin_coefs,
Expand All @@ -907,7 +907,7 @@ macro_rules! impl_ProblemOrSolving {
let cons = Rc::new(
Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
}
);
cons
Expand Down Expand Up @@ -942,12 +942,12 @@ macro_rules! impl_ProblemOrSolving {
) -> Rc<Constraint> {
assert_eq!(vars.len(), coefs.len());
let cons = self
.scip()
.scip
.create_cons(vars, coefs, lhs, rhs, name)
.expect("Failed to create constraint in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -969,12 +969,12 @@ macro_rules! impl_ProblemOrSolving {
fn add_cons_set_part(&mut self, vars: Vec<Rc<Variable>>, name: &str) -> Rc<Constraint> {
assert!(vars.iter().all(|v| v.var_type() == VarType::Binary));
let cons = self
.scip()
.scip
.create_cons_set_part(vars, name)
.expect("Failed to add constraint set partition in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -996,12 +996,12 @@ macro_rules! impl_ProblemOrSolving {
fn add_cons_set_cover(&mut self, vars: Vec<Rc<Variable>>, name: &str) -> Rc<Constraint> {
assert!(vars.iter().all(|v| v.var_type() == VarType::Binary));
let cons = self
.scip()
.scip
.create_cons_set_cover(vars, name)
.expect("Failed to add constraint set cover in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -1023,12 +1023,12 @@ macro_rules! impl_ProblemOrSolving {
fn add_cons_set_pack(&mut self, vars: Vec<Rc<Variable>>, name: &str) -> Rc<Constraint> {
assert!(vars.iter().all(|v| v.var_type() == VarType::Binary));
let cons = self
.scip()
.scip
.create_cons_set_pack(vars, name)
.expect("Failed to add constraint set packing in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -1050,12 +1050,12 @@ macro_rules! impl_ProblemOrSolving {
/// This method panics if the constraint cannot be created in the current state.
fn add_cons_cardinality(&mut self, vars: Vec<Rc<Variable>>, cardinality: usize, name: &str) -> Rc<Constraint> {
let cons = self
.scip()
.scip
.create_cons_cardinality(vars, cardinality, name)
.expect("Failed to add cardinality constraint");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand Down Expand Up @@ -1088,12 +1088,12 @@ macro_rules! impl_ProblemOrSolving {
assert_eq!(vars.len(), coefs.len());
assert_eq!(bin_var.var_type(), VarType::Binary);
let cons = self
.scip()
.scip
.create_cons_indicator(bin_var, vars, coefs, rhs, name)
.expect("Failed to create constraint in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -1120,8 +1120,8 @@ macro_rules! impl_WithSolutions {
fn best_sol(&self) -> Option<Solution> {
if self.n_sols() > 0 {
let sol = Solution {
scip_ptr: self.scip().clone(),
raw: self.scip().best_sol().unwrap(),
scip_ptr: self.scip.clone(),
raw: self.scip.best_sol().unwrap(),
};
Some(sol)
} else {
Expand All @@ -1131,7 +1131,7 @@ macro_rules! impl_WithSolutions {

/// Returns the number of solutions found by the optimization model.
fn n_sols(&self) -> usize {
self.scip().n_sols()
self.scip.n_sols()
}

})*
Expand Down Expand Up @@ -1164,27 +1164,27 @@ macro_rules! impl_WithSolvingStats {

/// Returns the objective value of the best solution found by the optimization model.
fn obj_val(&self) -> f64 {
self.scip().obj_val()
self.scip.obj_val()
}

/// Returns the best bound (dualbound) proven so far.
fn best_bound(&self) -> f64 {
self.scip().best_bound()
self.scip.best_bound()
}

/// Returns the number of nodes explored by the optimization model.
fn n_nodes(&self) -> usize {
self.scip().n_nodes()
self.scip.n_nodes()
}

/// Returns the total solving time of the optimization model.
fn solving_time(&self) -> f64 {
self.scip().solving_time()
self.scip.solving_time()
}

/// Returns the number of LP iterations performed by the optimization model.
fn n_lp_iterations(&self) -> usize {
self.scip().n_lp_iterations()
self.scip.n_lp_iterations()
}

})*
Expand All @@ -1193,41 +1193,6 @@ macro_rules! impl_WithSolvingStats {

impl_WithSolvingStats!(for Model<Solved>, Model<Solving>, Model<ProblemCreated>);

/// A trait for optimization models with any state that hold a pointer to the underlying SCIP instance.
pub trait HasScipPtr {
/// Returns a reference-counted pointer to the underlying SCIP instance.
fn scip(&self) -> Rc<ScipPtr>;

/// Returns a pointer to the underlying SCIP instance.
///
/// # Safety
///
/// This method is unsafe because it returns a raw pointer to the underlying SCIP instance.
/// The caller must ensure that the pointer is used safely and correctly.
#[cfg(feature = "raw")]
unsafe fn scip_ptr(&self) -> *mut ffi::SCIP {
self.scip().raw
}
}

impl HasScipPtr for Model<ProblemCreated> {
fn scip(&self) -> Rc<ScipPtr> {
self.scip.clone()
}
}

impl HasScipPtr for Model<Solved> {
fn scip(&self) -> Rc<ScipPtr> {
self.scip.clone()
}
}

impl HasScipPtr for Model<Solving> {
fn scip(&self) -> Rc<ScipPtr> {
self.scip.clone()
}
}

/// 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()
Expand Down Expand Up @@ -1634,7 +1599,7 @@ mod tests {
"c2",
);

let scip_ptr = unsafe { model.scip_ptr() };
let scip_ptr = model.scip.raw;
assert!(!scip_ptr.is_null());
}

Expand Down
Loading
Loading