Expand description
Interface to Gurobi’s callback API
Gurobi allows for user callbacks to be called at different points during a solve. At each of these points, the user may query or modify the model in different ways.
This module provides a context handle type for each place at which a callback may be called.
In the Gurobi manual,
these are represented by the where
values. The handle types are bundled in the
Where
enum, so to obtain an instance of a particular handle type
in a callback, use pattern matching. For example:
fn callback(w: Where) -> CbResult {
match w {
Where::PreSolve(ctx) => {/* type of ctx = PreSolveCtx */ },
Where::MIPSol(ctx) => {/* type of ctx = MIPCtx */ },
_ => {},
}
Ok(())
}
For details on each handle type and its available methods, see the *Ctx
structs in this module.
Callbacks can be defined using the Callback
trait on an object, or using a closure.
§Examples
§Using closures
Because of Rust’s lifetime requirements on closures, if you are using large lookup structures within your
callbacks, you should wrap them in a std::rc::Rc
<
std::cell::RefCell
<_>>
. This can be a little
tedious, so if you need to use a stateful callback, so implementing the Callback
trait is preferred.
use grb::prelude::*;
use std::{rc::Rc, cell::RefCell};
#[derive(Default)]
struct MyCallbackStats {
ncalls : usize,
big_data: [u8; 32],
}
let mut m = Model::new("model")?;
let x = add_ctsvar!(m, obj: 2)?;
let y = add_intvar!(m, bounds: 0..100)?;
m.add_constr("c0", c!(x <= y - 0.5 ))?;
// Need to put `stats` behind a Rc<RefCell<_>> because of closure lifetimes.
let stats = Rc::new(RefCell::new(MyCallbackStats::default()));
let mut callback = {
// Note that `MyCallbackStats` doesn't implement Clone: `Rc<_>` makes a cheap pointer copy
let stats = stats.clone();
// `move` moves the `stats` clone we just made into the closure
move |w : Where| {
// This should never panic - `callback` runs single-threaded
let stats: &mut MyCallbackStats = &mut *stats.borrow_mut();
if let Where::Polling(_) = w {
println!("in polling: callback has been called {} times", stats.ncalls);
}
stats.ncalls += 1;
Ok(())
}
};
m.optimize_with_callback(&mut callback)?;
§Using the Callback
trait
use grb::prelude::*;
use grb::callback::CbResult;
#[derive(Default)]
struct MyCallbackStats {
ncalls : usize,
big_data: [u8; 32],
}
impl Callback for MyCallbackStats {
fn callback(&mut self, w: Where) -> CbResult {
if let Where::Polling(_) = w {
println!("in polling: callback has been called {} times", self.ncalls);
}
self.ncalls += 1;
Ok(())
}
}
let mut m = Model::new("model")?;
let x = add_ctsvar!(m, obj: 2)?;
let y = add_intvar!(m, bounds: 0..100)?;
m.add_constr("c0", c!(x <= y - 0.5 ))?;
let mut stats = MyCallbackStats::default();
m.optimize_with_callback(&mut stats)?;
Structs§
- Callback context object during
BARRIER
. - Callback context object during
IIS
. - Callback context object during
MIP
. - Callback context object during
MIPNODE
. - Callback context object during
MIPSOL
. - Callback context object during
MESSAGE
. - Callback context object during
POLLING
. - Callback context object during
PRESOLVE
. - Callback context object during
SIMPLEX
.
Enums§
- Possible values for
ctx.phase()
- TODO: (medium) add MultiObj ctx The argument given to callbacks.
Traits§
- A trait that allows structs to be used as a callback object
Type Aliases§
- The return type for callbacks, an alias of
anyhow::Result
.