vrp_core/models/solution/
registry.rs

1#[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
10/// Specifies an entity responsible for providing actors and keeping track of their usage.
11pub 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    /// Creates a new instance of `Registry`
20    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    /// Removes an actor from the list of available actors.
31    /// Returns whether the actor was present in the registry.
32    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    /// Adds actor to the list of available actors.
37    /// Returns whether the actor was not present in the registry.
38    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    /// Returns all actors.
43    pub fn all(&'_ self) -> impl Iterator<Item = Arc<Actor>> + '_ {
44        self.all.iter().cloned()
45    }
46
47    /// Returns list of all available actors.
48    pub fn available(&'_ self) -> impl Iterator<Item = Arc<Actor>> + '_ {
49        self.available.iter().flat_map(|(_, set)| set.iter().cloned())
50    }
51
52    /// Returns next available actors from each different type.
53    pub fn next(&'_ self) -> impl Iterator<Item = Arc<Actor>> + '_ {
54        self.available.iter().flat_map(move |(_, set)| {
55            // NOTE pick a random actor from set of available actors.
56            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    /// Creates a deep copy of registry.
62    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    /// Creates a deep sliced copy of registry keeping only specific actors.
72    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}