Skip to content

Commit

Permalink
Add variable is Solving state && free sol after adding (#100)
Browse files Browse the repository at this point in the history
* Latest changes (#99)

* Test solution printing

* Update version number

* Update CHANGELOG

* Move ScipPtr struct and methods to its own module (#96)

* Update version number (#84)

* Test solution printing

* Update version number

* Update CHANGELOG

* Primal heuristic plugin (#85)

* Add primal heuristic plugin

* Add primal heuristic plugin

* Update CHANGELOG

* Raise lowest coverage limit (#86)

* Fix links

* Rename back method name

* Use correct file name

* CI: use download links from github (#87)

* CI: use download links from github

* Use ubuntu download link

* Generate correct download link from version

* Change status of project in README (#94)

* Move scipptr struct and methods to its own module

* Update changelog

* Make raw scip ptr visible to crate

* Solving state, represents methods accessible from plugin implementations (#97)

* Separate solution methods to its own trait (#98)

* Solving state, represents methods accessible from plugin implementations

* Separate solution methods to its own trait

* Update version number

* Allow add_var to be called from Solving state

* Release vars added in solving

* WIP

* Free sol after adding

* Fix fn calling

* Update changelog
  • Loading branch information
mmghannam authored Jul 30, 2023
1 parent 03e1993 commit a19d1d8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## unreleased
### Added
### Fixed
### Changed
- Free sol after adding in `ScipPtr::add_sol()`.
- Allow adding a var in `Solving` mode.
### Removed

## 0.2.5
### Added
- Primal heuristic plugin.
- Solving Model state, to represent methods accessible when during solving.
- Moved solution query methods to its own trait.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authors = ["Mohammad Ghannam <[email protected]>"]
description = "Rust interface for SCIP"
license = "Apache-2.0"
repository = "https://github.com/scipopt/russcip"
version = "0.2.4"
version = "0.2.5"
edition = "2021"
exclude = ["data/test/*"]

Expand Down
37 changes: 37 additions & 0 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,43 @@ impl Model<ProblemCreated> {
}

impl Model<Solving> {
/// Adds a new variable to the model with the given lower bound, upper bound, objective coefficient, name, and type.
///
/// # Arguments
///
/// * `lb` - The lower bound of the variable.
/// * `ub` - The upper bound of the variable.
/// * `obj` - The objective coefficient of the variable.
/// * `name` - The name of the variable.
/// * `var_type` - The type of the variable.
///
/// # Returns
///
/// A reference-counted pointer to the new variable.
///
/// # Panics
///
/// This method panics if the variable cannot be created in the current state.
pub fn add_var(
&mut self,
lb: f64,
ub: f64,
obj: f64,
name: &str,
var_type: VarType,
) -> Rc<Variable> {
let var = self
.scip
.create_var_solving(lb, ub, obj, name, var_type)
.expect("Failed to create variable in state ProblemCreated");
let var_id = var.index();
let var = Rc::new(var);
self.state.vars.borrow_mut().insert(var_id, var.clone());
var
}

/// Adds a new priced variable to the SCIP data structure.

/// Returns the current node of the model.
///
/// # Panics
Expand Down
40 changes: 38 additions & 2 deletions src/scip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::rc::Rc;
pub(crate) struct ScipPtr {
pub(crate) raw: *mut ffi::SCIP,
consumed: bool,
vars_added_in_solving: Vec<*mut ffi::SCIP_VAR>
}

impl ScipPtr {
Expand All @@ -26,13 +27,15 @@ impl ScipPtr {
ScipPtr {
raw: scip_ptr,
consumed: false,
vars_added_in_solving: Vec::new(),
}
}

pub(crate) fn clone(&self) -> Self {
ScipPtr {
raw: self.raw,
consumed: true,
vars_added_in_solving: Vec::new(),
}
}

Expand Down Expand Up @@ -209,6 +212,34 @@ impl ScipPtr {
Ok(Variable { raw: var_ptr })
}

pub(crate) fn create_var_solving(
&mut self,
lb: f64,
ub: f64,
obj: f64,
name: &str,
var_type: VarType,
) -> Result<Variable, Retcode> {
let name = CString::new(name).unwrap();
let mut var_ptr = MaybeUninit::uninit();
scip_call! { ffi::SCIPcreateVarBasic(
self.raw,
var_ptr.as_mut_ptr(),
name.as_ptr(),
lb,
ub,
obj,
var_type.into(),
) };
let mut var_ptr = unsafe { var_ptr.assume_init() };
scip_call! { ffi::SCIPaddVar(self.raw, var_ptr) }
let mut transformed_var = MaybeUninit::uninit();
scip_call! { ffi::SCIPgetTransformedVar(self.raw, var_ptr, transformed_var.as_mut_ptr()) };
let trans_var_ptr = unsafe { transformed_var.assume_init() };
scip_call! { ffi::SCIPreleaseVar(self.raw, &mut var_ptr) };
Ok(Variable { raw: trans_var_ptr })
}

pub(crate) fn create_priced_var(
&mut self,
lb: f64,
Expand Down Expand Up @@ -879,9 +910,9 @@ impl ScipPtr {
Ok(Node { raw: node_ptr })
}

pub(crate) fn add_sol(&self, sol: Solution) -> Result<bool, Retcode> {
pub(crate) fn add_sol(&self, mut sol: Solution) -> Result<bool, Retcode> {
let mut stored = MaybeUninit::uninit();
scip_call!(ffi::SCIPaddSol(self.raw, sol.raw, stored.as_mut_ptr()));
scip_call!(ffi::SCIPaddSolFree(self.raw, &mut sol.raw, stored.as_mut_ptr()));
let stored = unsafe { stored.assume_init() };
Ok(stored != 0)
}
Expand Down Expand Up @@ -916,6 +947,11 @@ impl Drop for ScipPtr {
scip_call_panic!(ffi::SCIPreleaseVar(self.raw, &mut var));
}

// release vars added in solving
for var_ptr in self.vars_added_in_solving.iter_mut() {
scip_call_panic!(ffi::SCIPreleaseVar(self.raw, var_ptr));
}

// release constraints
let n_conss = unsafe { ffi::SCIPgetNOrigConss(self.raw) };
let conss = unsafe { ffi::SCIPgetOrigConss(self.raw) };
Expand Down

0 comments on commit a19d1d8

Please sign in to comment.