solverforge_solver/heuristic/move/
either.rs1use std::fmt::Debug;
8
9use solverforge_core::domain::PlanningSolution;
10use solverforge_scoring::Director;
11
12use super::{
13 ChangeMove, CompoundScalarMove, ConflictRepairMove, Move, MoveTabuSignature, PillarChangeMove,
14 PillarSwapMove, RuinRecreateMove, SequentialCompositeMove, SwapMove,
15};
16
17#[allow(clippy::large_enum_variant)]
22pub enum ScalarMoveUnion<S, V> {
23 Change(ChangeMove<S, V>),
24 Swap(SwapMove<S, V>),
25 PillarChange(PillarChangeMove<S, V>),
26 PillarSwap(PillarSwapMove<S, V>),
27 RuinRecreate(RuinRecreateMove<S>),
28 Composite(SequentialCompositeMove<S, ScalarMoveUnion<S, V>>),
29 CompoundScalar(CompoundScalarMove<S>),
30 ConflictRepair(ConflictRepairMove<S>),
31}
32
33impl<S, V> Clone for ScalarMoveUnion<S, V>
34where
35 S: PlanningSolution,
36 V: Clone + PartialEq + Send + Sync + Debug + 'static,
37{
38 fn clone(&self) -> Self {
39 match self {
40 Self::Change(m) => Self::Change(m.clone()),
41 Self::Swap(m) => Self::Swap(*m),
42 Self::PillarChange(m) => Self::PillarChange(m.clone()),
43 Self::PillarSwap(m) => Self::PillarSwap(m.clone()),
44 Self::RuinRecreate(m) => Self::RuinRecreate(m.clone()),
45 Self::Composite(m) => Self::Composite(m.clone()),
46 Self::CompoundScalar(m) => Self::CompoundScalar(m.clone()),
47 Self::ConflictRepair(m) => Self::ConflictRepair(m.clone()),
48 }
49 }
50}
51
52impl<S, V> Debug for ScalarMoveUnion<S, V>
53where
54 S: PlanningSolution,
55 V: Clone + PartialEq + Send + Sync + Debug + 'static,
56{
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 match self {
59 Self::Change(m) => m.fmt(f),
60 Self::Swap(m) => m.fmt(f),
61 Self::PillarChange(m) => m.fmt(f),
62 Self::PillarSwap(m) => m.fmt(f),
63 Self::RuinRecreate(m) => m.fmt(f),
64 Self::Composite(m) => m.fmt(f),
65 Self::CompoundScalar(m) => m.fmt(f),
66 Self::ConflictRepair(m) => m.fmt(f),
67 }
68 }
69}
70
71impl<S, V> Move<S> for ScalarMoveUnion<S, V>
72where
73 S: PlanningSolution,
74 V: Clone + PartialEq + Send + Sync + Debug + 'static,
75{
76 fn is_doable<D: Director<S>>(&self, score_director: &D) -> bool {
77 match self {
78 Self::Change(m) => m.is_doable(score_director),
79 Self::Swap(m) => m.is_doable(score_director),
80 Self::PillarChange(m) => m.is_doable(score_director),
81 Self::PillarSwap(m) => m.is_doable(score_director),
82 Self::RuinRecreate(m) => m.is_doable(score_director),
83 Self::Composite(m) => m.is_doable(score_director),
84 Self::CompoundScalar(m) => m.is_doable(score_director),
85 Self::ConflictRepair(m) => m.is_doable(score_director),
86 }
87 }
88
89 fn do_move<D: Director<S>>(&self, score_director: &mut D) {
90 match self {
91 Self::Change(m) => m.do_move(score_director),
92 Self::Swap(m) => m.do_move(score_director),
93 Self::PillarChange(m) => m.do_move(score_director),
94 Self::PillarSwap(m) => m.do_move(score_director),
95 Self::RuinRecreate(m) => m.do_move(score_director),
96 Self::Composite(m) => m.do_move(score_director),
97 Self::CompoundScalar(m) => m.do_move(score_director),
98 Self::ConflictRepair(m) => m.do_move(score_director),
99 }
100 }
101
102 fn descriptor_index(&self) -> usize {
103 match self {
104 Self::Change(m) => m.descriptor_index(),
105 Self::Swap(m) => m.descriptor_index(),
106 Self::PillarChange(m) => m.descriptor_index(),
107 Self::PillarSwap(m) => m.descriptor_index(),
108 Self::RuinRecreate(m) => m.descriptor_index(),
109 Self::Composite(m) => m.descriptor_index(),
110 Self::CompoundScalar(m) => m.descriptor_index(),
111 Self::ConflictRepair(m) => m.descriptor_index(),
112 }
113 }
114
115 fn entity_indices(&self) -> &[usize] {
116 match self {
117 Self::Change(m) => m.entity_indices(),
118 Self::Swap(m) => m.entity_indices(),
119 Self::PillarChange(m) => m.entity_indices(),
120 Self::PillarSwap(m) => m.entity_indices(),
121 Self::RuinRecreate(m) => m.entity_indices(),
122 Self::Composite(m) => m.entity_indices(),
123 Self::CompoundScalar(m) => m.entity_indices(),
124 Self::ConflictRepair(m) => m.entity_indices(),
125 }
126 }
127
128 fn variable_name(&self) -> &str {
129 match self {
130 Self::Change(m) => m.variable_name(),
131 Self::Swap(m) => m.variable_name(),
132 Self::PillarChange(m) => m.variable_name(),
133 Self::PillarSwap(m) => m.variable_name(),
134 Self::RuinRecreate(m) => m.variable_name(),
135 Self::Composite(m) => m.variable_name(),
136 Self::CompoundScalar(m) => m.variable_name(),
137 Self::ConflictRepair(m) => m.variable_name(),
138 }
139 }
140
141 fn requires_hard_improvement(&self) -> bool {
142 match self {
143 Self::Change(m) => m.requires_hard_improvement(),
144 Self::Swap(m) => m.requires_hard_improvement(),
145 Self::PillarChange(m) => m.requires_hard_improvement(),
146 Self::PillarSwap(m) => m.requires_hard_improvement(),
147 Self::RuinRecreate(m) => m.requires_hard_improvement(),
148 Self::Composite(m) => m.requires_hard_improvement(),
149 Self::CompoundScalar(m) => m.requires_hard_improvement(),
150 Self::ConflictRepair(m) => m.requires_hard_improvement(),
151 }
152 }
153
154 fn tabu_signature<D: Director<S>>(&self, score_director: &D) -> MoveTabuSignature {
155 match self {
156 Self::Change(m) => m.tabu_signature(score_director),
157 Self::Swap(m) => m.tabu_signature(score_director),
158 Self::PillarChange(m) => m.tabu_signature(score_director),
159 Self::PillarSwap(m) => m.tabu_signature(score_director),
160 Self::RuinRecreate(m) => m.tabu_signature(score_director),
161 Self::Composite(m) => m.tabu_signature(score_director),
162 Self::CompoundScalar(m) => m.tabu_signature(score_director),
163 Self::ConflictRepair(m) => m.tabu_signature(score_director),
164 }
165 }
166
167 fn for_each_affected_entity(&self, visitor: &mut dyn FnMut(super::MoveAffectedEntity<'_>)) {
168 match self {
169 Self::Change(m) => m.for_each_affected_entity(visitor),
170 Self::Swap(m) => m.for_each_affected_entity(visitor),
171 Self::PillarChange(m) => m.for_each_affected_entity(visitor),
172 Self::PillarSwap(m) => m.for_each_affected_entity(visitor),
173 Self::RuinRecreate(m) => m.for_each_affected_entity(visitor),
174 Self::Composite(m) => m.for_each_affected_entity(visitor),
175 Self::CompoundScalar(m) => m.for_each_affected_entity(visitor),
176 Self::ConflictRepair(m) => m.for_each_affected_entity(visitor),
177 }
178 }
179}