Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/25/10 16:29:06 (14 years ago)
Author:
svonolfe
Message:

Improved the parsers (#1039)

Location:
branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/ORLIBParser.cs

    r4315 r4317  
    2525using System.Text;
    2626using System.IO;
     27using System.Globalization;
    2728
    2829namespace HeuristicLab.Problems.VehicleRouting {
    2930  class ORLIBParser {
    3031    private StreamReader source;
     32    CultureInfo culture = new CultureInfo("en-US");
    3133   
    3234    private string name;
     
    101103        line = source.ReadLine();
    102104        tokens = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
    103         vertices[0, 0] = double.Parse(tokens[0]);
    104         vertices[0, 1] = double.Parse(tokens[1]);
     105        vertices[0, 0] = double.Parse(tokens[0], culture.NumberFormat);
     106        vertices[0, 1] = double.Parse(tokens[1], culture.NumberFormat);
    105107
    106108        for (int i = 0; i < customers; i++) {
    107109          line = source.ReadLine();
    108110          tokens = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
    109           vertices[i + 1, 0] = double.Parse(tokens[0]);
    110           vertices[i + 1, 1] = double.Parse(tokens[1]);
    111           demands[i + 1] = double.Parse(tokens[2]);
     111          vertices[i + 1, 0] = double.Parse(tokens[0], culture.NumberFormat);
     112          vertices[i + 1, 1] = double.Parse(tokens[1], culture.NumberFormat);
     113          demands[i + 1] = double.Parse(tokens[2], culture.NumberFormat);
    112114        }
    113115      }
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/TSPLIBParser.cs

    r4232 r4317  
    2626namespace HeuristicLab.Problems.VehicleRouting {
    2727  /// <summary>
    28   /// Parses a *.tsp file in TSPLIB format and extracts its information about a TSP.
     28  /// Parses a *.vrp file in TSPLIB format and extracts its information about a VRP.
    2929  /// </summary>
    3030  public class TSPLIBParser {
     
    4343    private const int DIM = 4;
    4444    private const int WEIGHTTYPE = 5;
     45    private const int WEIGHTFORMAT = 11;
    4546    private const int NODETYPE = 6;
    4647    private const int NODESECTION = 7;
    4748    private const int CAPACITY = 8;
     49    private const int DISTANCE = 12;
     50    private const int VEHICLES = 13;
    4851    private const int DEPOTSECTION = 9;
    4952    private const int DEMANDSECTION = 10;
    5053
    5154    private StreamReader source;
     55    private bool alternateFormat;
     56    CultureInfo culture = new CultureInfo("en-US");
    5257
    5358    private string name;
    5459    /// <summary>
    55     /// Gets the name of the parsed TSP.
     60    /// Gets the name of the parsed VRP.
    5661    /// </summary>
    5762    public string Name {
     
    6065    private string comment;
    6166    /// <summary>
    62     /// Gets the comment of the parsed TSP.
     67    /// Gets the comment of the parsed VRP.
    6368    /// </summary>
    6469    public string Comment {
     
    6772    private double[,] vertices;
    6873    /// <summary>
    69     /// Gets the vertices of the parsed TSP.
     74    /// Gets the vertices of the parsed VRP.
    7075    /// </summary>
    7176    public double[,] Vertices {
     
    7479    private TSPLIBEdgeWeightType weightType;
    7580    /// <summary>
    76     /// Gets the weight type of the parsed TSP.
     81    /// Gets the weight format of the parsed VRP.
    7782    /// </summary>
    7883    public TSPLIBEdgeWeightType WeightType {
     
    8792    }
    8893
     94    private double distance;
     95    public double Distance {
     96      get {
     97        return distance;
     98      }
     99    }
     100
     101    private int vehicles;
     102    public int Vehicles {
     103      get {
     104        return vehicles;
     105      }
     106    }
     107
    89108    private int depot;
    90109    public int Depot {
     
    104123    /// Initializes a new instance of <see cref="TSPLIBParser"/> with the given <paramref name="path"/>.
    105124    /// </summary>
    106     /// <exception cref="ArgumentException">Thrown if the input file is not a TSPLIB TSP file (*.tsp)
     125    /// <exception cref="ArgumentException">Thrown if the input file is not a TSPLIB TSP file (*.vrp)
    107126    /// </exception>
    108     /// <param name="path">The path where the TSP is stored.</param>
     127    /// <param name="path">The path where the VRP is stored.</param>
    109128    public TSPLIBParser(String path) {
    110129      if (!path.EndsWith(".vrp"))
    111         throw new ArgumentException("Input file has to be a TSPLIB CVRP file (*.tsp).");
    112 
    113       source = new StreamReader(path);
     130        throw new ArgumentException("Input file has to be a TSPLIB CVRP file (*.vrp, *.txt).");
     131
     132      source = null;
    114133      name = path;
    115134      comment = string.Empty;
     
    117136      weightType = TSPLIBEdgeWeightType.UNDEFINED;
    118137      capacity = -1;
     138      distance = -1;
     139      vehicles = -1;
    119140      depot = -1;
    120141      demands = null;
    121     }
    122 
    123     /// <summary>
    124     /// Reads the TSPLIB TSP file and parses the elements.
     142      alternateFormat = false;
     143    }
     144
     145    /// <summary>
     146    /// Reads the TSPLIB VRP file and parses the elements.
    125147    /// </summary>
    126148    /// <exception cref="InvalidDataException">Thrown if the file has an invalid format or contains invalid data.</exception>
    127149    public void Parse() {
    128       int section = -1;
    129       string str = null;
    130       bool typeIsChecked = false;
    131       bool weightTypeIsChecked = false;
    132 
    133       do {
    134         str = source.ReadLine();
    135         section = GetSection(str);
    136 
    137         if (section != -1) {
    138           switch (section) {
    139             case NAME:
    140               ReadName(str);
    141               break;
    142             case TYPE:
    143               CheckType(str);
    144               typeIsChecked = true;
    145               break;
    146             case COMMENT:
    147               ReadComment(str);
    148               break;
    149             case DIM:
    150               InitArrays(str);
    151               break;
    152             case WEIGHTTYPE:
    153               ReadWeightType(str);
    154               weightTypeIsChecked = true;
    155               break;
    156             case NODETYPE:
    157               CheckNodeType(str);
    158               break;
    159             case NODESECTION:
    160               ReadVertices();
    161               break;
    162             case CAPACITY:
    163               ReadCapacity(str);
    164               break;
    165             case DEPOTSECTION:
    166               ReadDepot();
    167               break;
    168             case DEMANDSECTION:
    169               ReadDemands();
    170               break;
     150      using (source = new StreamReader(name)) {
     151        int section = -1;
     152        string str = null;
     153        bool typeIsChecked = false;
     154        bool weightTypeIsChecked = false;
     155        bool weightFormatIsChecked = false;
     156
     157        do {
     158          str = source.ReadLine();
     159          section = GetSection(str);
     160
     161          if (section != -1) {
     162            switch (section) {
     163              case NAME:
     164                ReadName(str);
     165                break;
     166              case TYPE:
     167                CheckType(str);
     168                typeIsChecked = true;
     169                break;
     170              case COMMENT:
     171                ReadComment(str);
     172                break;
     173              case DIM:
     174                InitArrays(str);
     175                break;
     176              case WEIGHTTYPE:
     177                ReadWeightType(str);
     178                weightTypeIsChecked = true;
     179                break;
     180              case WEIGHTFORMAT:
     181                ReadWeightFormat(str);
     182                weightFormatIsChecked = true;
     183                break;
     184              case NODETYPE:
     185                CheckNodeType(str);
     186                break;
     187              case NODESECTION:
     188                ReadVertices();
     189                break;
     190              case CAPACITY:
     191                ReadCapacity(str);
     192                break;
     193              case DISTANCE:
     194                ReadDistance(str);
     195                break;
     196              case VEHICLES:
     197                ReadVehicles(str);
     198                break;
     199              case DEPOTSECTION:
     200                ReadDepot();
     201                break;
     202              case DEMANDSECTION:
     203                ReadDemands();
     204                break;
     205            }
    171206          }
    172         }
    173       } while (!((section == EOF) || (str == null)));
    174 
    175       if (!(typeIsChecked && weightTypeIsChecked))
    176         throw new InvalidDataException("Input file does not contain type or edge weight type information.");
     207        } while (!((section == EOF) || (str == null)));
     208
     209        if (!typeIsChecked || !weightTypeIsChecked ||
     210          (alternateFormat && !weightFormatIsChecked) ||
     211          weightType == TSPLIBEdgeWeightType.UNDEFINED)
     212          throw new InvalidDataException("Input file does not contain format or edge weight format information.");
     213      }
     214      source = null;
    177215    }
    178216
     
    198236      if (token.Equals("edge_weight_type", StringComparison.OrdinalIgnoreCase))
    199237        return WEIGHTTYPE;
     238      if (token.Equals("edge_weight_format", StringComparison.OrdinalIgnoreCase))
     239        return WEIGHTFORMAT;
    200240      if (token.Equals("node_coord_type", StringComparison.OrdinalIgnoreCase))
    201241        return NODETYPE;
     
    204244      if (token.Equals("capacity", StringComparison.OrdinalIgnoreCase))
    205245        return CAPACITY;
     246      if (token.Equals("distance", StringComparison.OrdinalIgnoreCase))
     247        return DISTANCE;
     248      if (token.Equals("vehicles", StringComparison.OrdinalIgnoreCase))
     249        return VEHICLES;
    206250      if (token.Equals("depot_section", StringComparison.OrdinalIgnoreCase))
    207251        return DEPOTSECTION;
     
    222266      string type = tokens[tokens.Length - 1].Trim();
    223267      if (!type.Equals("cvrp", StringComparison.OrdinalIgnoreCase))
    224         throw new InvalidDataException("Input file type is not \"CVRP\"");
     268        throw new InvalidDataException("Input file format is not \"CVRP\"");
    225269    }
    226270
     
    247291      else if (type.Equals("geo", StringComparison.OrdinalIgnoreCase))
    248292        weightType = TSPLIBEdgeWeightType.GEO;
     293      else if (type.Equals("function", StringComparison.OrdinalIgnoreCase)) {
     294        weightType = TSPLIBEdgeWeightType.UNDEFINED;
     295        alternateFormat = true;
     296      } else
     297        throw new InvalidDataException("Input file contains an unsupported edge weight format (only \"EUC_2D\" and \"GEO\" are supported).");
     298    }
     299
     300    private void ReadWeightFormat(string str) {
     301      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
     302      string format = tokens[tokens.Length - 1].Trim();
     303
     304      if (alternateFormat && format.Equals("euc_2d", StringComparison.OrdinalIgnoreCase))
     305        weightType = TSPLIBEdgeWeightType.EUC_2D;
     306      else if (format.Equals("geo", StringComparison.OrdinalIgnoreCase))
     307        weightType = TSPLIBEdgeWeightType.GEO;
    249308      else
    250         throw new InvalidDataException("Input file contains an unsupported edge weight type (only \"EUC_2D\" and \"GEO\" are supported).");
     309        throw new InvalidDataException("Input file contains an unsupported edge weight format.");
    251310    }
    252311
     
    256315
    257316      if (!type.Equals("twod_coords", StringComparison.OrdinalIgnoreCase))
    258         throw new InvalidDataException("Input file contains an unsupported node coordinates type (only \"TWOD_COORDS\" is supported).");
     317        throw new InvalidDataException("Input file contains an unsupported node coordinates format (only \"TWOD_COORDS\" is supported).");
    259318    }
    260319
     
    264323
    265324      for (int i = 0; i < (vertices.Length / 2); i++) {
    266         string str = source.ReadLine();
    267         string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
    268 
    269         if (tokens.Length != 3)
    270           throw new InvalidDataException("Input file contains invalid node coordinates.");
    271 
    272         CultureInfo culture = new CultureInfo("en-US");
    273         vertices[i, 0] = double.Parse(tokens[1], culture.NumberFormat);
    274         vertices[i, 1] = double.Parse(tokens[2], culture.NumberFormat);
     325        if (!(alternateFormat && i == 0)) {
     326          string str = source.ReadLine();
     327          string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
     328
     329          if (tokens.Length != 3)
     330            throw new InvalidDataException("Input file contains invalid node coordinates.");
     331
     332          vertices[i, 0] = double.Parse(tokens[1], culture.NumberFormat);
     333          vertices[i, 1] = double.Parse(tokens[2], culture.NumberFormat);
     334        }
    275335      }
    276336    }
     
    278338    private void ReadCapacity(string str) {
    279339      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
    280       capacity = double.Parse(tokens[tokens.Length - 1].Trim());
     340      capacity = double.Parse(tokens[tokens.Length - 1].Trim(), culture.NumberFormat);
     341    }
     342
     343    private void ReadDistance(string str) {
     344      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
     345      distance = double.Parse(tokens[tokens.Length - 1].Trim(), culture.NumberFormat);
     346    }
     347
     348    private void ReadVehicles(string str) {
     349      string[] tokens = str.Split(new string[] { ":" }, StringSplitOptions.None);
     350      vehicles = int.Parse(tokens[tokens.Length - 1].Trim());
    281351    }
    282352
    283353    private void ReadDepot() {
    284       int read;
    285 
    286       do {
    287         string str = source.ReadLine();
    288         read = int.Parse(str);
    289         if (read != -1)
    290           depot = read;
    291       } while (read != -1);
     354      if (alternateFormat) {
     355        string[] tokens;
     356        do {
     357          string str = source.ReadLine();
     358          tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
     359
     360          if (tokens.Length == 2) {
     361            vertices[0, 0] = double.Parse(tokens[0], culture.NumberFormat);
     362            vertices[0, 1] = double.Parse(tokens[1], culture.NumberFormat);
     363            depot = 1;
     364          }
     365        } while(tokens.Length == 2);
     366      } else {
     367        int read;
     368        do {
     369          string str = source.ReadLine();
     370          read = int.Parse(str);
     371          if (read != -1)
     372            depot = read;
     373        } while (read != -1);
     374      }
    292375    }
    293376
     
    297380
    298381      for (int i = 0; i < demands.Length; i++) {
    299         string str = source.ReadLine();
    300         string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
    301 
    302         if (tokens.Length != 2)
    303           throw new InvalidDataException("Input file contains invalid demands.");
    304 
    305         int index = int.Parse(tokens[0]);
    306         double value = double.Parse(tokens[1]);
    307 
    308         demands[index - 1] = value;
     382        if (!(alternateFormat && i == 0)) {
     383          string str = source.ReadLine();
     384          string[] tokens = str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
     385
     386          if (tokens.Length != 2)
     387            throw new InvalidDataException("Input file contains invalid demands.");
     388
     389          int index = int.Parse(tokens[0]);
     390          double value = double.Parse(tokens[1]);
     391
     392          if (alternateFormat)
     393            demands[index] = value;
     394          else
     395            demands[index - 1] = value;
     396        } else {
     397          demands[0] = 0;
     398        }
    309399      }
    310400    }
  • branches/VRP/HeuristicLab.Problems.VehicleRouting/3.3/VehicleRoutingProblem.cs

    r4315 r4317  
    461461
    462462      Coordinates = new DoubleMatrix(parser.Vertices);
    463       Vehicles.Value = problemSize - 1;
     463      if (parser.Vehicles != -1)
     464        Vehicles.Value = parser.Vehicles;
     465      else
     466        Vehicles.Value = problemSize - 1;
    464467      Capacity.Value = parser.Capacity;
    465468      Demand = new DoubleArray(parser.Demands);
     
    472475        DueTime[i] = int.MaxValue;
    473476        ServiceTime[i] = 0;
     477      }
     478
     479      if (parser.Distance != -1) {
     480        DueTime[0] = parser.Distance;
    474481      }
    475482
Note: See TracChangeset for help on using the changeset viewer.