solverforge_solver/heuristic/move/
list_either.rs1use std::fmt::Debug;
7
8use solverforge_core::domain::PlanningSolution;
9use solverforge_scoring::ScoreDirector;
10
11use super::{
12 KOptMove, ListChangeMove, ListReverseMove, ListRuinMove, ListSwapMove, Move, SubListChangeMove,
13 SubListSwapMove,
14};
15
16pub enum ListMoveImpl<S, V> {
30 ListChange(ListChangeMove<S, V>),
31 ListSwap(ListSwapMove<S, V>),
32 SubListChange(SubListChangeMove<S, V>),
33 SubListSwap(SubListSwapMove<S, V>),
34 ListReverse(ListReverseMove<S, V>),
35 KOpt(KOptMove<S, V>),
36 ListRuin(ListRuinMove<S, V>),
37}
38
39impl<S, V: Clone> Clone for ListMoveImpl<S, V> {
40 fn clone(&self) -> Self {
41 match self {
42 Self::ListChange(m) => Self::ListChange(*m),
43 Self::ListSwap(m) => Self::ListSwap(*m),
44 Self::SubListChange(m) => Self::SubListChange(*m),
45 Self::SubListSwap(m) => Self::SubListSwap(*m),
46 Self::ListReverse(m) => Self::ListReverse(*m),
47 Self::KOpt(m) => Self::KOpt(m.clone()),
48 Self::ListRuin(m) => Self::ListRuin(m.clone()),
49 }
50 }
51}
52
53impl<S, V: Debug> Debug for ListMoveImpl<S, V> {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 match self {
56 Self::ListChange(m) => m.fmt(f),
57 Self::ListSwap(m) => m.fmt(f),
58 Self::SubListChange(m) => m.fmt(f),
59 Self::SubListSwap(m) => m.fmt(f),
60 Self::ListReverse(m) => m.fmt(f),
61 Self::KOpt(m) => m.fmt(f),
62 Self::ListRuin(m) => m.fmt(f),
63 }
64 }
65}
66
67impl<S, V> Move<S> for ListMoveImpl<S, V>
68where
69 S: PlanningSolution,
70 V: Clone + PartialEq + Send + Sync + Debug + 'static,
71{
72 fn is_doable<D: ScoreDirector<S>>(&self, score_director: &D) -> bool {
73 match self {
74 Self::ListChange(m) => m.is_doable(score_director),
75 Self::ListSwap(m) => m.is_doable(score_director),
76 Self::SubListChange(m) => m.is_doable(score_director),
77 Self::SubListSwap(m) => m.is_doable(score_director),
78 Self::ListReverse(m) => m.is_doable(score_director),
79 Self::KOpt(m) => m.is_doable(score_director),
80 Self::ListRuin(m) => m.is_doable(score_director),
81 }
82 }
83
84 fn do_move<D: ScoreDirector<S>>(&self, score_director: &mut D) {
85 match self {
86 Self::ListChange(m) => m.do_move(score_director),
87 Self::ListSwap(m) => m.do_move(score_director),
88 Self::SubListChange(m) => m.do_move(score_director),
89 Self::SubListSwap(m) => m.do_move(score_director),
90 Self::ListReverse(m) => m.do_move(score_director),
91 Self::KOpt(m) => m.do_move(score_director),
92 Self::ListRuin(m) => m.do_move(score_director),
93 }
94 }
95
96 fn descriptor_index(&self) -> usize {
97 match self {
98 Self::ListChange(m) => m.descriptor_index(),
99 Self::ListSwap(m) => m.descriptor_index(),
100 Self::SubListChange(m) => m.descriptor_index(),
101 Self::SubListSwap(m) => m.descriptor_index(),
102 Self::ListReverse(m) => m.descriptor_index(),
103 Self::KOpt(m) => m.descriptor_index(),
104 Self::ListRuin(m) => m.descriptor_index(),
105 }
106 }
107
108 fn entity_indices(&self) -> &[usize] {
109 match self {
110 Self::ListChange(m) => m.entity_indices(),
111 Self::ListSwap(m) => m.entity_indices(),
112 Self::SubListChange(m) => m.entity_indices(),
113 Self::SubListSwap(m) => m.entity_indices(),
114 Self::ListReverse(m) => m.entity_indices(),
115 Self::KOpt(m) => m.entity_indices(),
116 Self::ListRuin(m) => m.entity_indices(),
117 }
118 }
119
120 fn variable_name(&self) -> &str {
121 match self {
122 Self::ListChange(m) => m.variable_name(),
123 Self::ListSwap(m) => m.variable_name(),
124 Self::SubListChange(m) => m.variable_name(),
125 Self::SubListSwap(m) => m.variable_name(),
126 Self::ListReverse(m) => m.variable_name(),
127 Self::KOpt(m) => m.variable_name(),
128 Self::ListRuin(m) => m.variable_name(),
129 }
130 }
131}