Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.0/sources/HeuristicLab.Routing.TSP/TSPParser.cs @ 16300

Last change on this file since 16300 was 2, checked in by swagner, 17 years ago

Added HeuristicLab 3.0 sources from former SVN repository at revision 52

File size: 6.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.IO;
26using System.Globalization;
27
28namespace HeuristicLab.Routing.TSP {
29  public class TSPParser {
30    private const int EOF = 0;
31    private const int NAME = 1;
32    private const int TYPE = 2;
33    private const int DIM = 3;
34    private const int WEIGHTTYPE = 4;
35    private const int NODETYPE = 5;
36    private const int NODESECTION = 6;
37
38    private StreamReader source;
39
40    private string myName;
41    public string Name {
42      get { return myName; }
43    }
44    private double[,] myVertices;
45    public double[,] Vertices {
46      get { return myVertices; }
47    }
48    private int myWeightType;
49    public int WeightType {
50      get { return myWeightType; }
51    }
52
53    public TSPParser(String path) {
54      if (!path.EndsWith(".tsp"))
55        throw new ArgumentException("Input file name has to be in TSP format (*.tsp)");
56
57      source = new StreamReader(path);
58      myName = path;
59      myVertices = null;
60      myWeightType = -1;
61    }
62
63    public void Parse() {
64      int section = -1;
65      string str = null;
66      bool typeIsChecked = false;
67      bool weightTypeIsChecked = false;
68
69      do {
70        str = source.ReadLine();
71        section = GetSection(str);
72
73        if (section != -1) {
74          switch (section) {
75            case NAME:
76              ReadName(str);
77              break;
78            case TYPE:
79              CheckType(str);
80              typeIsChecked = true;
81              break;
82            case DIM:
83              InitVerticesArray(str);
84              break;
85            case WEIGHTTYPE:
86              ReadWeightType(str);
87              weightTypeIsChecked = true;
88              break;
89            case NODETYPE:
90              CheckNodeType(str);
91              break;
92            case NODESECTION:
93              ReadVertices();
94              break;
95          }
96        }
97      } while (!((section == EOF) || (str == null)));
98
99      if (!(typeIsChecked && weightTypeIsChecked))
100        throw new InvalidDataException("File contains unknown (edge) types");
101    }
102
103    private int GetSection(string str) {
104      if (str == null)
105        return EOF;
106
107      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
108      if (tokens.Length == 0)
109        return -1;
110
111      string token = tokens[0].Trim();
112      if (token.Equals("eof", StringComparison.OrdinalIgnoreCase))
113        return EOF;
114      if (token.Equals("name", StringComparison.OrdinalIgnoreCase))
115        return NAME;
116      if (token.Equals("type", StringComparison.OrdinalIgnoreCase))
117        return TYPE;
118      if (token.Equals("dimension", StringComparison.OrdinalIgnoreCase))
119        return DIM;
120      if (token.Equals("edge_weight_type", StringComparison.OrdinalIgnoreCase))
121        return WEIGHTTYPE;
122      if (token.Equals("node_coord_type", StringComparison.OrdinalIgnoreCase))
123        return NODETYPE;
124      if (token.Equals("node_coord_section", StringComparison.OrdinalIgnoreCase))
125        return NODESECTION;
126
127      return -1;
128    }
129
130    private void ReadName(string str) {
131      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
132      myName = tokens[tokens.Length - 1].Trim();
133    }
134
135    private void CheckType(string str) {
136      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
137
138      string type = tokens[tokens.Length - 1].Trim();
139      if (!type.Equals("tsp", StringComparison.OrdinalIgnoreCase))
140        throw new InvalidDataException("Input data format is not \"TSP\"");
141    }
142
143    private void InitVerticesArray(string str) {
144      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
145      string dimension = tokens[tokens.Length - 1].Trim();
146
147      int dim = Int32.Parse(dimension);
148      myVertices = new double[dim, 2];
149    }
150
151    private void ReadWeightType(string str) {
152      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
153      string type = tokens[tokens.Length - 1].Trim();
154
155      if (type.Equals("euc_2d", StringComparison.OrdinalIgnoreCase))
156        myWeightType = 0;
157      else if (type.Equals("geo", StringComparison.OrdinalIgnoreCase))
158        myWeightType = 1;
159      else
160        throw new InvalidDataException("Unsupported type of edge weights");
161    }
162
163    private void CheckNodeType(string str) {
164      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
165      string type = tokens[tokens.Length - 1].Trim();
166
167      if (!type.Equals("twod_coords", StringComparison.OrdinalIgnoreCase))
168        throw new InvalidDataException("Unsupported node type");
169    }
170
171    private void ReadVertices() {
172      if (myVertices == null)
173        throw new InvalidDataException("Dimension not found");
174
175      for (int i = 0; i < (myVertices.Length / 2); i++) {
176        string str = source.ReadLine();
177        string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
178
179        if (tokens.Length != 3)
180          throw new InvalidDataException("Invalid node format");
181
182        CultureInfo culture = new CultureInfo("en-US");
183        myVertices[i, 0] = Double.Parse(tokens[1], culture.NumberFormat);
184        myVertices[i, 1] = Double.Parse(tokens[2], culture.NumberFormat);
185      }
186    }
187  }
188}
Note: See TracBrowser for help on using the repository browser.