Module grb::callback

source ·
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§

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§