solverforge_solver/realtime/mod.rs
1//! Real-time planning support.
2//!
3//! Allows submitting problem changes while the solver is running. Changes are
4//! processed at step boundaries to maintain solver consistency.
5//!
6//! # Overview
7//!
8//! Real-time planning enables dynamic updates to the problem during solving:
9//! - Add new entities (e.g., new orders, tasks, employees)
10//! - Remove entities (e.g., cancelled orders)
11//! - Update entity properties (e.g., deadline changes)
12//! - Modify problem facts (e.g., new constraints)
13//!
14//! # Example
15//!
16//! ```
17//! use solverforge_solver::realtime::ProblemChange;
18//! use solverforge_scoring::ScoreDirector;
19//! use solverforge_core::domain::PlanningSolution;
20//! use solverforge_core::score::SimpleScore;
21//!
22//! #[derive(Clone, Debug)]
23//! struct Task { id: usize, priority: Option<i32> }
24//!
25//! #[derive(Clone, Debug)]
26//! struct Schedule {
27//! tasks: Vec<Task>,
28//! score: Option<SimpleScore>,
29//! }
30//!
31//! impl PlanningSolution for Schedule {
32//! type Score = SimpleScore;
33//! fn score(&self) -> Option<Self::Score> { self.score }
34//! fn set_score(&mut self, score: Option<Self::Score>) { self.score = score; }
35//! }
36//!
37//! // Create a problem change that adds a new task
38//! #[derive(Debug)]
39//! struct AddTask { id: usize }
40//!
41//! impl ProblemChange<Schedule> for AddTask {
42//! fn apply(&self, score_director: &mut dyn ScoreDirector<Schedule>) {
43//! let task = Task { id: self.id, priority: None };
44//! score_director.working_solution_mut().tasks.push(task);
45//! score_director.trigger_variable_listeners();
46//! }
47//! }
48//! ```
49
50mod problem_change;
51mod solver_handle;
52
53pub use problem_change::{BoxedProblemChange, ClosureProblemChange, ProblemChange};
54pub use solver_handle::{ProblemChangeReceiver, ProblemChangeResult, SolverHandle};