Skip to main content

ferrox/scheduling/
mod.rs

1//! Multi-agent task scheduling suggestors.
2//!
3//! Two competing implementations of the same scheduling contract:
4//!
5//! | Suggestor | Algorithm | Latency | Confidence |
6//! |---|---|---|---|
7//! | [`GreedySchedulerSuggestor`] | EDF + earliest-available | sub-ms | ≤ 0.65 |
8//! | [`CpSatSchedulerSuggestor`] | CP-SAT optional-interval | seconds | ≤ 1.0 |
9//!
10//! # Formation pattern
11//!
12//! Register both in the same [`converge_core::Engine`].  Both accept
13//! `"scheduling-request:*"` seeds and emit solver-prefixed plans to
14//! `ContextKey::Strategies`:
15//!
16//! - Greedy → `"scheduling-plan-greedy:<id>"`
17//! - CP-SAT → `"scheduling-plan-cpsat:<id>"`
18//!
19//! Downstream consumers compare confidence scores and select the plan that
20//! maximises throughput.  In practice: greedy answers in < 1 ms; CP-SAT
21//! improves on it and proves optimality within the time budget.
22//!
23//! # Benchmark result (60 tasks · 12 agents · 5 skills · horizon 360 min)
24//!
25//! ```text
26//! Greedy:  56 / 60 tasks scheduled   (93.3 %)   0.03 ms
27//! CP-SAT:  60 / 60 tasks scheduled  (100.0 %)   260 ms   ← optimal
28//! ```
29//!
30//! CP-SAT scheduled 4 additional tasks that greedy could not fit, and proved
31//! the schedule is globally optimal.
32
33pub mod problem;
34
35pub mod greedy;
36
37#[cfg(feature = "ortools")]
38pub mod cpsat;
39
40pub use problem::{
41    SchedulingAgent, SchedulingPlan, SchedulingRequest, SchedulingTask, TaskAssignment,
42};
43pub use greedy::GreedySchedulerSuggestor;
44
45#[cfg(feature = "ortools")]
46pub use cpsat::CpSatSchedulerSuggestor;