Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.Instances.VehicleRouting/3.4/VRPInstanceProvider.cs @ 13869

Last change on this file since 13869 was 12012, checked in by ascheibe, 10 years ago

#2212 merged r12008, r12009, r12010 back into trunk

File size: 6.1 KB
RevLine 
[7881]1#region License Information
2/* HeuristicLab
[12012]3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[7881]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.IO;
[11650]25using System.IO.Compression;
[7881]26using System.Linq;
27using System.Reflection;
28using System.Text.RegularExpressions;
[11455]29using HeuristicLab.Common;
[7881]30
31namespace HeuristicLab.Problems.Instances.VehicleRouting {
[11428]32  public abstract class VRPInstanceProvider<TData> : ProblemInstanceProvider<TData>, IVRPInstanceProvider<TData> where TData : IVRPData {
[7881]33    protected abstract string FileName { get; }
34
35    public override IEnumerable<IDataDescriptor> GetDataDescriptors() {
[11428]36      var solutions = new Dictionary<string, string>();
[7881]37      var solutionsArchiveName = GetResourceName(FileName + @"\.opt\.zip");
38      if (!String.IsNullOrEmpty(solutionsArchiveName)) {
[11650]39        using (var solutionsZipFile = new ZipArchive(GetType().Assembly.GetManifestResourceStream(solutionsArchiveName), ZipArchiveMode.Read)) {
40          foreach (var entry in solutionsZipFile.Entries)
41            solutions.Add(Path.GetFileNameWithoutExtension(entry.Name) + "." + FileName, entry.Name);
[7881]42        }
43      }
44      var instanceArchiveName = GetResourceName(FileName + @"\.zip");
45      if (String.IsNullOrEmpty(instanceArchiveName)) yield break;
46
[11650]47      using (var instanceStream = new ZipArchive(GetType().Assembly.GetManifestResourceStream(instanceArchiveName), ZipArchiveMode.Read)) {
48        foreach (var entry in instanceStream.Entries.Select(x => x.Name).OrderBy(x => x, new NaturalStringComparer())) {
[11428]49          string solutionEntry = Path.GetFileNameWithoutExtension(entry) + "." + FileName;
[7881]50          yield return new VRPDataDescriptor(Path.GetFileNameWithoutExtension(entry), GetInstanceDescription(), entry, solutions.ContainsKey(solutionEntry) ? solutions[solutionEntry] : String.Empty);
51        }
52      }
53    }
54
[11428]55    public override TData LoadData(IDataDescriptor id) {
[7881]56      var descriptor = (VRPDataDescriptor)id;
57      var instanceArchiveName = GetResourceName(FileName + @"\.zip");
[11650]58      using (var instancesZipFile = new ZipArchive(GetType().Assembly.GetManifestResourceStream(instanceArchiveName))) {
[7881]59        var entry = instancesZipFile.GetEntry(descriptor.InstanceIdentifier);
[11650]60        var stream = entry.Open();
[7881]61        var instance = LoadData(stream);
62        if (string.IsNullOrEmpty(instance.Name)) {
63          instance.Name = Path.GetFileNameWithoutExtension(entry.ToString());
64        }
65
66        if (!String.IsNullOrEmpty(descriptor.SolutionIdentifier)) {
67          var solutionsArchiveName = GetResourceName(FileName + @"\.opt\.zip");
[11650]68          using (var solutionsZipFile = new ZipArchive(GetType().Assembly.GetManifestResourceStream(solutionsArchiveName))) {
[7881]69            entry = solutionsZipFile.GetEntry(descriptor.SolutionIdentifier);
[11650]70            stream = entry.Open();
[7881]71            LoadSolution(stream, instance);
72          }
73        }
74
75        return instance;
76      }
77    }
78
[11428]79    #region IVRPInstanceProvider
80    public TData Import(string vrpFile, string tourFile) {
81      var data = ImportData(vrpFile);
82      if (!String.IsNullOrEmpty(tourFile)) {
83        LoadSolution(tourFile, data);
84      }
85      return data;
86    }
87
88    public void Export(TData instance, string path) {
89      ExportData(instance, path);
90    }
91    #endregion
92
93    protected virtual void LoadSolution(Stream stream, TData instance) {
[11478]94      LoadOptFile(stream, instance);
95    }
96
97    private void LoadOptFile(Stream stream, TData instance) {
[7881]98      List<List<int>> routes = new List<List<int>>();
99
100      using (StreamReader reader = new StreamReader(stream)) {
101        String line;
102        while ((line = reader.ReadLine()) != null) {
103          if (line.StartsWith("Route")) {
104            string[] token = line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
105
106            List<int> route = new List<int>();
107
108            for (int i = 2; i < token.Length; i++) {
109              route.Add(int.Parse(token[i]) - 1);
110            }
111
112            routes.Add(route);
113          }
[11295]114
115          if (line.StartsWith("Solution")) {
116            if (routes.Any()) {
117              // Skip remaining solutions since only one "best solution" is stored
118              break;
119            }
120          }
[7881]121        }
122      }
123
124      instance.BestKnownTour = routes.Select(x => x.ToArray()).ToArray();
125    }
126
[11428]127    public void LoadSolution(string path, TData instance) {
[11478]128      try {
129        using (var stream = new FileStream(path, FileMode.Open)) {
130          LoadSolution(stream, instance);
131        }
[11650]132      }
133      catch (Exception) {
[11478]134        // new stream necessary because first try already read from stream
135        using (var stream = new FileStream(path, FileMode.Open)) {
136          LoadOptFile(stream, instance); // Fallback to .opt-Format
137        }
[7881]138      }
139    }
140
[11428]141    protected abstract TData LoadData(Stream stream);
[7881]142
[11428]143    #region Helpers
[7881]144    protected virtual string GetResourceName(string fileName) {
145      return Assembly.GetExecutingAssembly().GetManifestResourceNames()
146              .Where(x => Regex.Match(x, @".*\.Data\." + fileName).Success).SingleOrDefault();
147    }
148
149    protected virtual string GetInstanceDescription() {
150      return "Embedded instance of plugin version " + Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true).Cast<AssemblyFileVersionAttribute>().First().Version + ".";
151    }
[11428]152    #endregion
[7881]153  }
154}
Note: See TracBrowser for help on using the repository browser.