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 CoverageRepairMoveSelector(CoverageRepairMoveSelectorConfig),
40
41 ListChangeMoveSelector(ListChangeMoveConfig),
43
44 NearbyListChangeMoveSelector(NearbyListChangeMoveConfig),
46
47 ListSwapMoveSelector(ListSwapMoveConfig),
49
50 NearbyListSwapMoveSelector(NearbyListSwapMoveConfig),
52
53 SublistChangeMoveSelector(SublistChangeMoveConfig),
55
56 SublistSwapMoveSelector(SublistSwapMoveConfig),
58
59 ListReverseMoveSelector(ListReverseMoveConfig),
61
62 KOptMoveSelector(KOptMoveSelectorConfig),
64
65 ListRuinMoveSelector(ListRuinMoveSelectorConfig),
67
68 LimitedNeighborhood(LimitedNeighborhoodConfig),
71
72 UnionMoveSelector(UnionMoveSelectorConfig),
74
75 CartesianProductMoveSelector(CartesianProductConfig),
79
80 ConflictRepairMoveSelector(ConflictRepairMoveSelectorConfig),
82
83 CompoundConflictRepairMoveSelector(CompoundConflictRepairMoveSelectorConfig),
85}
86
87#[derive(Debug, Clone, Default, Deserialize, Serialize)]
89#[serde(rename_all = "snake_case")]
90pub struct ChangeMoveConfig {
91 pub value_candidate_limit: Option<usize>,
92 #[serde(flatten)]
93 pub target: VariableTargetConfig,
94}
95
96#[derive(Debug, Clone, Default, Deserialize, Serialize)]
98#[serde(rename_all = "snake_case")]
99pub struct SwapMoveConfig {
100 #[serde(flatten)]
101 pub target: VariableTargetConfig,
102}
103
104#[derive(Debug, Clone, Deserialize, Serialize)]
106#[serde(rename_all = "snake_case")]
107pub struct NearbyChangeMoveConfig {
108 pub max_nearby: usize,
109 pub value_candidate_limit: Option<usize>,
110 #[serde(flatten)]
111 pub target: VariableTargetConfig,
112}
113
114impl Default for NearbyChangeMoveConfig {
115 fn default() -> Self {
116 Self {
117 max_nearby: 10,
118 value_candidate_limit: None,
119 target: VariableTargetConfig::default(),
120 }
121 }
122}
123
124#[derive(Debug, Clone, Deserialize, Serialize)]
126#[serde(rename_all = "snake_case")]
127pub struct NearbySwapMoveConfig {
128 pub max_nearby: usize,
129 #[serde(flatten)]
130 pub target: VariableTargetConfig,
131}
132
133impl Default for NearbySwapMoveConfig {
134 fn default() -> Self {
135 Self {
136 max_nearby: 10,
137 target: VariableTargetConfig::default(),
138 }
139 }
140}
141
142#[derive(Debug, Clone, Default, Deserialize, Serialize)]
144#[serde(rename_all = "snake_case")]
145pub struct PillarChangeMoveConfig {
146 pub minimum_sub_pillar_size: usize,
147 pub maximum_sub_pillar_size: usize,
148 pub value_candidate_limit: Option<usize>,
149 #[serde(flatten)]
150 pub target: VariableTargetConfig,
151}
152
153#[derive(Debug, Clone, Default, Deserialize, Serialize)]
155#[serde(rename_all = "snake_case")]
156pub struct PillarSwapMoveConfig {
157 pub minimum_sub_pillar_size: usize,
158 pub maximum_sub_pillar_size: usize,
159 #[serde(flatten)]
160 pub target: VariableTargetConfig,
161}
162
163#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
164#[serde(rename_all = "snake_case")]
165pub enum RecreateHeuristicType {
166 #[default]
167 FirstFit,
168 CheapestInsertion,
169}
170
171#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
172#[serde(rename_all = "snake_case")]
173pub enum UnionSelectionOrder {
174 #[default]
175 Sequential,
176 RoundRobin,
177}
178
179#[derive(Debug, Clone, Deserialize, Serialize)]
181#[serde(rename_all = "snake_case")]
182pub struct RuinRecreateMoveSelectorConfig {
183 pub min_ruin_count: usize,
184 pub max_ruin_count: usize,
185 pub moves_per_step: Option<usize>,
186 pub value_candidate_limit: Option<usize>,
187 pub recreate_heuristic_type: RecreateHeuristicType,
188 #[serde(flatten)]
189 pub target: VariableTargetConfig,
190}
191
192impl Default for RuinRecreateMoveSelectorConfig {
193 fn default() -> Self {
194 Self {
195 min_ruin_count: 2,
196 max_ruin_count: 5,
197 moves_per_step: None,
198 value_candidate_limit: None,
199 recreate_heuristic_type: RecreateHeuristicType::FirstFit,
200 target: VariableTargetConfig::default(),
201 }
202 }
203}
204
205#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
207#[serde(rename_all = "snake_case")]
208pub struct GroupedScalarMoveSelectorConfig {
209 pub group_name: String,
210 pub value_candidate_limit: Option<usize>,
211 pub max_moves_per_step: Option<usize>,
212 #[serde(default)]
213 pub require_hard_improvement: bool,
214}
215
216#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
217#[serde(rename_all = "snake_case")]
218pub struct CoverageRepairMoveSelectorConfig {
219 pub group_name: String,
220 pub value_candidate_limit: Option<usize>,
221 pub max_moves_per_step: Option<usize>,
222 #[serde(default)]
223 pub require_hard_improvement: bool,
224}
225
226#[derive(Debug, Clone, Default, Deserialize, Serialize)]
228#[serde(rename_all = "snake_case")]
229pub struct ListChangeMoveConfig {
230 #[serde(flatten)]
231 pub target: VariableTargetConfig,
232}
233
234#[derive(Debug, Clone, Deserialize, Serialize)]
236#[serde(rename_all = "snake_case")]
237pub struct NearbyListChangeMoveConfig {
238 pub max_nearby: usize,
240 #[serde(flatten)]
241 pub target: VariableTargetConfig,
242}
243
244impl Default for NearbyListChangeMoveConfig {
245 fn default() -> Self {
246 Self {
247 max_nearby: 10,
248 target: VariableTargetConfig::default(),
249 }
250 }
251}
252
253#[derive(Debug, Clone, Default, Deserialize, Serialize)]
255#[serde(rename_all = "snake_case")]
256pub struct ListSwapMoveConfig {
257 #[serde(flatten)]
258 pub target: VariableTargetConfig,
259}
260
261#[derive(Debug, Clone, Deserialize, Serialize)]
263#[serde(rename_all = "snake_case")]
264pub struct NearbyListSwapMoveConfig {
265 pub max_nearby: usize,
267 #[serde(flatten)]
268 pub target: VariableTargetConfig,
269}
270
271impl Default for NearbyListSwapMoveConfig {
272 fn default() -> Self {
273 Self {
274 max_nearby: 10,
275 target: VariableTargetConfig::default(),
276 }
277 }
278}
279
280#[derive(Debug, Clone, Deserialize, Serialize)]
282#[serde(rename_all = "snake_case")]
283pub struct SublistChangeMoveConfig {
284 pub min_sublist_size: usize,
286 pub max_sublist_size: usize,
288 #[serde(flatten)]
289 pub target: VariableTargetConfig,
290}
291
292impl Default for SublistChangeMoveConfig {
293 fn default() -> Self {
294 Self {
295 min_sublist_size: 1,
296 max_sublist_size: 3,
297 target: VariableTargetConfig::default(),
298 }
299 }
300}
301
302#[derive(Debug, Clone, Deserialize, Serialize)]
304#[serde(rename_all = "snake_case")]
305pub struct SublistSwapMoveConfig {
306 pub min_sublist_size: usize,
308 pub max_sublist_size: usize,
310 #[serde(flatten)]
311 pub target: VariableTargetConfig,
312}
313
314impl Default for SublistSwapMoveConfig {
315 fn default() -> Self {
316 Self {
317 min_sublist_size: 1,
318 max_sublist_size: 3,
319 target: VariableTargetConfig::default(),
320 }
321 }
322}
323
324#[derive(Debug, Clone, Default, Deserialize, Serialize)]
326#[serde(rename_all = "snake_case")]
327pub struct ListReverseMoveConfig {
328 #[serde(flatten)]
329 pub target: VariableTargetConfig,
330}
331
332#[derive(Debug, Clone, Deserialize, Serialize)]
334#[serde(rename_all = "snake_case")]
335pub struct KOptMoveSelectorConfig {
336 pub k: usize,
338 pub min_segment_len: usize,
340 pub max_nearby: usize,
343 #[serde(flatten)]
344 pub target: VariableTargetConfig,
345}
346
347impl Default for KOptMoveSelectorConfig {
348 fn default() -> Self {
349 Self {
350 k: 3,
351 min_segment_len: 1,
352 max_nearby: 0,
353 target: VariableTargetConfig::default(),
354 }
355 }
356}
357
358#[derive(Debug, Clone, Deserialize, Serialize)]
360#[serde(rename_all = "snake_case")]
361pub struct ListRuinMoveSelectorConfig {
362 pub min_ruin_count: usize,
364 pub max_ruin_count: usize,
366 pub moves_per_step: Option<usize>,
368 #[serde(flatten)]
369 pub target: VariableTargetConfig,
370}
371
372impl Default for ListRuinMoveSelectorConfig {
373 fn default() -> Self {
374 Self {
375 min_ruin_count: 2,
376 max_ruin_count: 5,
377 moves_per_step: None,
378 target: VariableTargetConfig::default(),
379 }
380 }
381}
382
383#[derive(Debug, Clone, Deserialize, Serialize)]
385#[serde(rename_all = "snake_case")]
386pub struct LimitedNeighborhoodConfig {
387 pub selected_count_limit: usize,
389 pub selector: Box<MoveSelectorConfig>,
391}
392
393#[derive(Debug, Clone, Default, Deserialize, Serialize)]
395#[serde(rename_all = "snake_case")]
396pub struct UnionMoveSelectorConfig {
397 #[serde(default)]
398 pub selection_order: UnionSelectionOrder,
399 pub selectors: Vec<MoveSelectorConfig>,
401}
402
403#[derive(Debug, Clone, Default, Deserialize, Serialize)]
405#[serde(rename_all = "snake_case")]
406pub struct CartesianProductConfig {
407 #[serde(default)]
409 pub require_hard_improvement: bool,
410
411 pub selectors: Vec<MoveSelectorConfig>,
413}
414
415#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
416#[serde(rename_all = "snake_case")]
417pub struct ConflictRepairMoveSelectorConfig {
418 pub constraints: Vec<String>,
419 #[serde(default = "default_conflict_repair_max_matches")]
420 pub max_matches_per_step: usize,
421 #[serde(default = "default_conflict_repair_max_repairs")]
422 pub max_repairs_per_match: usize,
423 #[serde(default = "default_conflict_repair_max_moves")]
424 pub max_moves_per_step: usize,
425 #[serde(default)]
426 pub require_hard_improvement: bool,
427 #[serde(default)]
428 pub include_soft_matches: bool,
429}
430
431impl Default for ConflictRepairMoveSelectorConfig {
432 fn default() -> Self {
433 Self {
434 constraints: Vec::new(),
435 max_matches_per_step: default_conflict_repair_max_matches(),
436 max_repairs_per_match: default_conflict_repair_max_repairs(),
437 max_moves_per_step: default_conflict_repair_max_moves(),
438 require_hard_improvement: false,
439 include_soft_matches: false,
440 }
441 }
442}
443
444#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
445#[serde(rename_all = "snake_case")]
446pub struct CompoundConflictRepairMoveSelectorConfig {
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 = "default_require_hard_improvement")]
455 pub require_hard_improvement: bool,
456 #[serde(default)]
457 pub include_soft_matches: bool,
458}
459
460impl Default for CompoundConflictRepairMoveSelectorConfig {
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: default_require_hard_improvement(),
468 include_soft_matches: false,
469 }
470 }
471}
472
473fn default_conflict_repair_max_matches() -> usize {
474 16
475}
476
477fn default_conflict_repair_max_repairs() -> usize {
478 32
479}
480
481fn default_conflict_repair_max_moves() -> usize {
482 256
483}
484
485fn default_require_hard_improvement() -> bool {
486 true
487}