Skip to main content

solverforge_config/
move_selector.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq)]
4#[serde(rename_all = "snake_case")]
5pub struct VariableTargetConfig {
6    pub entity_class: Option<String>,
7    pub variable_name: Option<String>,
8}
9
10// Move selector configuration.
11#[derive(Debug, Clone, Deserialize, Serialize)]
12#[serde(tag = "type", rename_all = "snake_case")]
13pub enum MoveSelectorConfig {
14    // Change move selector (standard variables).
15    ChangeMoveSelector(ChangeMoveConfig),
16
17    // Swap move selector (standard variables).
18    SwapMoveSelector(SwapMoveConfig),
19
20    // List change move selector — relocates single elements within/between routes.
21    ListChangeMoveSelector(ListChangeMoveConfig),
22
23    // Nearby list change move selector — distance-pruned element relocation.
24    NearbyListChangeMoveSelector(NearbyListChangeMoveConfig),
25
26    // List swap move selector — swaps single elements within/between routes.
27    ListSwapMoveSelector(ListSwapMoveConfig),
28
29    // Nearby list swap move selector — distance-pruned element swap.
30    NearbyListSwapMoveSelector(NearbyListSwapMoveConfig),
31
32    // Sublist change move selector (Or-opt) — relocates contiguous segments.
33    SubListChangeMoveSelector(SubListChangeMoveConfig),
34
35    // Sublist swap move selector — swaps contiguous segments between routes.
36    SubListSwapMoveSelector(SubListSwapMoveConfig),
37
38    // List reverse move selector (2-opt) — reverses segments within a route.
39    ListReverseMoveSelector(ListReverseMoveConfig),
40
41    // K-opt move selector — generalised route reconnection.
42    KOptMoveSelector(KOptMoveSelectorConfig),
43
44    // List ruin move selector (LNS) — removes elements for reinsertion.
45    ListRuinMoveSelector(ListRuinMoveSelectorConfig),
46
47    // Union of multiple selectors.
48    UnionMoveSelector(UnionMoveSelectorConfig),
49
50    // Cartesian product of selectors.
51    CartesianProductMoveSelector(CartesianProductConfig),
52}
53
54// Change move configuration.
55#[derive(Debug, Clone, Default, Deserialize, Serialize)]
56#[serde(rename_all = "snake_case")]
57pub struct ChangeMoveConfig {
58    #[serde(flatten)]
59    pub target: VariableTargetConfig,
60}
61
62// Swap move configuration.
63#[derive(Debug, Clone, Default, Deserialize, Serialize)]
64#[serde(rename_all = "snake_case")]
65pub struct SwapMoveConfig {
66    #[serde(flatten)]
67    pub target: VariableTargetConfig,
68}
69
70// Configuration for `ListChangeMoveSelector`.
71#[derive(Debug, Clone, Default, Deserialize, Serialize)]
72#[serde(rename_all = "snake_case")]
73pub struct ListChangeMoveConfig {
74    #[serde(flatten)]
75    pub target: VariableTargetConfig,
76}
77
78// Configuration for `NearbyListChangeMoveSelector`.
79#[derive(Debug, Clone, Deserialize, Serialize)]
80#[serde(rename_all = "snake_case")]
81pub struct NearbyListChangeMoveConfig {
82    // Maximum nearby destination positions to consider per source element.
83    pub max_nearby: usize,
84    #[serde(flatten)]
85    pub target: VariableTargetConfig,
86}
87
88impl Default for NearbyListChangeMoveConfig {
89    fn default() -> Self {
90        Self {
91            max_nearby: 10,
92            target: VariableTargetConfig::default(),
93        }
94    }
95}
96
97// Configuration for `ListSwapMoveSelector`.
98#[derive(Debug, Clone, Default, Deserialize, Serialize)]
99#[serde(rename_all = "snake_case")]
100pub struct ListSwapMoveConfig {
101    #[serde(flatten)]
102    pub target: VariableTargetConfig,
103}
104
105// Configuration for `NearbyListSwapMoveSelector`.
106#[derive(Debug, Clone, Deserialize, Serialize)]
107#[serde(rename_all = "snake_case")]
108pub struct NearbyListSwapMoveConfig {
109    // Maximum nearby swap partners to consider per source element.
110    pub max_nearby: usize,
111    #[serde(flatten)]
112    pub target: VariableTargetConfig,
113}
114
115impl Default for NearbyListSwapMoveConfig {
116    fn default() -> Self {
117        Self {
118            max_nearby: 10,
119            target: VariableTargetConfig::default(),
120        }
121    }
122}
123
124// Configuration for `SubListChangeMoveSelector` (Or-opt).
125#[derive(Debug, Clone, Deserialize, Serialize)]
126#[serde(rename_all = "snake_case")]
127pub struct SubListChangeMoveConfig {
128    // Minimum segment size (inclusive). Default: 1.
129    pub min_sublist_size: usize,
130    // Maximum segment size (inclusive). Default: 3.
131    pub max_sublist_size: usize,
132    #[serde(flatten)]
133    pub target: VariableTargetConfig,
134}
135
136impl Default for SubListChangeMoveConfig {
137    fn default() -> Self {
138        Self {
139            min_sublist_size: 1,
140            max_sublist_size: 3,
141            target: VariableTargetConfig::default(),
142        }
143    }
144}
145
146// Configuration for `SubListSwapMoveSelector`.
147#[derive(Debug, Clone, Deserialize, Serialize)]
148#[serde(rename_all = "snake_case")]
149pub struct SubListSwapMoveConfig {
150    // Minimum segment size (inclusive). Default: 1.
151    pub min_sublist_size: usize,
152    // Maximum segment size (inclusive). Default: 3.
153    pub max_sublist_size: usize,
154    #[serde(flatten)]
155    pub target: VariableTargetConfig,
156}
157
158impl Default for SubListSwapMoveConfig {
159    fn default() -> Self {
160        Self {
161            min_sublist_size: 1,
162            max_sublist_size: 3,
163            target: VariableTargetConfig::default(),
164        }
165    }
166}
167
168// Configuration for `ListReverseMoveSelector` (2-opt).
169#[derive(Debug, Clone, Default, Deserialize, Serialize)]
170#[serde(rename_all = "snake_case")]
171pub struct ListReverseMoveConfig {
172    #[serde(flatten)]
173    pub target: VariableTargetConfig,
174}
175
176// Configuration for `KOptMoveSelector`.
177#[derive(Debug, Clone, Deserialize, Serialize)]
178#[serde(rename_all = "snake_case")]
179pub struct KOptMoveSelectorConfig {
180    // K value (number of cuts). Default: 3.
181    pub k: usize,
182    // Minimum segment length between cuts. Default: 1.
183    pub min_segment_len: usize,
184    // Maximum nearby positions to consider per cut. Default: 0 (full enumeration).
185    // When > 0, uses distance-pruned NearbyKOptMoveSelector instead of full KOptMoveSelector.
186    pub max_nearby: usize,
187    #[serde(flatten)]
188    pub target: VariableTargetConfig,
189}
190
191impl Default for KOptMoveSelectorConfig {
192    fn default() -> Self {
193        Self {
194            k: 3,
195            min_segment_len: 1,
196            max_nearby: 0,
197            target: VariableTargetConfig::default(),
198        }
199    }
200}
201
202// Configuration for `ListRuinMoveSelector` (LNS).
203#[derive(Debug, Clone, Deserialize, Serialize)]
204#[serde(rename_all = "snake_case")]
205pub struct ListRuinMoveSelectorConfig {
206    // Minimum number of elements to ruin per move. Default: 2.
207    pub min_ruin_count: usize,
208    // Maximum number of elements to ruin per move. Default: 5.
209    pub max_ruin_count: usize,
210    // Number of ruin moves to generate per step. Default: 10.
211    pub moves_per_step: Option<usize>,
212    #[serde(flatten)]
213    pub target: VariableTargetConfig,
214}
215
216impl Default for ListRuinMoveSelectorConfig {
217    fn default() -> Self {
218        Self {
219            min_ruin_count: 2,
220            max_ruin_count: 5,
221            moves_per_step: None,
222            target: VariableTargetConfig::default(),
223        }
224    }
225}
226
227// Union move selector configuration.
228#[derive(Debug, Clone, Default, Deserialize, Serialize)]
229#[serde(rename_all = "snake_case")]
230pub struct UnionMoveSelectorConfig {
231    // Child selectors.
232    pub selectors: Vec<MoveSelectorConfig>,
233}
234
235// Cartesian product move selector configuration.
236#[derive(Debug, Clone, Default, Deserialize, Serialize)]
237#[serde(rename_all = "snake_case")]
238pub struct CartesianProductConfig {
239    // Child selectors.
240    pub selectors: Vec<MoveSelectorConfig>,
241}