Skip to main content

solverforge_solver/heuristic/move/
mod.rs

1/* Move system for modifying planning solutions.
2
3Moves are the fundamental operations that modify planning variables during
4solving. The solver explores the solution space by applying different moves
5and evaluating their impact on the score.
6
7# Architecture
8
9All moves are fully monomorphized 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- `SequentialCompositeMove<S, M>` - applies two owned moves in sequence
14- `PillarChangeMove<S, V>` - changes multiple entities with same value
15- `PillarSwapMove<S, V>` - swaps between two pillars
16- `ListChangeMove<S, V>` - relocates an element in a list variable
17- `ListSwapMove<S, V>` - swaps two elements in list variables
18- `SublistChangeMove<S, V>` - relocates a contiguous sublist
19- `SublistSwapMove<S, V>` - swaps two contiguous sublists
20- `ListReverseMove<S, V>` - reverses a segment (2-opt for TSP)
21- `RuinMove<S, V>` - unassigns multiple entities (for Large Neighborhood Search)
22- `ListRuinMove<S, V>` - removes elements from a list (for LNS on list variables)
23
24Each move returns typed undo data from `do_move` and restores itself through
25`undo_move`; speculative evaluation does not use boxed callbacks.
26
27# Arena Allocation
28
29Use `MoveArena<M>` for O(1) per-step cleanup. Call `reset()` at each step
30instead of allocating a new Vec.
31
32# Zero-Erasure Design
33
34Moves are NEVER cloned. Ownership transfers via arena indices:
35
36```
37use solverforge_solver::heuristic::MoveArena;
38
39// Simple move type for demonstration
40struct SimpleMove { value: i32 }
41
42let mut arena: MoveArena<SimpleMove> = MoveArena::new();
43
44// Store moves - track indices manually
45arena.push(SimpleMove { value: 1 }); // index 0
46arena.push(SimpleMove { value: 2 }); // index 1
47
48// Take ownership from arena when picking
49let selected = arena.take(0);
50assert_eq!(selected.value, 1);
51
52// Reset clears arena for next step
53arena.reset();
54```
55*/
56
57/// Inlined undo journal for short list edit sets (K-opt route restorations
58/// and similar arbitrary-length undo payloads). Capacity is inline up to 24
59/// elements; longer routes spill to the heap and rely on the move's
60/// per-trial journal pool so retained capacity is reused across trials.
61pub type ListUndoJournal<T> = smallvec::SmallVec<[T; 24]>;
62
63mod arena;
64mod change;
65mod composite;
66mod compound_scalar;
67mod conflict_repair;
68mod dynamic_list_change;
69mod dynamic_scalar_change;
70mod dynamic_scalar_swap;
71mod k_opt;
72pub mod k_opt_reconnection;
73mod list_change;
74pub(crate) mod list_kernel;
75mod list_multi_swap;
76mod list_permute;
77mod list_reverse;
78mod list_ruin;
79mod list_swap;
80mod list_union;
81pub(crate) mod metadata;
82mod pillar_change;
83mod pillar_swap;
84mod ruin;
85mod ruin_recreate;
86mod runtime_compound;
87mod scalar_union;
88mod segment_layout;
89mod sublist_change;
90mod sublist_swap;
91mod swap;
92mod traits;
93
94#[cfg(test)]
95mod tests;
96
97pub use arena::MoveArena;
98pub use change::ChangeMove;
99pub use composite::CompositeMove;
100pub use composite::SequentialCompositeMove;
101pub(crate) use composite::SequentialCompositeMoveRef;
102pub use compound_scalar::{CompoundScalarEdit, CompoundScalarMove, COMPOUND_SCALAR_VARIABLE};
103pub use conflict_repair::{ConflictRepairMove, ConflictRepairScalarEdit};
104pub use dynamic_list_change::DynamicListChangeMove;
105pub use dynamic_scalar_change::DynamicScalarChangeMove;
106pub use dynamic_scalar_swap::DynamicScalarSwapMove;
107pub use k_opt::{CutPoint, KOptMove};
108pub use list_change::ListChangeMove;
109pub use list_multi_swap::ListMultiSwapMove;
110pub use list_permute::{ListPermuteMove, MAX_LIST_PERMUTE_WINDOW_SIZE};
111pub use list_reverse::ListReverseMove;
112pub use list_ruin::ListRuinMove;
113pub use list_swap::ListSwapMove;
114pub use list_union::ListMoveUnion;
115pub use metadata::MoveTabuSignature;
116pub use pillar_change::PillarChangeMove;
117pub use pillar_swap::PillarSwapMove;
118pub use ruin::RuinMove;
119pub use ruin_recreate::{RuinRecreateMove, ScalarRecreateValueSource};
120#[cfg(test)]
121pub(crate) use runtime_compound::{
122    reset_runtime_compound_move_clone_count, runtime_compound_move_clone_count,
123};
124pub use runtime_compound::{RuntimeCompoundMove, RuntimeCompoundMoveKind};
125pub use scalar_union::ScalarMoveUnion;
126pub(crate) use segment_layout::{SegmentRelocationCoords, SegmentSwapCoords};
127pub use sublist_change::SublistChangeMove;
128pub use sublist_swap::SublistSwapMove;
129pub use swap::SwapMove;
130pub use traits::{Move, MoveAffectedEntity};