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