1#[cfg(test)]
2#[path = "../../../tests/unit/models/problem/fleet_test.rs"]
3mod fleet_test;
4
5use crate::models::common::*;
6use crate::utils::short_type_name;
7use rosomaxa::prelude::Float;
8use std::collections::{HashMap, HashSet};
9use std::fmt::{Debug, Formatter};
10use std::hash::{Hash, Hasher};
11use std::sync::Arc;
12
13custom_dimension!(VehicleId typeof String);
14
15#[derive(Clone, Debug)]
17pub struct Costs {
18 pub fixed: Float,
20 pub per_distance: Float,
22 pub per_driving_time: Float,
24 pub per_waiting_time: Float,
26 pub per_service_time: Float,
28}
29
30#[derive(Clone, Hash, Eq, PartialEq)]
32pub struct DriverDetail {}
33
34pub struct Driver {
37 pub costs: Costs,
39
40 pub dimens: Dimensions,
42
43 pub details: Vec<DriverDetail>,
45}
46
47impl Driver {
48 pub(crate) fn empty() -> Self {
50 Self {
51 costs: Costs {
52 fixed: 0.,
53 per_distance: 0.,
54 per_driving_time: 0.,
55 per_waiting_time: 0.,
56 per_service_time: 0.,
57 },
58 dimens: Default::default(),
59 details: vec![],
60 }
61 }
62}
63
64#[derive(Clone, Debug, Hash, Eq, PartialEq)]
66pub struct VehiclePlace {
67 pub location: Location,
69
70 pub time: TimeInterval,
72}
73
74#[derive(Clone, Debug, Hash, Eq, PartialEq)]
76pub struct VehicleDetail {
77 pub start: Option<VehiclePlace>,
79
80 pub end: Option<VehiclePlace>,
82}
83
84#[derive(Clone, Debug)]
86pub struct Vehicle {
87 pub profile: Profile,
89
90 pub costs: Costs,
92
93 pub dimens: Dimensions,
95
96 pub details: Vec<VehicleDetail>,
98}
99
100#[derive(Clone, Hash, Eq, PartialEq)]
102pub struct ActorDetail {
103 pub start: Option<VehiclePlace>,
105
106 pub end: Option<VehiclePlace>,
108
109 pub time: TimeWindow,
111}
112
113pub struct Actor {
115 pub vehicle: Arc<Vehicle>,
117
118 pub driver: Arc<Driver>,
120
121 pub detail: ActorDetail,
123}
124
125impl Debug for Actor {
126 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
127 f.debug_struct(short_type_name::<Self>())
128 .field("vehicle", &self.vehicle.dimens.get_vehicle_id().map(|id| id.as_str()).unwrap_or("undef"))
129 .finish_non_exhaustive()
130 }
131}
132
133pub struct Fleet {
135 pub drivers: Vec<Arc<Driver>>,
137
138 pub vehicles: Vec<Arc<Vehicle>>,
140
141 pub profiles: Vec<Profile>,
143
144 pub actors: Vec<Arc<Actor>>,
146
147 pub groups: HashMap<usize, HashSet<Arc<Actor>>>,
149}
150
151impl Fleet {
152 pub fn new<R: Fn(&Actor) -> usize + Send + Sync>(
154 drivers: Vec<Arc<Driver>>,
155 vehicles: Vec<Arc<Vehicle>>,
156 group_key: impl Fn(&[Arc<Actor>]) -> R,
157 ) -> Fleet {
158 assert_eq!(drivers.len(), 1);
160 assert!(!vehicles.is_empty());
161
162 let profiles: HashMap<usize, Profile> = vehicles.iter().map(|v| (v.profile.index, v.profile.clone())).collect();
163 let mut profiles = profiles.into_iter().collect::<Vec<_>>();
164 profiles.sort_by(|(a, _), (b, _)| a.cmp(b));
165 let (_, profiles): (Vec<_>, Vec<_>) = profiles.into_iter().unzip();
166
167 let actors = vehicles
168 .iter()
169 .flat_map(|vehicle| {
170 vehicle.details.iter().map(|detail| {
171 Arc::new(Actor {
172 vehicle: vehicle.clone(),
173 driver: drivers.first().unwrap().clone(),
174 detail: ActorDetail {
175 start: detail.start.clone(),
176 end: detail.end.clone(),
177 time: TimeWindow {
178 start: detail.start.as_ref().and_then(|s| s.time.earliest).unwrap_or(0.),
179 end: detail.end.as_ref().and_then(|e| e.time.latest).unwrap_or(Float::MAX),
180 },
181 },
182 })
183 })
184 })
185 .collect::<Vec<_>>();
186
187 let group_key = (group_key)(&actors);
188 let groups: HashMap<_, HashSet<_>> = actors.iter().cloned().fold(HashMap::new(), |mut acc, actor| {
189 acc.entry((group_key)(&actor)).or_default().insert(actor.clone());
190 acc
191 });
192
193 Fleet { drivers, vehicles, profiles, actors, groups }
194 }
195}
196
197impl Debug for Fleet {
198 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
199 f.debug_struct(short_type_name::<Self>())
200 .field("vehicles", &self.vehicles.len())
201 .field("drivers", &self.drivers.len())
202 .field("profiles", &self.profiles.len())
203 .field("actors", &self.actors.len())
204 .field("groups", &self.groups.len())
205 .finish()
206 }
207}
208
209impl PartialEq<Actor> for Actor {
210 fn eq(&self, other: &Actor) -> bool {
211 std::ptr::eq(self, other)
212 }
213}
214
215impl Eq for Actor {}
216
217impl Hash for Actor {
218 fn hash<H: Hasher>(&self, state: &mut H) {
219 let address = self as *const Actor;
220 address.hash(state);
221 }
222}