ubnt-intrepid's blog

書いてあることがブログの内容です

Gurobi の Rust API を作ってた

少し前から手をつけていたのですが,Rust から Gurobi を呼び出したいなぁと(少し)思っていたので作ってみました.

https://crates.io/crates/gurobi

基本的な API の使用は C++ 版のものを参考にしましたが,言語的な制約から多少異なったものになっています.

使い方

extern crate gurobi;

fn main() {
  let env = gurobi::Env::new("logfile.log").unwrap();

  // モデルのインスタンス生成
  let mut model = gurobi::Model::new("modelname", &env).unwrap();

  // 決定変数の追加
  let x = model.add_var("x", gurobi::Continuous, 0.0, -gurobi::INFINITY, gurobi::INFINITY, &[], &[]).unwrap();
  let y = model.add_var("y", gurobi::Binary, 0.0, -gurobi::INFINITY, gurobi::INFINITY, &[], &[]).unwrap();
  // ...

  // 目的関数の設定
  model.set_objective(&x + &y, gurobi::Minimize).unwrap();

  // 線形制約
  model.add_constr("c0", &x + 2.0 * &y, gurobi::Greater, 0.0).unwrap();
  
  // 二次制約
  model.add_qconstr("qc0", &x + 2.0 * &y * &y, gurobi::Greater, 0.0).unwrap();

  ...

  // 最適化の実行
  model.optimize().unwrap();

  // 結果の出力
  let status = model.status().unwrap();
  println!("Status: {:?}", status);

  let x = x.get(&model, gurobi:attr::X).unwrap();
  let y = y.get(&model, gurobi:attr::X).unwrap();
  println!("x = {}, y = {}", x, y);

  model.write("modelname.lp").unwrap();
  model.write("modelname.sol").unwrap();
}

APIの名称はできるだけ公式のものと近づけるようにしたので,ドキュメントと公式のAPIの使用方法を照らし合わせれば何となく使えるのではないかと思います.

現状では一通りCのAPIをラッピングしただけですが,できれば使用していただけると(そして不具合の報告やプルリクエストを送っていただけると)幸いです.