vrp_core/models/solution/
registry.rs1#[cfg(test)]
2#[path = "../../../tests/unit/models/solution/actor_test.rs"]
3mod actor_test;
4
5use crate::models::problem::{Actor, Fleet};
6use rosomaxa::prelude::Random;
7use std::collections::{HashMap, HashSet};
8use std::sync::Arc;
9
10pub struct Registry {
12 available: HashMap<usize, HashSet<Arc<Actor>>>,
13 index: HashMap<Arc<Actor>, usize>,
14 all: Vec<Arc<Actor>>,
15 random: Arc<dyn Random>,
16}
17
18impl Registry {
19 pub fn new(fleet: &Fleet, random: Arc<dyn Random>) -> Self {
21 let index = fleet
22 .groups
23 .iter()
24 .flat_map(|(group_id, actors)| actors.iter().map(|a| (a.clone(), *group_id)).collect::<Vec<_>>())
25 .collect();
26
27 Self { available: fleet.groups.clone(), index, all: fleet.actors.to_vec(), random }
28 }
29
30 pub fn use_actor(&mut self, actor: &Actor) -> bool {
33 self.index.get(actor).and_then(|idx| self.available.get_mut(idx)).map_or(false, |set| set.remove(actor))
34 }
35
36 pub fn free_actor(&mut self, actor: &Arc<Actor>) -> bool {
39 self.index.get(actor).and_then(|idx| self.available.get_mut(idx)).map_or(false, |set| set.insert(actor.clone()))
40 }
41
42 pub fn all(&'_ self) -> impl Iterator<Item = Arc<Actor>> + '_ {
44 self.all.iter().cloned()
45 }
46
47 pub fn available(&'_ self) -> impl Iterator<Item = Arc<Actor>> + '_ {
49 self.available.iter().flat_map(|(_, set)| set.iter().cloned())
50 }
51
52 pub fn next(&'_ self) -> impl Iterator<Item = Arc<Actor>> + '_ {
54 self.available.iter().flat_map(move |(_, set)| {
55 let skip_amount = if set.len() < 2 { 0 } else { self.random.uniform_int(0, set.len() as i32 - 1) as usize };
57 set.iter().skip(skip_amount).take(1).cloned()
58 })
59 }
60
61 pub fn deep_copy(&self) -> Self {
63 Self {
64 available: self.available.clone(),
65 index: self.index.clone(),
66 all: self.all.clone(),
67 random: self.random.clone(),
68 }
69 }
70
71 pub fn deep_slice(&self, filter: impl Fn(&Actor) -> bool) -> Self {
73 Self {
74 available: self
75 .available
76 .iter()
77 .map(|(idx, actors)| {
78 let actors = actors.iter().filter(|actor| filter(actor.as_ref())).cloned().collect::<HashSet<_>>();
79 (*idx, actors)
80 })
81 .collect(),
82 index: self
83 .index
84 .iter()
85 .filter(|(actor, _)| filter(actor.as_ref()))
86 .map(|(actor, idx)| (actor.clone(), *idx))
87 .collect(),
88 all: self.all.iter().filter(|actor| filter(actor.as_ref())).cloned().collect(),
89 random: self.random.clone(),
90 }
91 }
92}