Domain Modeling
Define planning solutions, entities, and problem facts using Rust derive macros.
SolverForge is a native Rust constraint solver for planning and scheduling problems. It uses derive macros for domain modeling, constraint streams for declarative rule definition, and metaheuristic algorithms for optimization.
cargo add solverforge
use solverforge::prelude::*;
// 1. Define your domain
#[problem_fact]
#[derive(Clone, Debug)]
pub struct Employee {
#[planning_id]
pub id: i64,
pub name: String,
}
#[planning_entity]
#[derive(Clone, Debug)]
pub struct Shift {
#[planning_id]
pub id: i64,
pub required_skill: String,
#[planning_variable(allows_unassigned = true)]
pub employee: Option<Employee>,
}
#[planning_solution]
#[derive(Clone, Debug)]
pub struct Schedule {
#[problem_fact_collection]
#[value_range_provider]
pub employees: Vec<Employee>,
#[planning_entity_collection]
pub shifts: Vec<Shift>,
#[planning_score]
pub score: Option<HardSoftScore>,
}
// 2. Define constraints
fn define_constraints() -> impl ConstraintSet<Schedule, HardSoftScore> {
let factory = ConstraintFactory::<Schedule, HardSoftScore>::new();
let unassigned = factory
.for_each(|s: &Schedule| s.shifts.as_slice())
.filter(|s: &Shift| s.employee.is_none())
.penalize(HardSoftScore::ONE_HARD)
.named("Unassigned shift");
(unassigned,)
}
// 3. Solve
fn main() {
let problem = Schedule {
employees: vec![/* ... */],
shifts: vec![/* ... */],
score: None,
};
let mut director = ScoreDirector::new(problem, define_constraints());
let score = director.calculate_score();
println!("Score: {:?}", score);
}
Full API documentation is available on docs.rs/solverforge.
Define planning solutions, entities, and problem facts using Rust derive macros.
Define business rules using constraint streams, joiners, collectors, and score types.
Configure and run the solver — phases, moves, termination, and SolverManager.
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.