solverforge_solver/heuristic/move/mod.rs
1//! Move system for modifying planning solutions.
2//!
3//! Moves are the fundamental operations that modify planning variables during
4//! solving. The solver explores the solution space by applying different moves
5//! and evaluating their impact on the score.
6//!
7//! # Architecture
8//!
9//! All moves are fully typed with inline value storage for maximum performance:
10//! - `ChangeMove<S, V>` - assigns a value to a variable
11//! - `SwapMove<S, V>` - swaps values between two entities
12//! - `CompositeMove<'a, S, M1, M2>` - applies two moves by reference
13//! - `PillarChangeMove<S, V>` - changes multiple entities with same value
14//! - `PillarSwapMove<S, V>` - swaps between two pillars
15//! - `ListChangeMove<S, V>` - relocates an element in a list variable
16//! - `ListSwapMove<S, V>` - swaps two elements in list variables
17//! - `SubListChangeMove<S, V>` - relocates a contiguous sublist
18//! - `SubListSwapMove<S, V>` - swaps two contiguous sublists
19//! - `ListReverseMove<S, V>` - reverses a segment (2-opt for TSP)
20//! - `RuinMove<S, V>` - unassigns multiple entities (for Large Neighborhood Search)
21//! - `ListRuinMove<S, V>` - removes elements from a list (for LNS on list variables)
22//!
23//! Undo is handled by `RecordingScoreDirector`, not by moves returning undo data.
24//!
25//! # Arena Allocation
26//!
27//! Use `MoveArena<M>` for O(1) per-step cleanup. Call `reset()` at each step
28//! instead of allocating a new Vec.
29//!
30//! # Zero-Erasure Design
31//!
32//! Moves are NEVER cloned. Ownership transfers via arena indices:
33//!
34//! ```
35//! use solverforge_solver::heuristic::MoveArena;
36//!
37//! // Simple move type for demonstration
38//! struct SimpleMove { value: i32 }
39//!
40//! let mut arena: MoveArena<SimpleMove> = MoveArena::new();
41//!
42//! // Store moves - track indices manually
43//! arena.push(SimpleMove { value: 1 }); // index 0
44//! arena.push(SimpleMove { value: 2 }); // index 1
45//!
46//! // Take ownership from arena when picking
47//! let selected = arena.take(0);
48//! assert_eq!(selected.value, 1);
49//!
50//! // Reset clears arena for next step
51//! arena.reset();
52//! ```
53
54mod arena;
55mod change;
56mod composite;
57mod either;
58mod k_opt;
59pub mod k_opt_reconnection;
60mod list_change;
61mod list_either;
62mod list_reverse;
63mod list_ruin;
64mod list_swap;
65mod pillar_change;
66mod pillar_swap;
67mod ruin;
68mod sublist_change;
69mod sublist_swap;
70mod swap;
71mod traits;
72
73#[cfg(test)]
74mod tests;
75
76pub use arena::MoveArena;
77pub use change::ChangeMove;
78pub use composite::CompositeMove;
79pub use either::EitherMove;
80pub use k_opt::{CutPoint, KOptMove};
81pub use list_change::ListChangeMove;
82pub use list_either::ListMoveImpl;
83pub use list_reverse::ListReverseMove;
84pub use list_ruin::ListRuinMove;
85pub use list_swap::ListSwapMove;
86pub use pillar_change::PillarChangeMove;
87pub use pillar_swap::PillarSwapMove;
88pub use ruin::RuinMove;
89pub use sublist_change::SubListChangeMove;
90pub use sublist_swap::SubListSwapMove;
91pub use swap::SwapMove;
92pub use traits::Move;