Changeset 7465
- Timestamp:
- 02/10/12 23:11:59 (13 years ago)
- Location:
- branches/GeneralizedQAP
- Files:
-
- 195 added
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/GeneralizedQAP/GeneralizedQAP.sln
r7444 r7465 24 24 EndProject 25 25 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.Instances.ElloumiCTAP-3.3", "HeuristicLab.Problems.Instances.ElloumiCTAP\3.3\HeuristicLab.Problems.Instances.ElloumiCTAP-3.3.csproj", "{CCF61DA0-B226-4C0F-8052-29ACC6BDE6EE}" 26 EndProject 27 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.Instances.TSPLIB-3.3", "HeuristicLab.Problems.Instances.TSPLIB\3.3\HeuristicLab.Problems.Instances.TSPLIB-3.3.csproj", "{CE0F99D6-1C56-48A9-9B68-3E5B833703EF}" 26 28 EndProject 27 29 Global … … 102 104 {CCF61DA0-B226-4C0F-8052-29ACC6BDE6EE}.Release|x64.ActiveCfg = Release|Any CPU 103 105 {CCF61DA0-B226-4C0F-8052-29ACC6BDE6EE}.Release|x86.ActiveCfg = Release|Any CPU 106 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 107 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Debug|Any CPU.Build.0 = Debug|Any CPU 108 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Debug|x64.ActiveCfg = Debug|Any CPU 109 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Debug|x86.ActiveCfg = Debug|Any CPU 110 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Release|Any CPU.ActiveCfg = Release|Any CPU 111 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Release|Any CPU.Build.0 = Release|Any CPU 112 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Release|x64.ActiveCfg = Release|Any CPU 113 {CE0F99D6-1C56-48A9-9B68-3E5B833703EF}.Release|x86.ActiveCfg = Release|Any CPU 104 114 EndGlobalSection 105 115 GlobalSection(SolutionProperties) = preSolution -
branches/GeneralizedQAP/HeuristicLab.Problems.Instances.TSPLIB/3.3/TSPLIBParser.cs
r7453 r7465 21 21 22 22 using System; 23 using System.Collections.Generic; 23 24 using System.Globalization; 24 25 using System.IO; 25 26 namespace HeuristicLab.Problems.TravelingSalesman { 27 /// <summary> 28 /// Parses a *.tsp file in TSPLIB format and extracts its information about a TSP. 29 /// </summary> 26 using System.Linq; 27 28 namespace HeuristicLab.Problems.Instances.TSPLIB { 29 30 #region Public Enums 31 public enum TSPLIBTypes { 32 UNKNOWN = 0, 33 TSP = 1, 34 ATSP = 2, 35 SOP = 3, 36 HCP = 4, 37 CVRP = 5, 38 TOUR = 6 39 } 40 41 public enum TSPLIBEdgeWeightTypes { 42 UNKNOWN = 0, 43 EXPLICIT = 1, 44 EUC_2D = 2, 45 EUC_3D = 3, 46 MAX_2D = 4, 47 MAX_3D = 5, 48 MAN_2D = 6, 49 MAN_3D = 7, 50 CEIL_2D = 8, 51 GEO = 9, 52 ATT = 10, 53 XRAY1 = 11, 54 XRAY2 = 12, 55 SPECIAL = 13 56 } 57 58 public enum TSPLIBDisplayDataTypes { 59 UNKNOWN = 0, 60 COORD_DISPLAY = 1, 61 TWOD_DISPLAY = 2, 62 NO_DISPLAY = 3 63 } 64 #endregion 65 30 66 public class TSPLIBParser { 31 #region Inner Enum TSPLIBEdgeWeightType 32 public enum TSPLIBEdgeWeightType { 33 UNDEFINED, 34 EUC_2D, 35 GEO 67 68 public string Name { get; private set; } 69 public TSPLIBTypes Type { get; private set; } 70 public string Comment { get; private set; } 71 public int Dimension { get; private set; } 72 public double? Capacity { get; private set; } 73 public TSPLIBEdgeWeightTypes EdgeWeightType { get; private set; } 74 public TSPLIBDisplayDataTypes DisplayDataType { get; private set; } 75 public double[,] Vertices { get; private set; } 76 public double[,] DisplayVertices { get; private set; } 77 public double[,] Distances { get; private set; } 78 public int[,] FixedEdges { get; private set; } 79 public int[] Depots { get; private set; } 80 public double[] Demands { get; private set; } 81 public int[][] Tour { get; private set; } 82 83 private static readonly char sectionSeparator = ':'; 84 private static readonly char[] itemSeparator = new char[] { ' ', '\t' }; 85 86 #region Private Enums 87 private enum TSPLIBSections { 88 UNKNOWN = 0, 89 EOF = 1, 90 NAME = 2, 91 TYPE = 3, 92 COMMENT = 4, 93 DIMENSION = 5, 94 CAPACITY = 6, 95 EDGE_WEIGHT_TYPE = 7, 96 EDGE_WEIGHT_FORMAT = 8, 97 EDGE_DATA_FORMAT = 9, 98 NODE_COORD_TYPE = 10, 99 DISPLAY_DATA_TYPE = 11, 100 NODE_COORD_SECTION = 12, 101 DEPOT_SECTION = 13, 102 DEMAND_SECTION = 14, 103 EDGE_DATA_SECTION = 15, 104 FIXED_EDGES_SECTION = 16, 105 DISPLAY_DATA_SECTION = 17, 106 TOUR_SECTION = 18, 107 EDGE_WEIGHT_SECTION = 19 108 } 109 private enum TSPLIBEdgeWeightFormats { 110 UNKNWON = 0, 111 FUNCTION = 1, 112 FULL_MATRIX = 2, 113 UPPER_ROW = 3, 114 LOWER_ROW = 4, 115 UPPER_DIAG_ROW = 5, 116 LOWER_DIAG_ROW = 6, 117 UPPER_COL = 7, 118 LOWER_COL = 8, 119 UPPER_DIAG_COL = 9, 120 LOWER_DIAG_COL = 10 121 } 122 private enum TSPLIBEdgeWeightDataFormats { 123 UNKNOWN = 0, 124 EDGE_LIST = 1, 125 ADJ_LIST = 2 126 } 127 private enum TSLPLIBNodeCoordTypes { 128 UNKNOWN = 0, 129 TWOD_COORDS = 1, 130 THREED_COORDS = 2, 131 NO_COORDS = 3 36 132 } 37 133 #endregion 38 134 39 private const int EOF = 0;40 private const int NAME = 1;41 private const int TYPE = 2;42 private const int COMMENT = 3;43 private const int DIM = 4;44 private const int WEIGHTTYPE = 5;45 private const int NODETYPE = 6;46 private const int NODESECTION = 7;47 48 135 private StreamReader source; 49 50 private string name; 136 private int currentLineNumber; 137 138 private TSPLIBEdgeWeightFormats edgeWeightFormat; 139 private TSPLIBEdgeWeightDataFormats edgeWeightDataFormat; 140 private TSLPLIBNodeCoordTypes nodeCoordType; 141 private TSPLIBDisplayDataTypes displayDataType; 142 143 private TSPLIBParser() { 144 Name = String.Empty; 145 Comment = String.Empty; 146 Type = TSPLIBTypes.UNKNOWN; 147 EdgeWeightType = TSPLIBEdgeWeightTypes.UNKNOWN; 148 149 edgeWeightFormat = TSPLIBEdgeWeightFormats.UNKNWON; 150 edgeWeightDataFormat = TSPLIBEdgeWeightDataFormats.UNKNOWN; 151 nodeCoordType = TSLPLIBNodeCoordTypes.UNKNOWN; 152 displayDataType = TSPLIBDisplayDataTypes.UNKNOWN; 153 } 154 155 public TSPLIBParser(String path) 156 : this() { 157 source = new StreamReader(path); 158 } 159 160 public TSPLIBParser(Stream stream) 161 : this() { 162 source = new StreamReader(stream); 163 } 164 51 165 /// <summary> 52 /// Gets the name of the parsed TSP. 53 /// </summary> 54 public string Name { 55 get { return name; } 56 } 57 private string comment; 58 /// <summary> 59 /// Gets the comment of the parsed TSP. 60 /// </summary> 61 public string Comment { 62 get { return comment; } 63 } 64 private double[,] vertices; 65 /// <summary> 66 /// Gets the vertices of the parsed TSP. 67 /// </summary> 68 public double[,] Vertices { 69 get { return vertices; } 70 } 71 private TSPLIBEdgeWeightType weightType; 72 /// <summary> 73 /// Gets the weight type of the parsed TSP. 74 /// </summary> 75 public TSPLIBEdgeWeightType WeightType { 76 get { return weightType; } 77 } 78 79 /// <summary> 80 /// Initializes a new instance of <see cref="TSPLIBParser"/> with the given <paramref name="path"/>. 81 /// </summary> 82 /// <exception cref="ArgumentException">Thrown if the input file is not a TSPLIB TSP file (*.tsp) 83 /// </exception> 84 /// <param name="path">The path where the TSP is stored.</param> 85 public TSPLIBParser(String path) { 86 if (!path.EndsWith(".tsp")) 87 throw new ArgumentException("Input file has to be a TSPLIB TSP file (*.tsp)."); 88 89 source = new StreamReader(path); 90 name = path; 91 comment = string.Empty; 92 vertices = null; 93 weightType = TSPLIBEdgeWeightType.UNDEFINED; 94 } 95 96 /// <summary> 97 /// Reads the TSPLIB TSP file and parses the elements. 166 /// Reads the TSPLIB file and parses the elements. 98 167 /// </summary> 99 168 /// <exception cref="InvalidDataException">Thrown if the file has an invalid format or contains invalid data.</exception> 100 169 public void Parse() { 101 int section = -1; 102 string str = null; 103 bool typeIsChecked = false; 104 bool weightTypeIsChecked = false; 105 170 TSPLIBSections section; 171 string line; 172 currentLineNumber = 0; 173 174 try { 175 do { 176 line = NextLine(); 177 string value; 178 section = GetSection(line, out value); 179 180 switch (section) { 181 case TSPLIBSections.UNKNOWN: 182 break; 183 case TSPLIBSections.NAME: 184 ReadName(value); 185 break; 186 case TSPLIBSections.TYPE: 187 ReadType(value); 188 break; 189 case TSPLIBSections.COMMENT: 190 ReadComment(value); 191 break; 192 case TSPLIBSections.DIMENSION: 193 ReadDimension(value); 194 break; 195 case TSPLIBSections.CAPACITY: 196 ReadCapacity(value); 197 break; 198 case TSPLIBSections.EDGE_WEIGHT_TYPE: 199 ReadEdgeWeightType(value); 200 break; 201 case TSPLIBSections.EDGE_WEIGHT_FORMAT: 202 ReadEdgeWeightFormat(value); 203 break; 204 case TSPLIBSections.EDGE_DATA_FORMAT: 205 ReadEdgeWeightDataFormat(value); 206 break; 207 case TSPLIBSections.NODE_COORD_TYPE: 208 ReadNodeCoordType(value); 209 break; 210 case TSPLIBSections.DISPLAY_DATA_TYPE: 211 ReadDisplayDataType(value); 212 break; 213 case TSPLIBSections.NODE_COORD_SECTION: 214 ReadNodeCoordsSection(); 215 break; 216 case TSPLIBSections.DEPOT_SECTION: 217 ReadDepotSection(); 218 break; 219 case TSPLIBSections.DEMAND_SECTION: 220 ReadDemandSection(); 221 break; 222 case TSPLIBSections.EDGE_DATA_SECTION: 223 ReadEdgeDataSection(); 224 break; 225 case TSPLIBSections.FIXED_EDGES_SECTION: 226 ReadFixedEdgesSection(); 227 break; 228 case TSPLIBSections.DISPLAY_DATA_SECTION: 229 ReadDisplayDataSection(); 230 break; 231 case TSPLIBSections.TOUR_SECTION: 232 ReadTourSection(); 233 break; 234 case TSPLIBSections.EDGE_WEIGHT_SECTION: 235 ReadEdgeWeightSection(); 236 break; 237 case TSPLIBSections.EOF: 238 break; 239 default: 240 throw new InvalidDataException("Input file contains unknown or unsupported section (" + line + ") in line " + currentLineNumber.ToString()); 241 } 242 } while (!(section == TSPLIBSections.EOF || source.EndOfStream)); 243 } finally { 244 source.Close(); 245 } 246 } 247 248 private string NextLine() { 249 currentLineNumber++; 250 return source.ReadLine(); 251 } 252 253 private TSPLIBSections GetSection(string line, out string value) { 254 value = String.Empty; 255 256 if (line == null) 257 return TSPLIBSections.UNKNOWN; 258 259 int sectionNameEnd = line.IndexOf(sectionSeparator); 260 if (sectionNameEnd == -1) sectionNameEnd = line.Length; 261 262 string sectionName = line.Substring(0, sectionNameEnd).Trim(); 263 if (sectionNameEnd + 1 < line.Length) 264 value = line.Substring(sectionNameEnd + 1); 265 266 TSPLIBSections section; 267 if (Enum.TryParse(sectionName, out section)) { 268 return section; 269 } else return TSPLIBSections.UNKNOWN; 270 } 271 272 private void ReadName(string value) { 273 Name += value.Trim(); 274 } 275 276 private void ReadType(string value) { 277 TSPLIBTypes t; 278 if (Enum.TryParse(value.Trim().ToUpper(), out t)) 279 Type = t; 280 else Type = TSPLIBTypes.UNKNOWN; 281 } 282 283 private void ReadComment(string value) { 284 Comment += value.Trim() + Environment.NewLine; 285 } 286 287 private void ReadCapacity(string value) { 288 double c; 289 if (double.TryParse(value.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out c)) 290 Capacity = c; 291 else throw new InvalidDataException("Parsing the capacity in line " + currentLineNumber + " failed. It is not recognized as double value."); 292 } 293 294 private void ReadDimension(string value) { 295 int dimension; 296 if (int.TryParse(value.Trim(), out dimension)) 297 Dimension = dimension; 298 else throw new InvalidDataException("Parsing the dimension in line " + currentLineNumber + " failed. It is not recognized as an integer number."); 299 } 300 301 private void ReadEdgeWeightType(string value) { 302 TSPLIBEdgeWeightTypes e; 303 if (Enum.TryParse(value.Trim().ToUpper(), out e)) 304 EdgeWeightType = e; 305 else throw new InvalidDataException("Input file contains an unsupported edge weight type (" + value + ") in line " + currentLineNumber + "."); 306 } 307 308 private void ReadEdgeWeightFormat(string value) { 309 TSPLIBEdgeWeightFormats e; 310 if (Enum.TryParse(value.Trim().ToUpper(), out e)) 311 edgeWeightFormat = e; 312 else throw new InvalidDataException("Input file contains an unsupported edge weight format (" + value + ") in line " + currentLineNumber + "."); 313 } 314 315 private void ReadEdgeWeightDataFormat(string value) { 316 TSPLIBEdgeWeightDataFormats e; 317 if (Enum.TryParse(value.Trim().ToUpper(), out e)) 318 edgeWeightDataFormat = e; 319 else throw new InvalidDataException("Input file contains an unsupported edge weight data format (" + value + ") in line " + currentLineNumber + "."); 320 } 321 322 private void ReadNodeCoordType(string value) { 323 TSLPLIBNodeCoordTypes n; 324 if (Enum.TryParse(value.Trim().ToUpper(), out n)) 325 nodeCoordType = n; 326 else throw new InvalidDataException("Input file contains an unsupported node coordinates type (" + value + ") in line " + currentLineNumber + "."); 327 } 328 329 private void ReadDisplayDataType(string value) { 330 TSPLIBDisplayDataTypes d; 331 if (Enum.TryParse(value.Trim().ToUpper(), out d)) 332 displayDataType = d; 333 else throw new InvalidDataException("Input file contains an unsupported display data type (" + value + ") in line " + currentLineNumber + "."); 334 } 335 336 private void ReadNodeCoordsSection() { 337 if (Dimension == 0) 338 throw new InvalidDataException("Input file does not contain dimension information."); 339 switch (nodeCoordType) { 340 case TSLPLIBNodeCoordTypes.NO_COORDS: 341 return; 342 case TSLPLIBNodeCoordTypes.UNKNOWN: // It's a pity that there is a documented standard which is ignored in most files. 343 case TSLPLIBNodeCoordTypes.TWOD_COORDS: 344 Vertices = new double[Dimension, 2]; 345 break; 346 case TSLPLIBNodeCoordTypes.THREED_COORDS: 347 Vertices = new double[Dimension, 3]; 348 break; 349 default: 350 throw new InvalidDataException("Input files does not specify a valid node coord type."); 351 } 352 353 for (int i = 0; i < Dimension; i++) { 354 string line = NextLine(); 355 string[] tokens = line.Split(itemSeparator, StringSplitOptions.RemoveEmptyEntries); 356 357 if (tokens.Length != Vertices.GetLength(1) + 1) 358 throw new InvalidDataException("Input file contains invalid number of node coordinates in line " + currentLineNumber + "."); 359 360 int node; 361 if (int.TryParse(tokens[0], out node)) { 362 for (int j = 0; j < Vertices.GetLength(1); j++) 363 Vertices[node - 1, j] = double.Parse(tokens[j + 1], CultureInfo.InvariantCulture.NumberFormat); 364 } else throw new InvalidDataException("Input file does not specify a valid node in line " + currentLineNumber + "."); 365 } 366 } 367 368 private void ReadDepotSection() { 369 var depots = new List<int>(); 106 370 do { 107 str = source.ReadLine(); 108 section = GetSection(str); 109 110 if (section != -1) { 111 switch (section) { 112 case NAME: 113 ReadName(str); 114 break; 115 case TYPE: 116 CheckType(str); 117 typeIsChecked = true; 118 break; 119 case COMMENT: 120 ReadComment(str); 121 break; 122 case DIM: 123 InitVerticesArray(str); 124 break; 125 case WEIGHTTYPE: 126 ReadWeightType(str); 127 weightTypeIsChecked = true; 128 break; 129 case NODETYPE: 130 CheckNodeType(str); 131 break; 132 case NODESECTION: 133 ReadVertices(); 134 break; 371 string line = NextLine(); 372 int node; 373 if (!int.TryParse(line, out node)) 374 throw new InvalidDataException("Input file contains an unknown depot entry at line " + currentLineNumber + "."); 375 if (node == -1) break; 376 depots.Add(node); 377 } while (true); 378 Depots = depots.ToArray(); 379 } 380 381 private void ReadDemandSection() { 382 if (Dimension == 0) 383 throw new InvalidDataException("Input file does not contain dimension information."); 384 Demands = new double[Dimension]; 385 for (int i = 0; i < Dimension; i++) { 386 string[] tokens = NextLine().Split(itemSeparator, StringSplitOptions.RemoveEmptyEntries); 387 int node; 388 if (int.TryParse(tokens[0], out node)) { 389 double demand; 390 if (double.TryParse(tokens[1], NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out demand)) 391 Demands[node - 1] = demand; 392 else throw new InvalidDataException("Input file contains invalid demand information in line " + currentLineNumber + "."); 393 } else throw new InvalidDataException("Input file contains invalid node information in line " + currentLineNumber + "."); 394 } 395 } 396 397 private void ReadEdgeDataSection() { 398 throw new NotSupportedException("Files with an edge data section are not supported."); 399 } 400 401 private void ReadFixedEdgesSection() { 402 var edges = new List<Tuple<int, int>>(); 403 bool finished = false; 404 while (!finished) { 405 string line = NextLine(); 406 string[] tokens = line.Split(itemSeparator, StringSplitOptions.RemoveEmptyEntries); 407 if (tokens.Length == 1) { 408 int number; 409 if (!int.TryParse(tokens[0], NumberStyles.Integer, CultureInfo.InvariantCulture.NumberFormat, out number)) 410 throw new InvalidDataException("Input file does not end the fixed edges section with \"-1\" in line " + currentLineNumber + "."); 411 if (number != -1) 412 throw new InvalidDataException("Input file must end the fixed edges section with a -1 in line " + currentLineNumber + "."); 413 finished = true; 414 } else { 415 if (tokens.Length != 2) 416 throw new InvalidDataException("Input file contains an error in line " + currentLineNumber + ", exactly two nodes need to be given in each line."); 417 int node1 = int.Parse(tokens[0], CultureInfo.InvariantCulture.NumberFormat) - 1; 418 int node2 = int.Parse(tokens[1], CultureInfo.InvariantCulture.NumberFormat) - 1; 419 edges.Add(Tuple.Create(node1, node2)); 420 } 421 } 422 FixedEdges = new int[edges.Count, 2]; 423 for (int i = 0; i < edges.Count; i++) { 424 FixedEdges[i, 0] = edges[i].Item1; 425 FixedEdges[i, 1] = edges[i].Item2; 426 } 427 } 428 429 private void ReadDisplayDataSection() { 430 if (Dimension == 0) 431 throw new InvalidDataException("Input file does not contain dimension information."); 432 433 switch (displayDataType) { 434 case TSPLIBDisplayDataTypes.NO_DISPLAY: 435 case TSPLIBDisplayDataTypes.COORD_DISPLAY: 436 return; 437 case TSPLIBDisplayDataTypes.TWOD_DISPLAY: 438 DisplayVertices = new double[Dimension, 2]; 439 break; 440 default: 441 throw new InvalidDataException("Input files does not specify a valid node coord type."); 442 } 443 444 for (int i = 0; i < Dimension; i++) { 445 string line = NextLine(); 446 string[] tokens = line.Split(itemSeparator, StringSplitOptions.RemoveEmptyEntries); 447 448 if (tokens.Length != DisplayVertices.GetLength(1) + 1) 449 throw new InvalidDataException("Input file contains invalid number of display data coordinates in line " + currentLineNumber + "."); 450 451 int node; 452 if (int.TryParse(tokens[0], out node)) { 453 for (int j = 0; j < DisplayVertices.GetLength(1); j++) 454 DisplayVertices[node - 1, j] = double.Parse(tokens[j + 1], CultureInfo.InvariantCulture.NumberFormat); 455 } else throw new InvalidDataException("Input file does not specify a valid node in line " + currentLineNumber + "."); 456 } 457 } 458 459 /// <summary> 460 /// Parses the tour section. 461 /// </summary> 462 /// <remarks> 463 /// Unfortunately, none of the given files for the TSP follow the description 464 /// in the TSPLIB documentation. 465 /// The faulty files use only one -1 to terminate the section as well as the tour 466 /// whereas the documentation says that one -1 terminates the tour and another -1 467 /// terminates the section. 468 /// So the parser peeks at the next character after a -1. If the next character 469 /// is an E as in EOF or the stream ends, the parser breaks. Otherwise it will 470 /// continue to read tours until a -1 is followed by a -1. 471 /// </remarks> 472 private void ReadTourSection() { 473 if (Dimension == 0) 474 throw new InvalidDataException("Input file does not contain dimension information."); 475 476 var tours = new List<List<int>>(); 477 do { 478 string[] nodes = NextLine().Split(itemSeparator, StringSplitOptions.RemoveEmptyEntries); 479 if (!nodes.Any()) break; 480 481 bool finished = false; 482 foreach (var nodeString in nodes) { 483 int node = int.Parse(nodeString, CultureInfo.InvariantCulture.NumberFormat); 484 if (node == -1) { 485 finished = (tours.Any() && tours.Last().Count == 0) // -1 followed by -1 486 || (source.BaseStream.CanSeek && source.Peek() == -1) 487 || source.Peek() == (int)'E'; 488 if (finished) break; 489 tours.Add(new List<int>()); 490 } else { 491 if (!tours.Any()) tours.Add(new List<int>()); 492 tours.Last().Add(node - 1); 135 493 } 136 494 } 137 } while (!((section == EOF) || (str == null))); 138 139 if (!(typeIsChecked && weightTypeIsChecked)) 140 throw new InvalidDataException("Input file does not contain type or edge weight type information."); 141 } 142 143 private int GetSection(string str) { 144 if (str == null) 145 return EOF; 146 147 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 148 if (tokens.Length == 0) 149 return -1; 150 151 string token = tokens[0].Trim(); 152 if (token.Equals("eof", StringComparison.OrdinalIgnoreCase)) 153 return EOF; 154 if (token.Equals("name", StringComparison.OrdinalIgnoreCase)) 155 return NAME; 156 if (token.Equals("type", StringComparison.OrdinalIgnoreCase)) 157 return TYPE; 158 if (token.Equals("comment", StringComparison.OrdinalIgnoreCase)) 159 return COMMENT; 160 if (token.Equals("dimension", StringComparison.OrdinalIgnoreCase)) 161 return DIM; 162 if (token.Equals("edge_weight_type", StringComparison.OrdinalIgnoreCase)) 163 return WEIGHTTYPE; 164 if (token.Equals("node_coord_type", StringComparison.OrdinalIgnoreCase)) 165 return NODETYPE; 166 if (token.Equals("node_coord_section", StringComparison.OrdinalIgnoreCase)) 167 return NODESECTION; 168 169 return -1; 170 } 171 172 private void ReadName(string str) { 173 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 174 name = tokens[tokens.Length - 1].Trim(); 175 } 176 177 private void CheckType(string str) { 178 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 179 180 string type = tokens[tokens.Length - 1].Trim(); 181 if (!type.Equals("tsp", StringComparison.OrdinalIgnoreCase)) 182 throw new InvalidDataException("Input file type is not \"TSP\""); 183 } 184 185 private void ReadComment(string str) { 186 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 187 comment = tokens[tokens.Length - 1].Trim(); 188 } 189 190 private void InitVerticesArray(string str) { 191 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 192 string dimension = tokens[tokens.Length - 1].Trim(); 193 194 int dim = Int32.Parse(dimension); 195 vertices = new double[dim, 2]; 196 } 197 198 private void ReadWeightType(string str) { 199 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 200 string type = tokens[tokens.Length - 1].Trim(); 201 202 if (type.Equals("euc_2d", StringComparison.OrdinalIgnoreCase)) 203 weightType = TSPLIBEdgeWeightType.EUC_2D; 204 else if (type.Equals("geo", StringComparison.OrdinalIgnoreCase)) 205 weightType = TSPLIBEdgeWeightType.GEO; 206 else 207 throw new InvalidDataException("Input file contains an unsupported edge weight type (only \"EUC_2D\" and \"GEO\" are supported)."); 208 } 209 210 private void CheckNodeType(string str) { 211 string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None); 212 string type = tokens[tokens.Length - 1].Trim(); 213 214 if (!type.Equals("twod_coords", StringComparison.OrdinalIgnoreCase)) 215 throw new InvalidDataException("Input file contains an unsupported node coordinates type (only \"TWOD_COORDS\" is supported)."); 216 } 217 218 private void ReadVertices() { 219 if (vertices == null) 495 if (finished) break; 496 } while (true); 497 if (tours.Last().Count == 0) tours.RemoveAt(tours.Count - 1); 498 Tour = tours.Select(x => x.ToArray()).ToArray(); 499 } 500 501 private void ReadEdgeWeightSection() { 502 if (Dimension == 0) 220 503 throw new InvalidDataException("Input file does not contain dimension information."); 221 504 222 for (int i = 0; i < (vertices.Length / 2); i++) { 223 string str = source.ReadLine(); 224 string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 225 226 if (tokens.Length != 3) 227 throw new InvalidDataException("Input file contains invalid node coordinates."); 228 229 CultureInfo culture = new CultureInfo("en-US"); 230 vertices[i, 0] = double.Parse(tokens[1], culture.NumberFormat); 231 vertices[i, 1] = double.Parse(tokens[2], culture.NumberFormat); 232 } 233 } 505 if (edgeWeightFormat == TSPLIBEdgeWeightFormats.UNKNWON) 506 throw new InvalidDataException("Input file does not specify an edge weight format."); 507 508 if (edgeWeightFormat == TSPLIBEdgeWeightFormats.FUNCTION) 509 return; 510 511 Distances = new double[Dimension, Dimension]; 512 513 bool triangular = edgeWeightFormat != TSPLIBEdgeWeightFormats.FULL_MATRIX; 514 bool upperTriangular = edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_COL 515 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_DIAG_COL 516 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_DIAG_ROW 517 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_ROW; 518 bool diagonal = edgeWeightFormat == TSPLIBEdgeWeightFormats.LOWER_DIAG_COL 519 || edgeWeightFormat == TSPLIBEdgeWeightFormats.LOWER_DIAG_ROW 520 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_DIAG_COL 521 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_DIAG_ROW; 522 bool rowWise = edgeWeightFormat == TSPLIBEdgeWeightFormats.LOWER_DIAG_ROW 523 || edgeWeightFormat == TSPLIBEdgeWeightFormats.LOWER_ROW 524 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_DIAG_ROW 525 || edgeWeightFormat == TSPLIBEdgeWeightFormats.UPPER_ROW; 526 527 int dim1 = !upperTriangular ? (diagonal ? 0 : 1) : 0; 528 int dim2 = upperTriangular ? (diagonal ? 0 : 1) : 0; 529 bool finished = false; 530 while (!finished) { 531 string line = NextLine(); 532 string[] weights = line.Split(itemSeparator, StringSplitOptions.RemoveEmptyEntries); 533 foreach (var weightString in weights) { 534 double weight; 535 if (!double.TryParse(weightString, NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out weight)) 536 throw new InvalidDataException("Input file contains unreadable weight information (" + weightString + ") in line " + currentLineNumber + "."); 537 538 if (triangular) { 539 Distances[dim1, dim2] = weight; 540 Distances[dim2, dim1] = weight; 541 if (upperTriangular) { 542 if (rowWise) { 543 dim2++; 544 if (dim2 == Dimension) { 545 dim1++; 546 if (diagonal) dim2 = dim1; 547 else dim2 = dim1 + 1; 548 } 549 } else { // column-wise 550 dim1++; 551 if (diagonal && dim1 == dim2 + 1 552 || !diagonal && dim1 == dim2) { 553 dim2++; 554 dim1 = 0; 555 } 556 } 557 } else { // lower-triangular 558 if (rowWise) { 559 dim2++; 560 if (diagonal && dim2 == dim1 + 1 561 || !diagonal && dim2 == dim1) { 562 dim1++; 563 dim2 = 0; 564 } 565 } else { // column-wise 566 dim1++; 567 if (dim1 == Dimension) { 568 dim2++; 569 if (diagonal) dim1 = dim2; 570 else dim1 = dim2 + 1; 571 } 572 } 573 } 574 } else { // full-matrix 575 Distances[dim1, dim2] = weight; 576 dim2++; 577 if (dim2 == Dimension) { 578 dim1++; 579 dim2 = 0; 580 } 581 } 582 } 583 finished = dim1 == Dimension || dim2 == Dimension; 584 } 585 } 586 234 587 } 235 588 } -
branches/GeneralizedQAP/HeuristicLab.Problems.Instances/3.3/HeuristicLab.Problems.Instances-3.3.csproj
r7448 r7465 55 55 <Compile Include="IInstanceDescriptor.cs" /> 56 56 <Compile Include="Instances\IQAPInstance.cs" /> 57 <Compile Include="Instances\ITSPInstance.cs" /> 57 58 <Compile Include="IProblemInstanceConsumer.cs" /> 58 59 <Compile Include="IProblemInstanceProvider.cs" /> 59 60 <Compile Include="Plugin.cs" /> 61 <Compile Include="ProblemInstanceProvider.cs" /> 60 62 <Compile Include="Properties\AssemblyInfo.cs" /> 61 63 <None Include="Properties\AssemblyInfo.cs.frame" /> -
branches/GeneralizedQAP/HeuristicLab.Problems.Instances/3.3/Plugin.cs
r7448 r7465 23 23 24 24 namespace HeuristicLab.Problems.Instances { 25 [Plugin("HeuristicLab.Problems.Instances", "3.3.6.744 5")]25 [Plugin("HeuristicLab.Problems.Instances", "3.3.6.7448")] 26 26 [PluginFile("HeuristicLab.Problems.Instances-3.3.dll", PluginFileType.Assembly)] 27 27 public class HeuristicLabProblemsInstancesPlugin : PluginBase { -
branches/GeneralizedQAP/UnitTests/UnitTests.csproj
r7412 r7465 99 99 <Compile Include="GQAPNMoveEvaluatorTest.cs" /> 100 100 <Compile Include="Properties\AssemblyInfo.cs" /> 101 <Compile Include="TSPLIBInstanceProviderTest.cs" /> 101 102 </ItemGroup> 102 103 <ItemGroup> … … 108 109 <Project>{C739E6D2-5680-4804-A810-8017DA0C238F}</Project> 109 110 <Name>HeuristicLab.Problems.GeneralizedQuadraticAssignment-3.3</Name> 111 </ProjectReference> 112 <ProjectReference Include="..\HeuristicLab.Problems.Instances.TSPLIB\3.3\HeuristicLab.Problems.Instances.TSPLIB-3.3.csproj"> 113 <Project>{CE0F99D6-1C56-48A9-9B68-3E5B833703EF}</Project> 114 <Name>HeuristicLab.Problems.Instances.TSPLIB-3.3</Name> 115 </ProjectReference> 116 <ProjectReference Include="..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj"> 117 <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project> 118 <Name>HeuristicLab.Problems.Instances-3.3</Name> 110 119 </ProjectReference> 111 120 </ItemGroup>
Note: See TracChangeset
for help on using the changeset viewer.