vrp_pragmatic/format/problem/
mod.rs1use super::*;
4use crate::parse_time;
5use std::io::{BufReader, Read};
6use std::sync::Arc;
7use vrp_core::models::common::TimeWindow;
8use vrp_core::models::Lock;
9use vrp_core::prelude::{ActivityCost, Fleet as CoreFleet, Jobs as CoreJobs, TransportCost};
10use vrp_core::utils::*;
11
12pub(crate) type ApiProblem = Problem;
13
14mod model;
15pub use self::model::*;
16
17#[cfg(test)]
18#[path = "../../../tests/unit/format/problem/reader_test.rs"]
19mod reader_test;
20
21mod clustering_reader;
22
23mod fleet_reader;
24pub use self::fleet_reader::create_approx_matrices;
25
26mod goal_reader;
27mod job_reader;
28
29mod problem_reader;
30use self::problem_reader::{map_to_problem_with_approx, map_to_problem_with_matrices};
31
32pub trait PragmaticProblem {
34 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError>;
36}
37
38impl<R: Read> PragmaticProblem for (BufReader<R>, Vec<BufReader<R>>) {
39 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
40 let problem = deserialize_problem(self.0)?;
41
42 let mut matrices = vec![];
43 for matrix in self.1 {
44 matrices.push(deserialize_matrix(matrix)?);
45 }
46
47 map_to_problem_with_matrices(problem, matrices)
48 }
49}
50
51impl<R: Read> PragmaticProblem for BufReader<R> {
52 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
53 let problem = deserialize_problem(self)?;
54
55 map_to_problem_with_approx(problem)
56 }
57}
58
59impl PragmaticProblem for (String, Vec<String>) {
60 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
61 let problem = deserialize_problem(BufReader::new(self.0.as_bytes()))?;
62
63 let mut matrices = vec![];
64 for matrix in self.1 {
65 matrices.push(deserialize_matrix(BufReader::new(matrix.as_bytes()))?);
66 }
67
68 map_to_problem_with_matrices(problem, matrices)
69 }
70}
71
72impl PragmaticProblem for String {
73 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
74 let problem = deserialize_problem(BufReader::new(self.as_bytes()))?;
75
76 map_to_problem_with_approx(problem)
77 }
78}
79
80impl PragmaticProblem for (ApiProblem, Vec<Matrix>) {
81 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
82 map_to_problem_with_matrices(self.0, self.1)
83 }
84}
85
86impl PragmaticProblem for ApiProblem {
87 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
88 map_to_problem_with_approx(self)
89 }
90}
91
92impl PragmaticProblem for (ApiProblem, Option<Vec<Matrix>>) {
93 fn read_pragmatic(self) -> Result<CoreProblem, MultiFormatError> {
94 if let Some(matrices) = self.1 {
95 (self.0, matrices).read_pragmatic()
96 } else {
97 self.0.read_pragmatic()
98 }
99 }
100}
101
102struct ProblemProperties {
104 has_multi_dimen_capacity: bool,
105 has_breaks: bool,
106 has_skills: bool,
107 has_unreachable_locations: bool,
108 has_reloads: bool,
109 has_recharges: bool,
110 has_order: bool,
111 has_group: bool,
112 has_value: bool,
113 has_compatibility: bool,
114 has_tour_size_limits: bool,
115 has_tour_travel_limits: bool,
116}
117
118struct ProblemBlocks {
120 jobs: Arc<CoreJobs>,
121 fleet: Arc<CoreFleet>,
122 job_index: Option<Arc<JobIndex>>,
123 transport: Arc<dyn TransportCost>,
124 activity: Arc<dyn ActivityCost>,
125 locks: Vec<Arc<Lock>>,
126 reserved_times_index: ReservedTimesIndex,
127}
128
129fn parse_time_window(tw: &[String]) -> TimeWindow {
130 assert_eq!(tw.len(), 2);
131 TimeWindow::new(parse_time(tw.first().unwrap()), parse_time(tw.last().unwrap()))
132}