1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::io::prelude::*;
use std::io::{BufReader, Read};
use std::sync::Arc;
use vrp_core::construction::constraints::*;
use vrp_core::models::common::*;
use vrp_core::models::problem::*;
use vrp_core::models::{Extras, Problem};
pub(crate) trait TextReader {
fn read_problem(&mut self, is_rounded: bool) -> Result<Problem, String> {
let (jobs, fleet) = self.read_definitions()?;
let transport = self.create_transport(is_rounded)?;
let activity = Arc::new(SimpleActivityCost::default());
let jobs = Jobs::new(&fleet, jobs, &transport);
Ok(Problem {
fleet: Arc::new(fleet),
jobs: Arc::new(jobs),
locks: vec![],
constraint: Arc::new(create_constraint(activity.clone(), transport.clone())),
activity,
transport,
objective: Arc::new(ProblemObjective::default()),
extras: Arc::new(self.create_extras()),
})
}
fn read_definitions(&mut self) -> Result<(Vec<Job>, Fleet), String>;
fn create_transport(&self, is_rounded: bool) -> Result<Arc<dyn TransportCost + Send + Sync>, String>;
fn create_extras(&self) -> Extras;
}
pub(crate) fn create_fleet_with_distance_costs(
number: usize,
capacity: usize,
location: Location,
time: TimeWindow,
) -> Fleet {
Fleet::new(
vec![Arc::new(Driver {
costs: Costs {
fixed: 0.0,
per_distance: 0.0,
per_driving_time: 0.0,
per_waiting_time: 0.0,
per_service_time: 0.0,
},
dimens: create_dimens_with_id("driver", &0.to_string()),
details: Default::default(),
})],
(0..number)
.map(|i| {
let mut dimens = create_dimens_with_id("v", &i.to_string());
dimens.set_capacity(SingleDimLoad::new(capacity as i32));
Arc::new(Vehicle {
profile: Profile::default(),
costs: Costs {
fixed: 0.0,
per_distance: 1.0,
per_driving_time: 0.0,
per_waiting_time: 0.0,
per_service_time: 0.0,
},
dimens,
details: vec![VehicleDetail {
start: Some(VehiclePlace {
location,
time: TimeInterval { earliest: Some(time.start), latest: None },
}),
end: Some(VehiclePlace {
location,
time: TimeInterval { earliest: None, latest: Some(time.end) },
}),
}],
})
})
.collect(),
Box::new(|_| Box::new(|_| 0)),
)
}
pub(crate) fn create_dimens_with_id(prefix: &str, id: &str) -> Dimensions {
let mut dimens = Dimensions::new();
dimens.set_id([prefix.to_string(), id.to_string()].concat().as_str());
dimens
}
pub(crate) fn create_constraint(
activity: Arc<SimpleActivityCost>,
transport: Arc<dyn TransportCost + Send + Sync>,
) -> ConstraintPipeline {
let mut constraint = ConstraintPipeline::default();
constraint.add_module(Arc::new(TransportConstraintModule::new(
transport.clone(),
activity.clone(),
Arc::new(|_| (None, None)),
1,
2,
3,
)));
constraint.add_module(Arc::new(CapacityConstraintModule::<SingleDimLoad>::new(activity, transport, 4)));
constraint.add_module(Arc::new(FleetUsageConstraintModule::new_minimized()));
constraint
}
pub(crate) fn read_line<R: Read>(reader: &mut BufReader<R>, buffer: &mut String) -> Result<usize, String> {
buffer.clear();
reader.read_line(buffer).map_err(|err| err.to_string())
}
pub(crate) fn skip_lines<R: Read>(count: usize, reader: &mut BufReader<R>, buffer: &mut String) -> Result<(), String> {
for _ in 0..count {
read_line(reader, buffer).map_err(|_| "cannot skip lines")?;
}
Ok(())
}