unifierv0.3.2

CASOON Open Source

Model constraint problems in Rust. Solve them anytime.

unifier models constraint satisfaction and optimization problems – variables, domains, constraints, weighted objectives – and solves them with interchangeable strategies, from exhaustive search that proves optimality to local search and a parallel portfolio.

cargo add unifier
MITearlycrates.io 0.3.2Rust 1.87+
cargo run --example job_shop
Job shop: 3 jobs, 3 machines, horizon 21
Status: Optimal
Score: Feasible(strong=0, medium=0, weak=-11)
Makespan: 11

       01234567890
  M0   00011......
  M1   2222001111.
  M2   .....122200

Digits are job numbers; each row is one machine.
interchangeable solver strategies
5
built-in constraints in 0.3.2, three of them global
16
outcome states: Optimal, Feasible, Infeasible, Aborted
4
runtime dependency (pathwise)
1

What it does

  1. Global constraints that propagate

    AllDifferent reaches generalized arc consistency with Régin’s matching algorithm; Cumulative and NoOverlap detect overload, and NoOverlap tightens bounds by edge-finding.

  2. Honest results

    Optimal only when Branch & Bound has proven it, Infeasible only when the search space is exhausted, Aborted with a reason otherwise – plus a score bound to show how far from proven a result is.

  3. Anytime and cancellable

    Time limits, node budgets and a cancellation token stop any solver with the best solution so far. The parallel portfolio shares that incumbent between its workers.

  4. Built for scheduling

    Activities, resources and groups compile into Cumulative and NoOverlap constraints, with calendars, optional activities, alternative resources and tardiness objectives.

Generated at build time

All examples →
cargo run --example map_coloring
Map of Australia: 7 regions, 9 borders

3 colours: Feasible
  WA   blue
  NT   green
  SA   red
  Q    blue
  NSW  green
  V    blue
  T    red

2 colours: Infeasible
  No colouring exists: WA, NT and SA border each other.

Every result on this site is printed by an example program in the repository, captured with scripts/regenerate-showcase.sh. The showcase puts each program next to its output.

examples/output/map_coloring.txt

Quickstart

From a model to a proven optimum. The full walkthrough lives in the documentation.

  1. Add the crate with cargo add unifier.
  2. Declare variables, constraints and objectives with ModelBuilder.
  3. Validate with build(), then pass the graph to a solver.
main.rsRust
use unifier::dsl::ModelBuilder;
use unifier::solver::{BranchAndBoundSolver, SolverOptions};

let mut model = ModelBuilder::new();

// Three meetings, each in one of the time slots 1 to 4.
let a = model.new_var("a", 1..=4);
let b = model.new_var("b", 1..=4);
let c = model.new_var("c", 1..=4);

// Hard constraints: no shared slot, and a ends before b starts.
model.add_all_different([a, b, c]);
model.add_less_than_or_equal(a, b, -1); // a <= b - 1

// Soft objective: schedule everything as early as possible.
model.add_minimize([a, b, c], 1);

let graph = model.build().expect("valid model");
let outcome = BranchAndBoundSolver::new().solve(&graph, &SolverOptions::default());
println!("{:?}", outcome.status); // Optimal