Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs @ 8334

Last change on this file since 8334 was 8334, checked in by jkarder, 10 years ago

#1331: reintegrated branch

File size: 22.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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.IO;
25using System.Linq;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.PermutationEncoding;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34using HeuristicLab.Problems.Instances;
35
36namespace HeuristicLab.Problems.TravelingSalesman {
37  [Item("Traveling Salesman Problem", "Represents a symmetric Traveling Salesman Problem.")]
38  [Creatable("Problems")]
39  [StorableClass]
40  public sealed class TravelingSalesmanProblem : SingleObjectiveHeuristicOptimizationProblem<ITSPEvaluator, IPermutationCreator>, IStorableContent,
41    IProblemInstanceConsumer<TSPData> {
42    private static readonly int DistanceMatrixSizeLimit = 1000;
43    public string Filename { get; set; }
44
45    #region Parameter Properties
46    public OptionalValueParameter<DoubleMatrix> CoordinatesParameter {
47      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
48    }
49    public OptionalValueParameter<DistanceMatrix> DistanceMatrixParameter {
50      get { return (OptionalValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
51    }
52    public ValueParameter<BoolValue> UseDistanceMatrixParameter {
53      get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
54    }
55    public OptionalValueParameter<Permutation> BestKnownSolutionParameter {
56      get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
57    }
58    #endregion
59
60    #region Properties
61    public DoubleMatrix Coordinates {
62      get { return CoordinatesParameter.Value; }
63      set { CoordinatesParameter.Value = value; }
64    }
65    public DistanceMatrix DistanceMatrix {
66      get { return DistanceMatrixParameter.Value; }
67      set { DistanceMatrixParameter.Value = value; }
68    }
69    public BoolValue UseDistanceMatrix {
70      get { return UseDistanceMatrixParameter.Value; }
71      set { UseDistanceMatrixParameter.Value = value; }
72    }
73    public Permutation BestKnownSolution {
74      get { return BestKnownSolutionParameter.Value; }
75      set { BestKnownSolutionParameter.Value = value; }
76    }
77    private BestTSPSolutionAnalyzer BestTSPSolutionAnalyzer {
78      get { return Operators.OfType<BestTSPSolutionAnalyzer>().FirstOrDefault(); }
79    }
80    private TSPAlleleFrequencyAnalyzer TSPAlleleFrequencyAnalyzer {
81      get { return Operators.OfType<TSPAlleleFrequencyAnalyzer>().FirstOrDefault(); }
82    }
83    private TSPPopulationDiversityAnalyzer TSPPopulationDiversityAnalyzer {
84      get { return Operators.OfType<TSPPopulationDiversityAnalyzer>().FirstOrDefault(); }
85    }
86    #endregion
87
88    // BackwardsCompatibility3.3
89    #region Backwards compatible code, remove with 3.4
90    [Obsolete]
91    [Storable(Name = "operators")]
92    private IEnumerable<IOperator> oldOperators {
93      get { return null; }
94      set {
95        if (value != null && value.Any())
96          Operators.AddRange(value);
97      }
98    }
99    #endregion
100
101    [StorableConstructor]
102    private TravelingSalesmanProblem(bool deserializing) : base(deserializing) { }
103    private TravelingSalesmanProblem(TravelingSalesmanProblem original, Cloner cloner)
104      : base(original, cloner) {
105      RegisterEventHandlers();
106    }
107    public override IDeepCloneable Clone(Cloner cloner) {
108      return new TravelingSalesmanProblem(this, cloner);
109    }
110    public TravelingSalesmanProblem()
111      : base(new TSPRoundedEuclideanPathEvaluator(), new RandomPermutationCreator()) {
112      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities."));
113      Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
114      Parameters.Add(new ValueParameter<BoolValue>("UseDistanceMatrix", "True if the coordinates based evaluators should calculate the distance matrix from the coordinates and use it for evaluation similar to the distance matrix evaluator, otherwise false.", new BoolValue(true)));
115      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
116
117      Maximization.Value = false;
118      MaximizationParameter.Hidden = true;
119      UseDistanceMatrixParameter.Hidden = true;
120      DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
121
122      Coordinates = new DoubleMatrix(new double[,] {
123        { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
124        { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },
125        { 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },
126        { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
127      });
128
129      SolutionCreator.PermutationParameter.ActualName = "TSPTour";
130      Evaluator.QualityParameter.ActualName = "TSPTourLength";
131      ParameterizeSolutionCreator();
132      ParameterizeEvaluator();
133
134      InitializeOperators();
135      RegisterEventHandlers();
136    }
137
138    #region Events
139    protected override void OnSolutionCreatorChanged() {
140      base.OnSolutionCreatorChanged();
141      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
142      ParameterizeSolutionCreator();
143      ParameterizeEvaluator();
144      ParameterizeAnalyzers();
145      ParameterizeOperators();
146    }
147    protected override void OnEvaluatorChanged() {
148      base.OnEvaluatorChanged();
149      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
150      ParameterizeEvaluator();
151      ParameterizeSolutionCreator();
152      UpdateMoveEvaluators();
153      ParameterizeAnalyzers();
154      if (Evaluator is ITSPCoordinatesPathEvaluator && Coordinates != null)
155        ClearDistanceMatrix();
156    }
157    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
158      if (Coordinates != null) {
159        Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
160        Coordinates.Reset += new EventHandler(Coordinates_Reset);
161      }
162      if (Evaluator is ITSPCoordinatesPathEvaluator) {
163        ParameterizeSolutionCreator();
164        ClearDistanceMatrix();
165      }
166    }
167    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
168      if (Evaluator is ITSPCoordinatesPathEvaluator) {
169        ClearDistanceMatrix();
170      }
171    }
172    private void Coordinates_Reset(object sender, EventArgs e) {
173      if (Evaluator is ITSPCoordinatesPathEvaluator) {
174        ParameterizeSolutionCreator();
175        ClearDistanceMatrix();
176      }
177    }
178    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
179      ParameterizeEvaluator();
180      ParameterizeAnalyzers();
181      ParameterizeOperators();
182    }
183    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
184      ParameterizeAnalyzers();
185    }
186    #endregion
187
188    #region Helpers
189    [StorableHook(HookType.AfterDeserialization)]
190    private void AfterDeserialization() {
191      // BackwardsCompatibility3.3
192      #region Backwards compatible code (remove with 3.4)
193      OptionalValueParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as OptionalValueParameter<DoubleMatrix>;
194      if (oldDistanceMatrixParameter != null) {
195        Parameters.Remove(oldDistanceMatrixParameter);
196        Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
197        DistanceMatrixParameter.GetsCollected = oldDistanceMatrixParameter.GetsCollected;
198        DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
199        if (oldDistanceMatrixParameter.Value != null) {
200          DoubleMatrix oldDM = oldDistanceMatrixParameter.Value;
201          DistanceMatrix newDM = new DistanceMatrix(oldDM.Rows, oldDM.Columns, oldDM.ColumnNames, oldDM.RowNames);
202          newDM.SortableView = oldDM.SortableView;
203          for (int i = 0; i < newDM.Rows; i++)
204            for (int j = 0; j < newDM.Columns; j++)
205              newDM[i, j] = oldDM[i, j];
206          DistanceMatrixParameter.Value = (DistanceMatrix)newDM.AsReadOnly();
207        }
208      }
209
210      ValueParameter<DoubleMatrix> oldCoordinates = (Parameters["Coordinates"] as ValueParameter<DoubleMatrix>);
211      if (oldCoordinates != null) {
212        Parameters.Remove(oldCoordinates);
213        Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.", oldCoordinates.Value, oldCoordinates.GetsCollected));
214      }
215
216      if (Operators.Count == 0) InitializeOperators();
217      #endregion
218      RegisterEventHandlers();
219    }
220
221    private void RegisterEventHandlers() {
222      CoordinatesParameter.ValueChanged += new EventHandler(CoordinatesParameter_ValueChanged);
223      if (Coordinates != null) {
224        Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
225        Coordinates.Reset += new EventHandler(Coordinates_Reset);
226      }
227      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
228      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
229    }
230
231    private void InitializeOperators() {
232      Operators.Add(new TSPImprovementOperator());
233      Operators.Add(new TSPMultipleGuidesPathRelinker());
234      Operators.Add(new TSPPathRelinker());
235      Operators.Add(new TSPSimultaneousPathRelinker());
236      Operators.Add(new TSPSimilarityCalculator());
237
238      Operators.Add(new BestTSPSolutionAnalyzer());
239      Operators.Add(new TSPAlleleFrequencyAnalyzer());
240      Operators.Add(new TSPPopulationDiversityAnalyzer());
241      ParameterizeAnalyzers();
242      var operators = new HashSet<IPermutationOperator>(new IPermutationOperator[] {
243        new OrderCrossover2(),
244        new InversionManipulator(),
245        new StochasticInversionMultiMoveGenerator()
246      }, new TypeEqualityComparer<IPermutationOperator>());
247      foreach (var op in ApplicationManager.Manager.GetInstances<IPermutationOperator>())
248        operators.Add(op);
249      Operators.AddRange(operators);
250      ParameterizeOperators();
251      UpdateMoveEvaluators();
252    }
253    private void UpdateMoveEvaluators() {
254      Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
255      foreach (ITSPPathMoveEvaluator op in ApplicationManager.Manager.GetInstances<ITSPPathMoveEvaluator>())
256        if (op.EvaluatorType == Evaluator.GetType()) {
257          Operators.Add(op);
258        }
259      ParameterizeOperators();
260      OnOperatorsChanged();
261    }
262    private void ParameterizeSolutionCreator() {
263      if (Evaluator is ITSPDistanceMatrixEvaluator && DistanceMatrix != null)
264        SolutionCreator.LengthParameter.Value = new IntValue(DistanceMatrix.Rows);
265      else if (Evaluator is ITSPCoordinatesPathEvaluator && Coordinates != null)
266        SolutionCreator.LengthParameter.Value = new IntValue(Coordinates.Rows);
267      else {
268        SolutionCreator.LengthParameter.Value = null;
269        string error = "The given problem does not support the selected evaluator.";
270        if (Evaluator is ITSPDistanceMatrixEvaluator)
271          error += Environment.NewLine + "Please review that the " + DistanceMatrixParameter.Name + " parameter is defined or choose another evaluator.";
272        else error += Environment.NewLine + "Please review that the " + CoordinatesParameter.Name + " parameter is defined or choose another evaluator.";
273        PluginInfrastructure.ErrorHandling.ShowErrorDialog(error, null);
274      }
275      SolutionCreator.LengthParameter.Hidden = SolutionCreator.LengthParameter.Value != null;
276      SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.RelativeUndirected);
277      SolutionCreator.PermutationTypeParameter.Hidden = true;
278    }
279    private void ParameterizeEvaluator() {
280      if (Evaluator is ITSPPathEvaluator) {
281        ITSPPathEvaluator evaluator = (ITSPPathEvaluator)Evaluator;
282        evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
283        evaluator.PermutationParameter.Hidden = true;
284      }
285      if (Evaluator is ITSPCoordinatesPathEvaluator) {
286        ITSPCoordinatesPathEvaluator evaluator = (ITSPCoordinatesPathEvaluator)Evaluator;
287        evaluator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
288        evaluator.CoordinatesParameter.Hidden = true;
289        evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
290        evaluator.DistanceMatrixParameter.Hidden = true;
291        evaluator.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
292        evaluator.UseDistanceMatrixParameter.Hidden = true;
293      }
294      if (Evaluator is ITSPDistanceMatrixEvaluator) {
295        var evaluator = (ITSPDistanceMatrixEvaluator)Evaluator;
296        evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
297        evaluator.DistanceMatrixParameter.Hidden = true;
298      }
299    }
300    private void ParameterizeAnalyzers() {
301      if (BestTSPSolutionAnalyzer != null) {
302        BestTSPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
303        BestTSPSolutionAnalyzer.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
304        BestTSPSolutionAnalyzer.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
305        BestTSPSolutionAnalyzer.ResultsParameter.ActualName = "Results";
306        BestTSPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
307        BestTSPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
308        BestTSPSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
309      }
310
311      if (TSPAlleleFrequencyAnalyzer != null) {
312        TSPAlleleFrequencyAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
313        TSPAlleleFrequencyAnalyzer.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
314        TSPAlleleFrequencyAnalyzer.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
315        TSPAlleleFrequencyAnalyzer.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
316        TSPAlleleFrequencyAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
317        TSPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
318        TSPAlleleFrequencyAnalyzer.ResultsParameter.ActualName = "Results";
319      }
320
321      if (TSPPopulationDiversityAnalyzer != null) {
322        TSPPopulationDiversityAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
323        TSPPopulationDiversityAnalyzer.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
324        TSPPopulationDiversityAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
325        TSPPopulationDiversityAnalyzer.ResultsParameter.ActualName = "Results";
326      }
327    }
328    private void ParameterizeOperators() {
329      foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>()) {
330        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
331        op.ParentsParameter.Hidden = true;
332        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
333        op.ChildParameter.Hidden = true;
334      }
335      foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>()) {
336        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
337        op.PermutationParameter.Hidden = true;
338      }
339      foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>()) {
340        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
341        op.PermutationParameter.Hidden = true;
342      }
343      foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>()) {
344        op.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
345        op.CoordinatesParameter.Hidden = true;
346        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
347        op.DistanceMatrixParameter.Hidden = true;
348        op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
349        op.UseDistanceMatrixParameter.Hidden = true;
350        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
351        op.QualityParameter.Hidden = true;
352        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
353        op.PermutationParameter.Hidden = true;
354      }
355      foreach (IPermutationMultiNeighborhoodShakingOperator op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()) {
356        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
357        op.PermutationParameter.Hidden = true;
358      }
359      foreach (ISingleObjectiveImprovementOperator op in Operators.OfType<ISingleObjectiveImprovementOperator>()) {
360        op.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
361        op.SolutionParameter.Hidden = true;
362      }
363      foreach (ISingleObjectivePathRelinker op in Operators.OfType<ISingleObjectivePathRelinker>()) {
364        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
365        op.ParentsParameter.Hidden = true;
366      }
367      foreach (TSPSimilarityCalculator op in Operators.OfType<TSPSimilarityCalculator>()) {
368        op.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;
369        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
370      }
371    }
372
373    private void ClearDistanceMatrix() {
374      DistanceMatrixParameter.Value = null;
375    }
376    #endregion
377
378    public void Load(TSPData data) {
379      if (data.Coordinates == null && data.Distances == null)
380        throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!");
381      if (data.Dimension > DistanceMatrixSizeLimit && (data.DistanceMeasure == DistanceMeasure.Att
382        || data.DistanceMeasure == DistanceMeasure.Manhattan
383        || data.DistanceMeasure == DistanceMeasure.Maximum
384        || data.DistanceMeasure == DistanceMeasure.UpperEuclidean))
385        throw new System.IO.InvalidDataException("The given instance uses an unsupported distance measure and is too large for using a distance matrix.");
386      if (data.Coordinates != null && data.Coordinates.GetLength(1) != 2)
387        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.");
388
389      Name = data.Name;
390      Description = data.Description;
391
392      bool clearCoordinates = false, clearDistanceMatrix = false;
393      if (data.Coordinates != null && data.Coordinates.GetLength(0) > 0)
394        Coordinates = new DoubleMatrix(data.Coordinates);
395      else clearCoordinates = true;
396
397      TSPEvaluator evaluator;
398      if (data.DistanceMeasure == DistanceMeasure.Att
399        || data.DistanceMeasure == DistanceMeasure.Manhattan
400        || data.DistanceMeasure == DistanceMeasure.Maximum
401        || data.DistanceMeasure == DistanceMeasure.UpperEuclidean) {
402        evaluator = new TSPDistanceMatrixEvaluator();
403        UseDistanceMatrix = new BoolValue(true);
404        DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix());
405      } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) {
406        evaluator = new TSPDistanceMatrixEvaluator();
407        UseDistanceMatrix = new BoolValue(true);
408        DistanceMatrix = new DistanceMatrix(data.Distances);
409      } else {
410        clearDistanceMatrix = true;
411        UseDistanceMatrix = new BoolValue(data.Dimension <= DistanceMatrixSizeLimit);
412        switch (data.DistanceMeasure) {
413          case DistanceMeasure.Euclidean:
414            evaluator = new TSPEuclideanPathEvaluator();
415            break;
416          case DistanceMeasure.RoundedEuclidean:
417            evaluator = new TSPRoundedEuclideanPathEvaluator();
418            break;
419          case DistanceMeasure.Geo:
420            evaluator = new TSPGeoPathEvaluator();
421            break;
422          default:
423            throw new InvalidDataException("An unknown distance measure is given in the instance!");
424        }
425      }
426      evaluator.QualityParameter.ActualName = "TSPTourLength";
427      Evaluator = evaluator;
428
429      // reset them after assigning the evaluator
430      if (clearCoordinates) Coordinates = null;
431      if (clearDistanceMatrix) DistanceMatrix = null;
432
433      BestKnownSolution = null;
434      BestKnownQuality = null;
435
436      if (data.BestKnownTour != null) {
437        try {
438          EvaluateAndLoadTour(data.BestKnownTour);
439        } catch (InvalidOperationException) {
440          if (data.BestKnownQuality.HasValue)
441            BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
442        }
443      } else if (data.BestKnownQuality.HasValue) {
444        BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);
445      }
446      OnReset();
447    }
448
449    public void EvaluateAndLoadTour(int[] tour) {
450      var route = new Permutation(PermutationTypes.RelativeUndirected, tour);
451      BestKnownSolution = route;
452
453      double quality;
454      if (Evaluator is ITSPDistanceMatrixEvaluator) {
455        quality = TSPDistanceMatrixEvaluator.Apply(DistanceMatrix, route);
456      } else if (Evaluator is ITSPCoordinatesPathEvaluator) {
457        quality = TSPCoordinatesPathEvaluator.Apply((TSPCoordinatesPathEvaluator)Evaluator, Coordinates, route);
458      } else {
459        throw new InvalidOperationException("Cannot calculate solution quality, evaluator type is unknown.");
460      }
461      BestKnownQuality = new DoubleValue(quality);
462    }
463  }
464}
Note: See TracBrowser for help on using the repository browser.