Skip to content

Specy/rooc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

332 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ROOC

ROOC logo

Optimization modeling language and solver

Crates.io npm

Language documentation · Web platform · Rust crate · TypeScript package

ROOC is a library and modeling language for linear and mixed-integer optimization. Define a model in Rust or in ROOC source, then solve it with the built-in solvers.

Choose an interface

  • Use the fluent Rust API when your application constructs models in code.
  • Use the fluent TypeScript API for typed browser and JavaScript models backed by the WebAssembly solvers.
  • Use the ROOC language when a formal, data-driven model is easier to read and maintain.
  • Use the web platform to write and run ROOC models in the browser.

Rust quick start

use rooc::builder::any;
use rooc::{Microlp, ModelBuilder, constraint, vars};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut model = ModelBuilder::new();

    vars! { model =>
        make_a: bool;
        make_b: bool;
        make_c: bool;
        material: int(0, 8);
    };

    let solution = model
        .maximize(6.0 * make_a + 5.0 * make_b + 4.0 * make_c - material)
        .with(constraint!(2.0 * make_a + 3.0 * make_b + make_c <= material))
        .with(constraint!(make_a -> make_b))
        .with(constraint!(any(vec![make_a, make_c])))
        .solve_with(Microlp::new())?;

    println!("objective = {}", solution.value());
    println!("make_a = {:?}", solution.var_value(make_a));
    println!("material = {:?}", solution.var_value(material));
    Ok(())
}

The crate README covers variables, expressions, constraints, LP export, and direct linear models.

Choose a solver

Use Auto for ROOC's safe general-purpose MILP default. It uses Microlp for every supported model. Use Microlp::new() when you need MIP options such as a time limit or mip gap. Select Clarabel explicitly for a continuous model.

The Rust crate enables microlp and clarabel by default. Every other solver feature is opt-in. Only the default solvers are implemented entirely in Rust and supported in WebAssembly builds.

Cargo feature Rust-only WASM Optional capabilities Scope Prerequisite
microlp Yes Yes MIP gap, time limit LP + MILP None
clarabel Yes Yes Shadow prices Continuous LP None
coin_cbc No No Initial solution, MIP gap, time limit LP + MILP Native CBC toolchain
highs No No Initial solution, MIP gap, time limit, shadow prices LP + MILP Native HiGHS toolchain
lpsolve No No Time limit LP + MILP Native C build
scip No No Initial solution, MIP gap, time limit LP + MILP SCIP installation
scip_bundled No No Initial solution, MIP gap, time limit LP + MILP Bundled native SCIP build
lp-solvers No No None through AllSolvers LP + MILP Solver executable on PATH
cplex-rs No No Time limit LP + MILP IBM CPLEX installation

Configured solvers expose only their implemented capabilities:

use rooc::Highs;
use std::time::Duration;

let solver = Highs::new()
    .with_time_limit(Duration::from_secs(30))
    .with_mip_gap(0.01)
    .with_initial_solution([("x", 1.0)]);

Clarabel and HiGHS provide named shadow prices through the existing DualValues solution capability. Reduced costs are not exposed.

Enable an opt-in solver explicitly in Cargo.toml:

[dependencies]
rooc = { version = "0.2.4", default-features = false, features = ["highs"] }

Use features = ["microlp", "clarabel", "highs"] when an application needs both default solvers and an additional native solver. Native-only features are rejected for wasm32; browser and WebAssembly builds should keep the default microlp and clarabel feature set. The lpsolve and cplex-rs features cannot be enabled together.

ROOC language

ROOC source is useful for models built from data, sets, graphs, and iteration:

min sum(v in nodes(G)) { x_v }
s.t.
    x_u or x_v for (u, v) in edges(G)
where
    let G = Graph {
        A -> [B, C],
        B -> [D],
        C -> [D],
        D -> [E],
        E
    }
define
    x_v as Boolean for v in nodes(G)

The language supports arithmetic, boolean logic, indexed constraints, collections, graphs, and the abs { }, min { }, and max { } blocks. See the language documentation for the complete syntax and examples.

TypeScript and web

@specy/rooc provides a type-safe fluent builder over the existing WebAssembly compiler, linearizer, and solvers:

import { ModelBuilder, sum } from "@specy/rooc";

const model = new ModelBuilder();
const { selected, capacity } = model.vars({
    selected: model.bool().array(4),
    capacity: model.int(0, 4),
});

const solution = model
    .maximize(sum(selected))
    .with(sum(selected).le(capacity))
    .solve();

console.log(solution.valuesOf({ selected, capacity }));

The source compiler and pipe-by-pipe APIs remain available for formal ROOC programs and intermediate pipeline inspection. See the TypeScript README for variables, expressions, solver selection, typed readback, generated source, and compatibility imports.

License

The Rust library is released under MPL-2.0. The web client is released under AGPL-3.0.

About

A language and integrated environment for modelling and solving mixed integer linear optimization problems

Topics

Resources

Stars

Watchers

Forks

Used by

Contributors

Languages