Skip to main content

solverforge_config/
move_selector.rs

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