solverforge_solver/heuristic/move/
list_either.rs1use std::fmt::Debug;
8
9use solverforge_core::domain::PlanningSolution;
10use solverforge_scoring::Director;
11
12use super::{
13 KOptMove, ListChangeMove, ListReverseMove, ListRuinMove, ListSwapMove, Move, MoveTabuSignature,
14 SequentialCompositeMove, SublistChangeMove, SublistSwapMove,
15};
16
17#[allow(clippy::large_enum_variant)]
31pub enum ListMoveUnion<S, V> {
32 ListChange(ListChangeMove<S, V>),
33 ListSwap(ListSwapMove<S, V>),
34 SublistChange(SublistChangeMove<S, V>),
35 SublistSwap(SublistSwapMove<S, V>),
36 ListReverse(ListReverseMove<S, V>),
37 KOpt(KOptMove<S, V>),
38 ListRuin(ListRuinMove<S, V>),
39 Composite(SequentialCompositeMove<S, ListMoveUnion<S, V>>),
40}
41
42impl<S, V> Clone for ListMoveUnion<S, V>
43where
44 S: PlanningSolution,
45 V: Clone + PartialEq + Send + Sync + Debug + 'static,
46{
47 fn clone(&self) -> Self {
48 match self {
49 Self::ListChange(m) => Self::ListChange(*m),
50 Self::ListSwap(m) => Self::ListSwap(*m),
51 Self::SublistChange(m) => Self::SublistChange(*m),
52 Self::SublistSwap(m) => Self::SublistSwap(*m),
53 Self::ListReverse(m) => Self::ListReverse(*m),
54 Self::KOpt(m) => Self::KOpt(m.clone()),
55 Self::ListRuin(m) => Self::ListRuin(m.clone()),
56 Self::Composite(m) => Self::Composite(m.clone()),
57 }
58 }
59}
60
61impl<S, V> Debug for ListMoveUnion<S, V>
62where
63 S: PlanningSolution,
64 V: Clone + PartialEq + Send + Sync + Debug + 'static,
65{
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 Self::ListChange(m) => m.fmt(f),
69 Self::ListSwap(m) => m.fmt(f),
70 Self::SublistChange(m) => m.fmt(f),
71 Self::SublistSwap(m) => m.fmt(f),
72 Self::ListReverse(m) => m.fmt(f),
73 Self::KOpt(m) => m.fmt(f),
74 Self::ListRuin(m) => m.fmt(f),
75 Self::Composite(m) => m.fmt(f),
76 }
77 }
78}
79
80impl<S, V> Move<S> for ListMoveUnion<S, V>
81where
82 S: PlanningSolution,
83 V: Clone + PartialEq + Send + Sync + Debug + 'static,
84{
85 fn is_doable<D: Director<S>>(&self, score_director: &D) -> bool {
86 match self {
87 Self::ListChange(m) => m.is_doable(score_director),
88 Self::ListSwap(m) => m.is_doable(score_director),
89 Self::SublistChange(m) => m.is_doable(score_director),
90 Self::SublistSwap(m) => m.is_doable(score_director),
91 Self::ListReverse(m) => m.is_doable(score_director),
92 Self::KOpt(m) => m.is_doable(score_director),
93 Self::ListRuin(m) => m.is_doable(score_director),
94 Self::Composite(m) => m.is_doable(score_director),
95 }
96 }
97
98 fn do_move<D: Director<S>>(&self, score_director: &mut D) {
99 match self {
100 Self::ListChange(m) => m.do_move(score_director),
101 Self::ListSwap(m) => m.do_move(score_director),
102 Self::SublistChange(m) => m.do_move(score_director),
103 Self::SublistSwap(m) => m.do_move(score_director),
104 Self::ListReverse(m) => m.do_move(score_director),
105 Self::KOpt(m) => m.do_move(score_director),
106 Self::ListRuin(m) => m.do_move(score_director),
107 Self::Composite(m) => m.do_move(score_director),
108 }
109 }
110
111 fn descriptor_index(&self) -> usize {
112 match self {
113 Self::ListChange(m) => m.descriptor_index(),
114 Self::ListSwap(m) => m.descriptor_index(),
115 Self::SublistChange(m) => m.descriptor_index(),
116 Self::SublistSwap(m) => m.descriptor_index(),
117 Self::ListReverse(m) => m.descriptor_index(),
118 Self::KOpt(m) => m.descriptor_index(),
119 Self::ListRuin(m) => m.descriptor_index(),
120 Self::Composite(m) => m.descriptor_index(),
121 }
122 }
123
124 fn entity_indices(&self) -> &[usize] {
125 match self {
126 Self::ListChange(m) => m.entity_indices(),
127 Self::ListSwap(m) => m.entity_indices(),
128 Self::SublistChange(m) => m.entity_indices(),
129 Self::SublistSwap(m) => m.entity_indices(),
130 Self::ListReverse(m) => m.entity_indices(),
131 Self::KOpt(m) => m.entity_indices(),
132 Self::ListRuin(m) => m.entity_indices(),
133 Self::Composite(m) => m.entity_indices(),
134 }
135 }
136
137 fn variable_name(&self) -> &str {
138 match self {
139 Self::ListChange(m) => m.variable_name(),
140 Self::ListSwap(m) => m.variable_name(),
141 Self::SublistChange(m) => m.variable_name(),
142 Self::SublistSwap(m) => m.variable_name(),
143 Self::ListReverse(m) => m.variable_name(),
144 Self::KOpt(m) => m.variable_name(),
145 Self::ListRuin(m) => m.variable_name(),
146 Self::Composite(m) => m.variable_name(),
147 }
148 }
149
150 fn tabu_signature<D: Director<S>>(&self, score_director: &D) -> MoveTabuSignature {
151 match self {
152 Self::ListChange(m) => m.tabu_signature(score_director),
153 Self::ListSwap(m) => m.tabu_signature(score_director),
154 Self::SublistChange(m) => m.tabu_signature(score_director),
155 Self::SublistSwap(m) => m.tabu_signature(score_director),
156 Self::ListReverse(m) => m.tabu_signature(score_director),
157 Self::KOpt(m) => m.tabu_signature(score_director),
158 Self::ListRuin(m) => m.tabu_signature(score_director),
159 Self::Composite(m) => m.tabu_signature(score_director),
160 }
161 }
162}