source: branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSP.cs @ 17270

Last change on this file since 17270 was 17270, checked in by abeham, 3 years ago

#2521: worked on removing virtual from Maximization for single-objective problems

File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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.Linq;
24using HEAL.Attic;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.PermutationEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Problems.Instances;
32using HeuristicLab.Problems.TravelingSalesman;
33using HeuristicLab.Random;
34
35namespace HeuristicLab.Problems.PTSP {
36  [Item("Probabilistic TSP (pTSP)", "Represents a Probabilistic Traveling Salesman Problem.")]
37  [StorableType("86041a8c-14e6-46e1-b20f-566892c871f6")]
38  public abstract class ProbabilisticTSP : PermutationProblem,
39      IProblemInstanceConsumer<PTSPData> {
40    protected bool SuppressEvents { get; set; }
41
42    public static int DistanceMatrixSizeLimit = 1000;
43
44    #region Parameter Properties
45    [Storable] public ValueParameter<IProbabilisticTSPData> PTSPDataParameter { get; private set; }
46    [Storable] public OptionalValueParameter<IProbabilisticTSPSolution> BestKnownSolutionParameter { get; private set; }
47    #endregion
48
49    #region Properties
50    public IProbabilisticTSPData ProbabilisticTSPData {
51      get { return PTSPDataParameter.Value; }
52      set { PTSPDataParameter.Value = value; }
53    }
54    public IProbabilisticTSPSolution BestKnownSolution {
55      get { return BestKnownSolutionParameter.Value; }
56      set { BestKnownSolutionParameter.Value = value; }
57    }
58    #endregion
59
60    [StorableConstructor]
61    protected ProbabilisticTSP(StorableConstructorFlag _) : base(_) { }
62    protected ProbabilisticTSP(ProbabilisticTSP original, Cloner cloner)
63      : base(original, cloner) {
64      PTSPDataParameter = cloner.Clone(original.PTSPDataParameter);
65      BestKnownSolutionParameter = cloner.Clone(original.BestKnownSolutionParameter);
66    }
67    protected ProbabilisticTSP() : base(new PermutationEncoding("Tour")) {
68      Maximization = false;
69      Parameters.Add(PTSPDataParameter = new ValueParameter<IProbabilisticTSPData>("PTSP Data", "The main parameters for the pTSP."));
70      Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<IProbabilisticTSPSolution>("BestKnownSolution", "The best known solution of this pTSP instance."));
71
72      ProbabilisticTSPData = new MatrixPTSPData();
73      Encoding.Length = ProbabilisticTSPData.Cities;
74    }
75
76    protected override void OnEncodingChanged() {
77      base.OnEncodingChanged();
78      Encoding.Length = ProbabilisticTSPData.Cities;
79    }
80
81    public override void Analyze(Permutation[] solutions, double[] qualities, ResultCollection results, IRandom random) {
82      base.Analyze(solutions, qualities, results, random);
83      var max = Maximization;
84
85      var i = !max ? qualities.Select((x, index) => new { index, Quality = x }).OrderBy(x => x.Quality).First().index
86                   : qualities.Select((x, index) => new { index, Quality = x }).OrderByDescending(x => x.Quality).First().index;
87
88      if (double.IsNaN(BestKnownQuality) ||
89          max && qualities[i] > BestKnownQuality ||
90          !max && qualities[i] < BestKnownQuality) {
91        BestKnownQuality = qualities[i];
92        BestKnownSolution = ProbabilisticTSPData.GetSolution((Permutation)solutions[i].Clone(), qualities[i]);
93      }
94
95      IResult bestSolutionResult;
96      if (results.TryGetValue("Best pTSP Solution", out bestSolutionResult)) {
97        var bestSolution = bestSolutionResult.Value as ITSPSolution;
98        if (bestSolution == null || Maximization && bestSolution.TourLength.Value < qualities[i]
99          || !Maximization && bestSolution.TourLength.Value > qualities[i]) {
100          bestSolutionResult.Value = ProbabilisticTSPData.GetSolution(solutions[i], qualities[i]);
101        }
102      } else results.Add(new Result("Best pTSP Solution", ProbabilisticTSPData.GetSolution(solutions[i], qualities[i])));
103    }
104
105    public virtual void Load(PTSPData data) {
106      if (data.Coordinates == null && data.Distances == null)
107        throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
108      if (data.Dimension > DistanceMatrixSizeLimit && (data.DistanceMeasure == DistanceMeasure.Att
109        || data.DistanceMeasure == DistanceMeasure.Manhattan
110        || data.DistanceMeasure == DistanceMeasure.Maximum))
111        throw new System.IO.InvalidDataException("The given instance uses an unsupported distance measure and is too large for using a distance matrix.");
112      if (data.Coordinates != null && data.Coordinates.GetLength(1) != 2)
113        throw new System.IO.InvalidDataException("The coordinates of the given instance are not in the right format, there need to be one row for each customer and two columns for the x and y coordinates.");
114
115      Encoding.Length = data.Dimension;
116      Name = data.Name;
117      Description = data.Description;
118
119      if (data.Dimension <= DistanceMatrixSizeLimit) {
120        ProbabilisticTSPData = new MatrixPTSPData(data.Name, data.GetDistanceMatrix(), data.Probabilities, data.Coordinates) { Description = data.Description };
121      } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) {
122        ProbabilisticTSPData = new MatrixPTSPData(data.Name, data.Distances, data.Probabilities, data.Coordinates) { Description = data.Description };
123      } else {
124        switch (data.DistanceMeasure) {
125          case DistanceMeasure.Att:
126            ProbabilisticTSPData = new AttPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
127            break;
128          case DistanceMeasure.Euclidean:
129            ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.None) { Description = data.Description };
130            break;
131          case DistanceMeasure.RoundedEuclidean:
132            ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.Midpoint) { Description = data.Description };
133            break;
134          case DistanceMeasure.UpperEuclidean:
135            ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.Ceiling) { Description = data.Description };
136            break;
137          case DistanceMeasure.Geo:
138            ProbabilisticTSPData = new GeoPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
139            break;
140          case DistanceMeasure.Manhattan:
141            ProbabilisticTSPData = new ManhattanPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
142            break;
143          case DistanceMeasure.Maximum:
144            ProbabilisticTSPData = new MaximumPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description };
145            break;
146          default:
147            throw new System.IO.InvalidDataException("An unknown distance measure is given in the instance!");
148        }
149      }
150      BestKnownSolution = null;
151      BestKnownQuality = double.NaN;
152
153      if (data.BestKnownTour != null) {
154        try {
155          var tour = new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour);
156          var tourLength = Evaluate(tour, new MersenneTwister(1));
157          BestKnownSolution = new ProbabilisticTSPSolution(data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null, new PercentArray(data.Probabilities), tour, new DoubleValue(tourLength));
158          BestKnownQuality = tourLength;
159        } catch (InvalidOperationException) {
160          if (data.BestKnownQuality.HasValue)
161            BestKnownQuality = data.BestKnownQuality.Value;
162        }
163      } else if (data.BestKnownQuality.HasValue) {
164        BestKnownQuality = data.BestKnownQuality.Value;
165      }
166      OnReset();
167    }
168  }
169}
Note: See TracBrowser for help on using the repository browser.