solverforge_solver/heuristic/move/
traits.rs1use std::fmt::Debug;
4
5use solverforge_core::domain::PlanningSolution;
6use solverforge_scoring::Director;
7
8use super::MoveTabuSignature;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct MoveAffectedEntity<'a> {
12 pub descriptor_index: usize,
13 pub entity_index: usize,
14 pub variable_name: &'a str,
15}
16
17pub trait Move<S: PlanningSolution>: Send + Sync + Debug {
30 type Undo: Send;
31
32 fn is_doable<D: Director<S>>(&self, score_director: &D) -> bool;
40
41 fn do_move<D: Director<S>>(&self, score_director: &mut D) -> Self::Undo;
47
48 fn undo_move<D: Director<S>>(&self, score_director: &mut D, undo: Self::Undo);
49
50 fn descriptor_index(&self) -> usize;
51
52 fn entity_indices(&self) -> &[usize];
53
54 fn variable_name(&self) -> &str;
55
56 fn telemetry_label(&self) -> &'static str {
57 "move"
58 }
59
60 fn requires_hard_improvement(&self) -> bool {
61 false
62 }
63
64 fn requires_score_improvement(&self) -> bool {
65 false
66 }
67
68 fn tabu_signature<D: Director<S>>(&self, score_director: &D) -> MoveTabuSignature;
69
70 fn for_each_affected_entity(&self, visitor: &mut dyn FnMut(MoveAffectedEntity<'_>)) {
71 let descriptor_index = self.descriptor_index();
72 let variable_name = self.variable_name();
73 for &entity_index in self.entity_indices() {
74 visitor(MoveAffectedEntity {
75 descriptor_index,
76 entity_index,
77 variable_name,
78 });
79 }
80 }
81}