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 Self {
114 max_nearby: 10,
115 value_candidate_limit: None,
116 target: VariableTargetConfig::default(),
117 }
118 }
119}
120
121#[derive(Debug, Clone, Deserialize, Serialize)]
123#[serde(rename_all = "snake_case")]
124pub struct NearbySwapMoveConfig {
125 pub max_nearby: usize,
126 #[serde(flatten)]
127 pub target: VariableTargetConfig,
128}
129
130impl Default for NearbySwapMoveConfig {
131 fn default() -> Self {
132 Self {
133 max_nearby: 10,
134 target: VariableTargetConfig::default(),
135 }
136 }
137}
138
139#[derive(Debug, Clone, Default, Deserialize, Serialize)]
141#[serde(rename_all = "snake_case")]
142pub struct PillarChangeMoveConfig {
143 pub minimum_sub_pillar_size: usize,
144 pub maximum_sub_pillar_size: usize,
145 pub value_candidate_limit: Option<usize>,
146 #[serde(flatten)]
147 pub target: VariableTargetConfig,
148}
149
150#[derive(Debug, Clone, Default, Deserialize, Serialize)]
152#[serde(rename_all = "snake_case")]
153pub struct PillarSwapMoveConfig {
154 pub minimum_sub_pillar_size: usize,
155 pub maximum_sub_pillar_size: usize,
156 #[serde(flatten)]
157 pub target: VariableTargetConfig,
158}
159
160#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
161#[serde(rename_all = "snake_case")]
162pub enum RecreateHeuristicType {
163 #[default]
164 FirstFit,
165 CheapestInsertion,
166}
167
168#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Eq)]
169#[serde(rename_all = "snake_case")]
170pub enum UnionSelectionOrder {
171 #[default]
172 Sequential,
173 RoundRobin,
174}
175
176#[derive(Debug, Clone, Deserialize, Serialize)]
178#[serde(rename_all = "snake_case")]
179pub struct RuinRecreateMoveSelectorConfig {
180 pub min_ruin_count: usize,
181 pub max_ruin_count: usize,
182 pub moves_per_step: Option<usize>,
183 pub value_candidate_limit: Option<usize>,
184 pub recreate_heuristic_type: RecreateHeuristicType,
185 #[serde(flatten)]
186 pub target: VariableTargetConfig,
187}
188
189impl Default for RuinRecreateMoveSelectorConfig {
190 fn default() -> Self {
191 Self {
192 min_ruin_count: 2,
193 max_ruin_count: 5,
194 moves_per_step: None,
195 value_candidate_limit: None,
196 recreate_heuristic_type: RecreateHeuristicType::FirstFit,
197 target: VariableTargetConfig::default(),
198 }
199 }
200}
201
202#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
204#[serde(rename_all = "snake_case")]
205pub struct GroupedScalarMoveSelectorConfig {
206 pub group_name: String,
207 pub value_candidate_limit: Option<usize>,
208 pub max_moves_per_step: Option<usize>,
209 #[serde(default)]
210 pub require_hard_improvement: bool,
211}
212
213#[derive(Debug, Clone, Default, Deserialize, Serialize)]
215#[serde(rename_all = "snake_case")]
216pub struct ListChangeMoveConfig {
217 #[serde(flatten)]
218 pub target: VariableTargetConfig,
219}
220
221#[derive(Debug, Clone, Deserialize, Serialize)]
223#[serde(rename_all = "snake_case")]
224pub struct NearbyListChangeMoveConfig {
225 pub max_nearby: usize,
227 #[serde(flatten)]
228 pub target: VariableTargetConfig,
229}
230
231impl Default for NearbyListChangeMoveConfig {
232 fn default() -> Self {
233 Self {
234 max_nearby: 10,
235 target: VariableTargetConfig::default(),
236 }
237 }
238}
239
240#[derive(Debug, Clone, Default, Deserialize, Serialize)]
242#[serde(rename_all = "snake_case")]
243pub struct ListSwapMoveConfig {
244 #[serde(flatten)]
245 pub target: VariableTargetConfig,
246}
247
248#[derive(Debug, Clone, Deserialize, Serialize)]
250#[serde(rename_all = "snake_case")]
251pub struct NearbyListSwapMoveConfig {
252 pub max_nearby: usize,
254 #[serde(flatten)]
255 pub target: VariableTargetConfig,
256}
257
258impl Default for NearbyListSwapMoveConfig {
259 fn default() -> Self {
260 Self {
261 max_nearby: 10,
262 target: VariableTargetConfig::default(),
263 }
264 }
265}
266
267#[derive(Debug, Clone, Deserialize, Serialize)]
269#[serde(rename_all = "snake_case")]
270pub struct SublistChangeMoveConfig {
271 pub min_sublist_size: usize,
273 pub max_sublist_size: usize,
275 #[serde(flatten)]
276 pub target: VariableTargetConfig,
277}
278
279impl Default for SublistChangeMoveConfig {
280 fn default() -> Self {
281 Self {
282 min_sublist_size: 1,
283 max_sublist_size: 3,
284 target: VariableTargetConfig::default(),
285 }
286 }
287}
288
289#[derive(Debug, Clone, Deserialize, Serialize)]
291#[serde(rename_all = "snake_case")]
292pub struct SublistSwapMoveConfig {
293 pub min_sublist_size: usize,
295 pub max_sublist_size: usize,
297 #[serde(flatten)]
298 pub target: VariableTargetConfig,
299}
300
301impl Default for SublistSwapMoveConfig {
302 fn default() -> Self {
303 Self {
304 min_sublist_size: 1,
305 max_sublist_size: 3,
306 target: VariableTargetConfig::default(),
307 }
308 }
309}
310
311#[derive(Debug, Clone, Default, Deserialize, Serialize)]
313#[serde(rename_all = "snake_case")]
314pub struct ListReverseMoveConfig {
315 #[serde(flatten)]
316 pub target: VariableTargetConfig,
317}
318
319#[derive(Debug, Clone, Deserialize, Serialize)]
321#[serde(rename_all = "snake_case")]
322pub struct KOptMoveSelectorConfig {
323 pub k: usize,
325 pub min_segment_len: usize,
327 pub max_nearby: usize,
330 #[serde(flatten)]
331 pub target: VariableTargetConfig,
332}
333
334impl Default for KOptMoveSelectorConfig {
335 fn default() -> Self {
336 Self {
337 k: 3,
338 min_segment_len: 1,
339 max_nearby: 0,
340 target: VariableTargetConfig::default(),
341 }
342 }
343}
344
345#[derive(Debug, Clone, Deserialize, Serialize)]
347#[serde(rename_all = "snake_case")]
348pub struct ListRuinMoveSelectorConfig {
349 pub min_ruin_count: usize,
351 pub max_ruin_count: usize,
353 pub moves_per_step: Option<usize>,
355 #[serde(flatten)]
356 pub target: VariableTargetConfig,
357}
358
359impl Default for ListRuinMoveSelectorConfig {
360 fn default() -> Self {
361 Self {
362 min_ruin_count: 2,
363 max_ruin_count: 5,
364 moves_per_step: None,
365 target: VariableTargetConfig::default(),
366 }
367 }
368}
369
370#[derive(Debug, Clone, Deserialize, Serialize)]
372#[serde(rename_all = "snake_case")]
373pub struct LimitedNeighborhoodConfig {
374 pub selected_count_limit: usize,
376 pub selector: Box<MoveSelectorConfig>,
378}
379
380#[derive(Debug, Clone, Default, Deserialize, Serialize)]
382#[serde(rename_all = "snake_case")]
383pub struct UnionMoveSelectorConfig {
384 #[serde(default)]
385 pub selection_order: UnionSelectionOrder,
386 pub selectors: Vec<MoveSelectorConfig>,
388}
389
390#[derive(Debug, Clone, Default, Deserialize, Serialize)]
392#[serde(rename_all = "snake_case")]
393pub struct CartesianProductConfig {
394 #[serde(default)]
396 pub require_hard_improvement: bool,
397
398 pub selectors: Vec<MoveSelectorConfig>,
400}
401
402#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
403#[serde(rename_all = "snake_case")]
404pub struct ConflictRepairMoveSelectorConfig {
405 pub constraints: Vec<String>,
406 #[serde(default = "default_conflict_repair_max_matches")]
407 pub max_matches_per_step: usize,
408 #[serde(default = "default_conflict_repair_max_repairs")]
409 pub max_repairs_per_match: usize,
410 #[serde(default = "default_conflict_repair_max_moves")]
411 pub max_moves_per_step: usize,
412 #[serde(default)]
413 pub require_hard_improvement: bool,
414 #[serde(default)]
415 pub include_soft_matches: bool,
416}
417
418impl Default for ConflictRepairMoveSelectorConfig {
419 fn default() -> Self {
420 Self {
421 constraints: Vec::new(),
422 max_matches_per_step: default_conflict_repair_max_matches(),
423 max_repairs_per_match: default_conflict_repair_max_repairs(),
424 max_moves_per_step: default_conflict_repair_max_moves(),
425 require_hard_improvement: false,
426 include_soft_matches: false,
427 }
428 }
429}
430
431#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
432#[serde(rename_all = "snake_case")]
433pub struct CompoundConflictRepairMoveSelectorConfig {
434 pub constraints: Vec<String>,
435 #[serde(default = "default_conflict_repair_max_matches")]
436 pub max_matches_per_step: usize,
437 #[serde(default = "default_conflict_repair_max_repairs")]
438 pub max_repairs_per_match: usize,
439 #[serde(default = "default_conflict_repair_max_moves")]
440 pub max_moves_per_step: usize,
441 #[serde(default = "default_require_hard_improvement")]
442 pub require_hard_improvement: bool,
443 #[serde(default)]
444 pub include_soft_matches: bool,
445}
446
447impl Default for CompoundConflictRepairMoveSelectorConfig {
448 fn default() -> Self {
449 Self {
450 constraints: Vec::new(),
451 max_matches_per_step: default_conflict_repair_max_matches(),
452 max_repairs_per_match: default_conflict_repair_max_repairs(),
453 max_moves_per_step: default_conflict_repair_max_moves(),
454 require_hard_improvement: default_require_hard_improvement(),
455 include_soft_matches: false,
456 }
457 }
458}
459
460fn default_conflict_repair_max_matches() -> usize {
461 16
462}
463
464fn default_conflict_repair_max_repairs() -> usize {
465 32
466}
467
468fn default_conflict_repair_max_moves() -> usize {
469 256
470}
471
472fn default_require_hard_improvement() -> bool {
473 true
474}