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#[derive(Debug, Clone, Deserialize, Serialize)]
12#[serde(tag = "type", rename_all = "snake_case")]
13pub enum MoveSelectorConfig {
14 ChangeMoveSelector(ChangeMoveConfig),
16
17 SwapMoveSelector(SwapMoveConfig),
19
20 NearbyChangeMoveSelector(NearbyChangeMoveConfig),
22
23 NearbySwapMoveSelector(NearbySwapMoveConfig),
25
26 PillarChangeMoveSelector(PillarChangeMoveConfig),
28
29 PillarSwapMoveSelector(PillarSwapMoveConfig),
31
32 RuinRecreateMoveSelector(RuinRecreateMoveSelectorConfig),
34
35 GroupedScalarMoveSelector(GroupedScalarMoveSelectorConfig),
37
38 ListChangeMoveSelector(ListChangeMoveConfig),
40
41 NearbyListChangeMoveSelector(NearbyListChangeMoveConfig),
43
44 ListSwapMoveSelector(ListSwapMoveConfig),
46
47 ListPermuteMoveSelector(ListPermuteMoveConfig),
49
50 ListPrecedenceMoveSelector(ListPrecedenceMoveConfig),
52
53 NearbyListSwapMoveSelector(NearbyListSwapMoveConfig),
55
56 SublistChangeMoveSelector(SublistChangeMoveConfig),
58
59 SublistSwapMoveSelector(SublistSwapMoveConfig),
61
62 ListReverseMoveSelector(ListReverseMoveConfig),
64
65 KOptMoveSelector(KOptMoveSelectorConfig),
67
68 ListRuinMoveSelector(ListRuinMoveSelectorConfig),
70
71 LimitedNeighborhood(LimitedNeighborhoodConfig),
74
75 UnionMoveSelector(UnionMoveSelectorConfig),
77
78 CartesianProductMoveSelector(CartesianProductConfig),
82
83 ConflictRepairMoveSelector(ConflictRepairMoveSelectorConfig),
85
86 CompoundConflictRepairMoveSelector(CompoundConflictRepairMoveSelectorConfig),
88}
89
90#[derive(Debug, Clone, Default, Deserialize, Serialize)]
92#[serde(rename_all = "snake_case")]
93pub struct ChangeMoveConfig {
94 pub value_candidate_limit: Option<usize>,
95 #[serde(flatten)]
96 pub target: VariableTargetConfig,
97}
98
99#[derive(Debug, Clone, Default, Deserialize, Serialize)]
101#[serde(rename_all = "snake_case")]
102pub struct SwapMoveConfig {
103 #[serde(flatten)]
104 pub target: VariableTargetConfig,
105}
106
107#[derive(Debug, Clone, Deserialize, Serialize)]
109#[serde(rename_all = "snake_case")]
110pub struct NearbyChangeMoveConfig {
111 pub max_nearby: usize,
112 pub value_candidate_limit: Option<usize>,
113 #[serde(flatten)]
114 pub target: VariableTargetConfig,
115}
116
117impl Default for NearbyChangeMoveConfig {
118 fn default() -> Self {
119 let (max_nearby, target) = default_nearby_target_config();
120 Self {
121 max_nearby,
122 value_candidate_limit: None,
123 target,
124 }
125 }
126}
127
128#[derive(Debug, Clone, Deserialize, Serialize)]
130#[serde(rename_all = "snake_case")]
131pub struct NearbySwapMoveConfig {
132 pub max_nearby: usize,
133 #[serde(flatten)]
134 pub target: VariableTargetConfig,
135}
136
137impl Default for NearbySwapMoveConfig {
138 fn default() -> Self {
139 let (max_nearby, target) = default_nearby_target_config();
140 Self { max_nearby, target }
141 }
142}
143
144#[derive(Debug, Clone, Default, Deserialize, Serialize)]
146#[serde(rename_all = "snake_case")]
147pub struct PillarChangeMoveConfig {
148 pub minimum_sub_pillar_size: usize,
149 pub maximum_sub_pillar_size: usize,
150 pub value_candidate_limit: Option<usize>,
151 #[serde(flatten)]
152 pub target: VariableTargetConfig,
153}
154
155#[derive(Debug, Clone, Default, Deserialize, Serialize)]
157#[serde(rename_all = "snake_case")]
158pub struct PillarSwapMoveConfig {
159 pub minimum_sub_pillar_size: usize,
160 pub maximum_sub_pillar_size: usize,
161 #[serde(flatten)]
162 pub target: VariableTargetConfig,
163}
164
165#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
166#[serde(rename_all = "snake_case")]
167pub enum RecreateHeuristicType {
168 #[default]
169 FirstFit,
170 CheapestInsertion,
171}
172
173#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
174#[serde(rename_all = "snake_case")]
175pub enum UnionSelectionOrder {
176 #[default]
177 Sequential,
178 RoundRobin,
179 RotatingRoundRobin,
180 StratifiedRandom,
181}
182
183#[derive(Debug, Clone, Deserialize, Serialize)]
185#[serde(rename_all = "snake_case")]
186pub struct RuinRecreateMoveSelectorConfig {
187 pub min_ruin_count: usize,
188 pub max_ruin_count: usize,
189 pub moves_per_step: Option<usize>,
190 pub value_candidate_limit: Option<usize>,
191 pub recreate_heuristic_type: RecreateHeuristicType,
192 #[serde(flatten)]
193 pub target: VariableTargetConfig,
194}
195
196impl Default for RuinRecreateMoveSelectorConfig {
197 fn default() -> Self {
198 Self {
199 min_ruin_count: 2,
200 max_ruin_count: 5,
201 moves_per_step: None,
202 value_candidate_limit: None,
203 recreate_heuristic_type: RecreateHeuristicType::FirstFit,
204 target: VariableTargetConfig::default(),
205 }
206 }
207}
208
209#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
211#[serde(rename_all = "snake_case")]
212pub struct GroupedScalarMoveSelectorConfig {
213 pub group_name: String,
214 pub value_candidate_limit: Option<usize>,
215 pub max_moves_per_step: Option<usize>,
216 #[serde(default)]
217 pub require_hard_improvement: bool,
218}
219
220#[derive(Debug, Clone, Default, Deserialize, Serialize)]
222#[serde(rename_all = "snake_case")]
223pub struct ListChangeMoveConfig {
224 #[serde(flatten)]
225 pub target: VariableTargetConfig,
226}
227
228#[derive(Debug, Clone, Deserialize, Serialize)]
230#[serde(rename_all = "snake_case")]
231pub struct NearbyListChangeMoveConfig {
232 pub max_nearby: usize,
234 #[serde(flatten)]
235 pub target: VariableTargetConfig,
236}
237
238impl Default for NearbyListChangeMoveConfig {
239 fn default() -> Self {
240 let (max_nearby, target) = default_nearby_target_config();
241 Self { max_nearby, target }
242 }
243}
244
245#[derive(Debug, Clone, Default, Deserialize, Serialize)]
247#[serde(rename_all = "snake_case")]
248pub struct ListSwapMoveConfig {
249 #[serde(flatten)]
250 pub target: VariableTargetConfig,
251}
252
253#[derive(Debug, Clone, Deserialize, Serialize)]
255#[serde(rename_all = "snake_case")]
256pub struct ListPermuteMoveConfig {
257 pub min_window_size: usize,
259 pub max_window_size: usize,
261 #[serde(flatten)]
262 pub target: VariableTargetConfig,
263}
264
265impl Default for ListPermuteMoveConfig {
266 fn default() -> Self {
267 Self {
268 min_window_size: 2,
269 max_window_size: 5,
270 target: VariableTargetConfig::default(),
271 }
272 }
273}
274
275#[derive(Debug, Clone, Default, Deserialize, Serialize)]
277#[serde(rename_all = "snake_case")]
278pub struct ListPrecedenceMoveConfig {
279 #[serde(flatten)]
280 pub target: VariableTargetConfig,
281}
282
283#[derive(Debug, Clone, Deserialize, Serialize)]
285#[serde(rename_all = "snake_case")]
286pub struct NearbyListSwapMoveConfig {
287 pub max_nearby: usize,
289 #[serde(flatten)]
290 pub target: VariableTargetConfig,
291}
292
293impl Default for NearbyListSwapMoveConfig {
294 fn default() -> Self {
295 let (max_nearby, target) = default_nearby_target_config();
296 Self { max_nearby, target }
297 }
298}
299
300#[derive(Debug, Clone, Deserialize, Serialize)]
302#[serde(rename_all = "snake_case")]
303pub struct SublistChangeMoveConfig {
304 pub min_sublist_size: usize,
306 pub max_sublist_size: usize,
308 #[serde(flatten)]
309 pub target: VariableTargetConfig,
310}
311
312impl Default for SublistChangeMoveConfig {
313 fn default() -> Self {
314 let (min_sublist_size, max_sublist_size, target) = default_sublist_target_config();
315 Self {
316 min_sublist_size,
317 max_sublist_size,
318 target,
319 }
320 }
321}
322
323#[derive(Debug, Clone, Deserialize, Serialize)]
325#[serde(rename_all = "snake_case")]
326pub struct SublistSwapMoveConfig {
327 pub min_sublist_size: usize,
329 pub max_sublist_size: usize,
331 #[serde(flatten)]
332 pub target: VariableTargetConfig,
333}
334
335impl Default for SublistSwapMoveConfig {
336 fn default() -> Self {
337 let (min_sublist_size, max_sublist_size, target) = default_sublist_target_config();
338 Self {
339 min_sublist_size,
340 max_sublist_size,
341 target,
342 }
343 }
344}
345
346#[derive(Debug, Clone, Default, Deserialize, Serialize)]
348#[serde(rename_all = "snake_case")]
349pub struct ListReverseMoveConfig {
350 #[serde(flatten)]
351 pub target: VariableTargetConfig,
352}
353
354#[derive(Debug, Clone, Deserialize, Serialize)]
356#[serde(rename_all = "snake_case")]
357pub struct KOptMoveSelectorConfig {
358 pub k: usize,
360 pub min_segment_len: usize,
362 pub max_nearby: usize,
365 #[serde(flatten)]
366 pub target: VariableTargetConfig,
367}
368
369impl Default for KOptMoveSelectorConfig {
370 fn default() -> Self {
371 Self {
372 k: 3,
373 min_segment_len: 1,
374 max_nearby: 0,
375 target: VariableTargetConfig::default(),
376 }
377 }
378}
379
380#[derive(Debug, Clone, Deserialize, Serialize)]
382#[serde(rename_all = "snake_case")]
383pub struct ListRuinMoveSelectorConfig {
384 pub min_ruin_count: usize,
386 pub max_ruin_count: usize,
388 pub moves_per_step: Option<usize>,
390 pub max_source_list_len: Option<usize>,
392 #[serde(default)]
394 pub skip_empty_destinations: bool,
395 #[serde(flatten)]
396 pub target: VariableTargetConfig,
397}
398
399impl Default for ListRuinMoveSelectorConfig {
400 fn default() -> Self {
401 Self {
402 min_ruin_count: 2,
403 max_ruin_count: 5,
404 moves_per_step: None,
405 max_source_list_len: None,
406 skip_empty_destinations: false,
407 target: VariableTargetConfig::default(),
408 }
409 }
410}
411
412#[derive(Debug, Clone, Deserialize, Serialize)]
414#[serde(rename_all = "snake_case")]
415pub struct LimitedNeighborhoodConfig {
416 pub selected_count_limit: usize,
418 pub selector: Box<MoveSelectorConfig>,
420}
421
422#[derive(Debug, Clone, Default, Deserialize, Serialize)]
424#[serde(rename_all = "snake_case")]
425pub struct UnionMoveSelectorConfig {
426 #[serde(default)]
427 pub selection_order: UnionSelectionOrder,
428 pub selectors: Vec<MoveSelectorConfig>,
430}
431
432#[derive(Debug, Clone, Default, Deserialize, Serialize)]
434#[serde(rename_all = "snake_case")]
435pub struct CartesianProductConfig {
436 #[serde(default)]
438 pub require_hard_improvement: bool,
439
440 pub selectors: Vec<MoveSelectorConfig>,
442}
443
444#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
445#[serde(rename_all = "snake_case")]
446pub struct ConflictRepairMoveSelectorConfig {
447 pub constraints: Vec<String>,
448 #[serde(default = "default_conflict_repair_max_matches")]
449 pub max_matches_per_step: usize,
450 #[serde(default = "default_conflict_repair_max_repairs")]
451 pub max_repairs_per_match: usize,
452 #[serde(default = "default_conflict_repair_max_moves")]
453 pub max_moves_per_step: usize,
454 #[serde(default)]
455 pub require_hard_improvement: bool,
456 #[serde(default)]
457 pub include_soft_matches: bool,
458}
459
460impl Default for ConflictRepairMoveSelectorConfig {
461 fn default() -> Self {
462 Self {
463 constraints: Vec::new(),
464 max_matches_per_step: default_conflict_repair_max_matches(),
465 max_repairs_per_match: default_conflict_repair_max_repairs(),
466 max_moves_per_step: default_conflict_repair_max_moves(),
467 require_hard_improvement: false,
468 include_soft_matches: false,
469 }
470 }
471}
472
473#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
474#[serde(rename_all = "snake_case")]
475pub struct CompoundConflictRepairMoveSelectorConfig {
476 pub constraints: Vec<String>,
477 #[serde(default = "default_conflict_repair_max_matches")]
478 pub max_matches_per_step: usize,
479 #[serde(default = "default_conflict_repair_max_repairs")]
480 pub max_repairs_per_match: usize,
481 #[serde(default = "default_conflict_repair_max_moves")]
482 pub max_moves_per_step: usize,
483 #[serde(default = "default_require_hard_improvement")]
484 pub require_hard_improvement: bool,
485 #[serde(default)]
486 pub include_soft_matches: bool,
487}
488
489impl Default for CompoundConflictRepairMoveSelectorConfig {
490 fn default() -> Self {
491 Self {
492 constraints: Vec::new(),
493 max_matches_per_step: default_conflict_repair_max_matches(),
494 max_repairs_per_match: default_conflict_repair_max_repairs(),
495 max_moves_per_step: default_conflict_repair_max_moves(),
496 require_hard_improvement: default_require_hard_improvement(),
497 include_soft_matches: false,
498 }
499 }
500}
501
502fn default_conflict_repair_max_matches() -> usize {
503 16
504}
505
506fn default_conflict_repair_max_repairs() -> usize {
507 32
508}
509
510fn default_conflict_repair_max_moves() -> usize {
511 256
512}
513
514fn default_require_hard_improvement() -> bool {
515 true
516}
517
518fn default_nearby_target_config() -> (usize, VariableTargetConfig) {
519 (10, VariableTargetConfig::default())
520}
521
522fn default_sublist_target_config() -> (usize, usize, VariableTargetConfig) {
523 (1, 3, VariableTargetConfig::default())
524}