1use std::error::Error;
43use std::fs::File;
44use std::io::{self, BufReader, BufRead};
45use std::path::Path;
46use std::str::FromStr;
47
48macro_rules! err_invalid_data {
49 ($fmt:expr, $($v:ident),*) => (
50 Err(invalid_data(format!($fmt, $($v),*)))
51 )
52}
53
54#[derive(Default, Debug)]
56pub struct Instance {
57 pub name: String,
58 pub type_: Option<Type>,
59 pub comment: Vec<String>,
60 pub dimension: usize,
61 pub capacity: usize,
62 pub edge_data: Option<EdgeData>,
63 pub edge_weight: Option<EdgeWeight>,
64 pub edge_weight_type: Option<EdgeWeightType>,
65 pub fixed_edges: Option<Vec<(usize, usize)>>,
66 pub node_coord: Option<NodeCoord>,
67 pub display_data: Option<Vec<(usize, f64, f64)>>,
68 pub display_data_type: Option<DisplayDataType>,
69 pub tour: Option<Vec<usize>>,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
73pub enum EdgeData {
74 EdgeList(Vec<(usize, usize)>),
75 AdjList(Vec<Vec<usize>>),
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
80pub enum Type {
81 Tsp,
82 Atsp,
83 Sop,
84 Hcp,
85 Cvrp,
86 Tour,
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
90pub enum EdgeWeightType {
91 Explicit,
92 Euc2d,
93 Euc3d,
94 Max2d,
95 Max3d,
96 Man2d,
97 Man3d,
98 Ceil2d,
99 Geo,
100 Att,
101 Xray1,
102 Xray2,
103 Special,
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
107pub enum EdgeWeight {
108 Function,
109 FullMatrix(Vec<usize>),
110 UpperRow(Vec<usize>),
111 LowerRow(Vec<usize>),
112 UpperDiagRow(Vec<usize>),
113 LowerDiagRow(Vec<usize>),
114 UpperCol(Vec<usize>),
115 LowerCol(Vec<usize>),
116 UpperDiagCol(Vec<usize>),
117 LowerDiagCol(Vec<usize>),
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
121pub enum DisplayDataType {
122 Coord,
123 TwoD,
124}
125
126#[derive(Debug, Clone, PartialEq, PartialOrd)]
127pub enum NodeCoord {
128 Two(Vec<(usize, f32, f32)>),
129 Three(Vec<(usize, f32, f32, f32)>),
130}
131
132pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Instance> {
144 parse(BufReader::new(File::open(path)?))
145}
146
147pub fn parse<R: BufRead>(mut reader: R) -> io::Result<Instance> {
153 let mut instance = Instance::default();
154 let mut line = String::new();
155 let mut keyword = String::new();
156 let mut value = String::new();
157
158 while reader.read_line(&mut line)? != 0 && line.trim() != EOF {
159 let r = {
160 let s = line.trim();
161 s.is_empty() || s == "-1"
162 };
163 if r {
164 line.clear();
165 continue;
166 }
167 let (keyword, value) = {
168 let (k, v) = split_colon(&line);
169 keyword.clear();
170 keyword.push_str(k);
171 value.clear();
172 value.push_str(v);
173 (keyword.as_str(), value.as_str())
174 };
175 match keyword {
176 NAME => {
177 instance.name = value.into();
178 }
179 COMMENT => {
180 instance.comment.push(value.into());
181 }
182 TYPE => {
183 instance.set_type(value)?;
184 }
185 DIMENSION => {
186 instance.dimension = parse_value(value)?;
187 }
188 CAPACITY => {
189 instance.capacity = parse_value(value)?;
190 }
191 EDGE_WEIGHT_TYPE => {
192 instance.set_edge_weight_type(value)?;
193 }
194 EDGE_WEIGHT_FORMAT => instance.set_edge_weight_format(value)?,
195 EDGE_DATA_FORMAT => {
196 instance.set_edge_data_format(value)?;
197 }
198 DISPLAY_DATA_TYPE => {
199 instance.set_display_data_type(value)?;
200 }
201 NODE_COORD_TYPE => instance.set_node_coord_type(value)?,
202 EDGE_DATA_SECTION => {
203 parse_edge_data_section(&mut instance, &mut reader)?;
204 }
205 NODE_COORD_SECTION => {
206 parse_node_coord_section(&mut instance, &mut reader)?;
207 }
208 EDGE_WEIGHT_SECTION => {
209 parse_edge_weight_section(&mut instance, &mut reader)?;
210 }
211 DISPLAY_DATA_SECTION => {
212 parse_display_data_section(&mut instance, &mut reader)?;
213 }
214 FIXED_EDGES_SECTION => {
215 parse_fixed_edges_section(&mut instance, &mut reader)?;
216 }
217 TOUR_SECTION => {
218 parse_tour_section(&mut instance, &mut reader)?;
219 }
220 DEPOT_SECTION | DEMAND_SECTION => {
221 return err_invalid_data!("not implemented: {}", keyword)
222 }
223 _ => return err_invalid_data!("invalid keyword: {}", keyword),
224 }
225 line.clear();
226 }
227
228 Ok(instance)
229}
230
231impl Instance {
232 fn num_edges(&self) -> Option<usize> {
233 let m = if let Some(ref edge_data) = self.edge_data {
234 use EdgeData::*;
235 match *edge_data {
236 EdgeList(ref v) => v.len(),
237 AdjList(ref v) => v.iter().map(Vec::len).sum::<usize>() - v.len(),
238 }
239 } else if let Some(ref edge_weight) = self.edge_weight {
240 use EdgeWeight::*;
241 let n = self.dimension;
242 match *edge_weight {
243 FullMatrix(_) => n * n,
244 UpperRow(_) | LowerRow(_) | UpperCol(_) | LowerCol(_) => (n * n - n) / 2,
245 UpperDiagRow(_) | LowerDiagRow(_) | UpperDiagCol(_) | LowerDiagCol(_) => {
246 (n * n + n) / 2
247 }
248 _ => return None,
249 }
250 } else {
251 return None;
252 };
253 Some(m)
254 }
255
256 fn set_type(&mut self, value: &str) -> io::Result<()> {
257 use Type::*;
258 let type_ = match value {
259 ATSP => Atsp,
260 CVRP => Cvrp,
261 HCP => Hcp,
262 SOP => Sop,
263 TOUR => Tour,
264 TSP | "TSP (M.~Hofmeister)" => Tsp,
265 _ => return err_invalid_data!("invalid TYPE: {}", value),
266 };
267 self.type_ = Some(type_);
268 Ok(())
269 }
270
271 fn set_edge_weight_type(&mut self, value: &str) -> io::Result<()> {
272 use EdgeWeightType::*;
273 let edge_weight_type = match value {
274 EXPLICIT => Explicit,
275 EUC_2D => Euc2d,
276 EUC_3D => Euc3d,
277 MAX_2D => Max2d,
278 MAX_3D => Max3d,
279 MAN_2D => Man2d,
280 MAN_3D => Man3d,
281 CEIL_2D => Ceil2d,
282 GEO => Geo,
283 ATT => Att,
284 XRAY1 => Xray1,
285 XRAY2 => Xray2,
286 SPECIAL => Special,
287 _ => return err_invalid_data!("invalid EDGE_WEIGHT_TYPE: {}", value),
288 };
289 self.edge_weight_type = Some(edge_weight_type);
290 self.node_coord = match value {
291 EXPLICIT => None,
292 EUC_2D | MAX_2D | MAN_2D | CEIL_2D | GEO | ATT => Some(NodeCoord::Two(vec![])),
293 EUC_3D | MAX_3D | MAN_3D => Some(NodeCoord::Three(vec![])),
294 XRAY1 | XRAY2 | SPECIAL => return err_invalid_data!("not implemented: {}", value),
295 _ => return err_invalid_data!("invalid EDGE_WEIGHT_TYPE: {}", value),
296 };
297 Ok(())
298 }
299
300 fn set_edge_weight_format(&mut self, value: &str) -> io::Result<()> {
301 use EdgeWeight::*;
302 let v = vec![];
303 let edge_weight = match value {
304 FUNCTION => Function,
305 FULL_MATRIX => FullMatrix(v),
306 UPPER_ROW => UpperRow(v),
307 LOWER_ROW => LowerRow(v),
308 UPPER_DIAG_ROW => UpperDiagRow(v),
309 LOWER_DIAG_ROW => LowerDiagRow(v),
310 UPPER_COL => UpperCol(v),
311 LOWER_COL => LowerCol(v),
312 UPPER_DIAG_COL => UpperDiagCol(v),
313 LOWER_DIAG_COL => LowerDiagCol(v),
314 _ => return err_invalid_data!("invalid EDGE_WEIGHT_FORMAT: {}", value),
315 };
316 self.edge_weight = Some(edge_weight);
317 Ok(())
318 }
319
320 fn set_edge_data_format(&mut self, value: &str) -> io::Result<()> {
321 use EdgeData::*;
322 let edge_data = match value {
323 EDGE_LIST => EdgeList(vec![]),
324 ADJ_LIST => AdjList(vec![]),
325 _ => return err_invalid_data!("invalid EDGE_DATA_FORMAT: {}", value),
326 };
327 self.edge_data = Some(edge_data);
328 Ok(())
329 }
330
331 fn set_display_data_type(&mut self, value: &str) -> io::Result<()> {
332 use DisplayDataType::*;
333 self.display_data_type = match value {
334 COORD_DISPLAY => Some(Coord),
335 TWOD_DISPLAY => Some(TwoD),
336 NO_DISPLAY => None,
337 _ => return err_invalid_data!("invalid DISPLAY_DATA_TYPE: {}", value),
338 };
339 Ok(())
340 }
341
342 fn set_node_coord_type(&mut self, value: &str) -> io::Result<()> {
343 use NodeCoord::*;
344 self.node_coord = match value {
345 TWOD_COORDS => Some(Two(vec![])),
346 THREED_COORDS => Some(Three(vec![])),
347 NO_COORDS => None,
348 _ => return err_invalid_data!("invalid NODE_COORD_TYPE: {}", value),
349 };
350 Ok(())
351 }
352}
353
354
355fn parse_edge_data_section<R: BufRead>(instance: &mut Instance, reader: &mut R) -> io::Result<()> {
356 use EdgeData::*;
357 match instance.edge_data {
358 Some(EdgeList(ref mut v)) => {
359 parse_vec(reader, v)?;
360 }
361 Some(AdjList(ref mut v)) => {
362 parse_vecs(reader, v)?;
363 }
364 None => return Err(invalid_data("EDGE_DATA_SECTION without EDGE_DATA_FORMAT")),
365 }
366 Ok(())
367}
368
369fn parse_edge_weight_section<R: BufRead>(instance: &mut Instance,
370 reader: &mut R)
371 -> io::Result<()> {
372 use EdgeWeight::*;
373 let num_edges = instance.num_edges();
374 match instance.edge_weight {
375 Some(Function) => {
376 panic!();
377 }
378 Some(FullMatrix(ref mut v)) |
379 Some(UpperRow(ref mut v)) |
380 Some(LowerRow(ref mut v)) |
381 Some(UpperDiagRow(ref mut v)) |
382 Some(LowerDiagRow(ref mut v)) |
383 Some(UpperCol(ref mut v)) |
384 Some(LowerCol(ref mut v)) |
385 Some(UpperDiagCol(ref mut v)) |
386 Some(LowerDiagCol(ref mut v)) => parse_all(reader, v, num_edges)?,
387 None => return Err(invalid_data("EDGE_WEIGHT_FORMAT without EDGE_WEIGHT_SECTION")),
388 }
389 Ok(())
390}
391
392fn parse_node_coord_section<R: BufRead>(instance: &mut Instance, reader: &mut R) -> io::Result<()> {
393 use NodeCoord::*;
394 match instance.node_coord {
395 Some(Two(ref mut v)) => {
396 parse_vec(reader, v)?;
397 }
398 Some(Three(ref mut v)) => {
399 parse_vec(reader, v)?;
400 }
401 None => return Err(invalid_data("EDGE_DATA_SECTION without EDGE_DATA_FORMAT")),
402 }
403 Ok(())
404}
405
406fn parse_display_data_section<R: BufRead>(instance: &mut Instance,
407 reader: &mut R)
408 -> io::Result<()> {
409 if let Some(DisplayDataType::TwoD) = instance.display_data_type {
410 let mut v = vec![];
411 parse_vec(reader, &mut v)?;
412 instance.display_data = Some(v);
413 } else {
414 return Err(invalid_data("DISPLAY_DATA_SECTION without EDGE_DATA_TYPE : TWOD_DISPLAY"));
415 }
416 Ok(())
417}
418
419fn parse_fixed_edges_section<R: BufRead>(instance: &mut Instance,
420 reader: &mut R)
421 -> io::Result<()> {
422 let mut v = vec![];
423 parse_vec(reader, &mut v)?;
424 instance.fixed_edges = Some(v);
425 Ok(())
426}
427
428fn parse_tour_section<R: BufRead>(instance: &mut Instance, reader: &mut R) -> io::Result<()> {
429 let mut v = vec![];
430 let num = if instance.dimension == 0 {
431 None
432 } else {
433 Some(instance.dimension)
434 };
435 parse_all(reader, &mut v, num)?;
436 instance.tour = Some(v);
437 Ok(())
438}
439
440fn parse_value<T>(s: &str) -> io::Result<T>
441 where T: FromStr,
442 T::Err: Into<Box<Error + Send + Sync>>
443{
444 s.parse().map_err(invalid_data)
445}
446
447fn parse_vec<T, R: BufRead>(reader: &mut R, v: &mut Vec<T>) -> io::Result<()>
448 where T: MyFromStr
449{
450 let mut line = String::new();
451 while reader.read_line(&mut line)? != 0 && !is_eof(&line) {
452 match MyFromStr::from_str(&line) {
453 Ok(a) => {
454 v.push(a);
455 }
456 Err(a) => {
457 return Err(invalid_data(a));
458 }
459 }
460 line.clear();
461 }
462 Ok(())
463}
464
465fn parse_all<T, R: BufRead>(reader: &mut R, v: &mut Vec<T>, num: Option<usize>) -> io::Result<()>
466 where T: FromStr + Copy,
467 T::Err: Into<Box<Error + Send + Sync>>
468{
469 let mut line = String::new();
470 while Some(v.len()) != num && reader.read_line(&mut line)? != 0 && !is_eof(&line) {
471 let values: Result<Vec<T>, _> = line.split_whitespace().map(|s| s.parse::<T>()).collect();
472 v.extend(values.map_err(invalid_data)?);
473 line.clear();
474 }
475 if let Some(num) = num {
476 if v.len() < num {
477 return Err(invalid_data("too few values"));
478 } else if v.len() > num {
479 return Err(invalid_data("too many values"));
480 }
481 }
482 Ok(())
483}
484
485fn parse_vecs<T, R: BufRead>(reader: &mut R, v: &mut Vec<Vec<T>>) -> io::Result<()>
486 where T: FromStr + Copy,
487 T::Err: Into<Box<Error + Send + Sync>>
488{
489 let mut line = String::new();
490 while reader.read_line(&mut line)? != 0 && !is_eof(&line) {
491 let values: Result<Vec<T>, _> = line.split_whitespace().map(|s| s.parse::<T>()).collect();
492 v.push(values.map_err(invalid_data)?);
493 line.clear();
494 }
495 Ok(())
496}
497
498fn is_eof(s: &str) -> bool {
499 let s = s.trim();
500 s.is_empty() || s == "-1" || s == EOF
501}
502
503fn split_colon(line: &str) -> (&str, &str) {
504 if let Some(p) = line.find(':') {
505 (line[..p].trim(), line[p + 1..].trim())
506 } else {
507 (line.trim(), &line[..0])
508 }
509}
510
511fn invalid_data<E>(error: E) -> io::Error
512 where E: Into<Box<Error + Send + Sync>>
513{
514 io::Error::new(io::ErrorKind::InvalidData, error)
515}
516
517trait MyFromStr: Sized {
518 fn from_str(s: &str) -> Result<Self, Box<Error + Send + Sync>>;
519}
520
521macro_rules! impl_from_str {
522 ($($T:ident),*) => (
523 impl<$($T),*> MyFromStr for ($($T),*)
524 where $($T: FromStr, $T::Err: Into<Box<Error + Send + Sync>>),*
525 {
526 #[allow(non_snake_case)]
527 fn from_str(s: &str) -> Result<Self, Box<Error + Send + Sync>> {
528 let mut iter = s.split_whitespace();
529 $(
530 let $T;
531 if let Some(x) = iter.next() {
532 $T = x.parse().map_err(invalid_data)?;
533 } else {
534 return Err(format!("too few values: {}", s).into());
535 }
536 )*
537
538 if iter.next().is_some() {
539 return Err(format!("too many values: {}", s).into());
540 }
541
542 Ok(($($T),*))
543 }
544 }
545 )
546}
547
548impl_from_str!(A, B);
549impl_from_str!(A, B, C);
550impl_from_str!(A, B, C, D);
551
552macro_rules! def_str_consts {
553 ($($name:ident),*) => (
554 $(const $name: &str = stringify!($name);)*
555 )
556}
557
558def_str_consts! {
559 NAME,
560 COMMENT,
561 TYPE,
562 TSP, ATSP, SOP, HCP, CVRP, TOUR,
563 DIMENSION,
564 CAPACITY,
565 EDGE_WEIGHT_TYPE,
566 EXPLICIT, EUC_2D, EUC_3D, MAX_2D, MAX_3D, MAN_2D, MAN_3D, CEIL_2D, GEO, ATT, XRAY1, XRAY2,
567 SPECIAL,
568 EDGE_WEIGHT_FORMAT,
569 FUNCTION, FULL_MATRIX, UPPER_ROW, LOWER_ROW, UPPER_DIAG_ROW, LOWER_DIAG_ROW, UPPER_COL,
570 LOWER_COL, UPPER_DIAG_COL, LOWER_DIAG_COL,
571 EDGE_DATA_FORMAT,
572 EDGE_LIST, ADJ_LIST,
573 NODE_COORD_TYPE,
574 TWOD_COORDS, THREED_COORDS, NO_COORDS,
575 DISPLAY_DATA_TYPE,
576 COORD_DISPLAY, TWOD_DISPLAY, NO_DISPLAY,
577 DEMAND_SECTION,
578 DEPOT_SECTION,
579 DISPLAY_DATA_SECTION,
580 EDGE_DATA_SECTION,
581 EDGE_WEIGHT_SECTION,
582 FIXED_EDGES_SECTION,
583 NODE_COORD_SECTION,
584 TOUR_SECTION,
585 EOF
586}