Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3340 was 3340, checked in by abeham, 14 years ago

Updated Tabu search, permutation move operators, real vector move operators, binary vector move operators #840
Added a Tabu Search TSP workbench

File size: 18.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Drawing;
25using System.IO;
26using System.Linq;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.PermutationEncoding;
31using HeuristicLab.Optimization;
32using HeuristicLab.Parameters;
33using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
34using HeuristicLab.PluginInfrastructure;
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 : ParameterizedNamedItem, ISingleObjectiveProblem {
41    public override Image ItemImage {
42      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Type; }
43    }
44
45    #region Parameter Properties
46    public ValueParameter<BoolValue> MaximizationParameter {
47      get { return (ValueParameter<BoolValue>)Parameters["Maximization"]; }
48    }
49    IParameter ISingleObjectiveProblem.MaximizationParameter {
50      get { return MaximizationParameter; }
51    }
52    public ValueParameter<DoubleMatrix> CoordinatesParameter {
53      get { return (ValueParameter<DoubleMatrix>)Parameters["Coordinates"]; }
54    }
55    public OptionalValueParameter<DoubleMatrix> DistanceMatrixParameter {
56      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
57    }
58    public ValueParameter<BoolValue> UseDistanceMatrixParameter {
59      get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
60    }
61    public ValueParameter<IPermutationCreator> SolutionCreatorParameter {
62      get { return (ValueParameter<IPermutationCreator>)Parameters["SolutionCreator"]; }
63    }
64    IParameter IProblem.SolutionCreatorParameter {
65      get { return SolutionCreatorParameter; }
66    }
67    public ValueParameter<ITSPEvaluator> EvaluatorParameter {
68      get { return (ValueParameter<ITSPEvaluator>)Parameters["Evaluator"]; }
69    }
70    IParameter IProblem.EvaluatorParameter {
71      get { return EvaluatorParameter; }
72    }
73    public OptionalValueParameter<ITSPSolutionsVisualizer> VisualizerParameter {
74      get { return (OptionalValueParameter<ITSPSolutionsVisualizer>)Parameters["Visualizer"]; }
75    }
76    IParameter IProblem.VisualizerParameter {
77      get { return VisualizerParameter; }
78    }
79    public OptionalValueParameter<DoubleValue> BestKnownQualityParameter {
80      get { return (OptionalValueParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
81    }
82    IParameter ISingleObjectiveProblem.BestKnownQualityParameter {
83      get { return BestKnownQualityParameter; }
84    }
85    public OptionalValueParameter<Permutation> BestKnownSolutionParameter {
86      get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
87    }
88    #endregion
89
90    #region Properties
91    public DoubleMatrix Coordinates {
92      get { return CoordinatesParameter.Value; }
93      set { CoordinatesParameter.Value = value; }
94    }
95    public DoubleMatrix DistanceMatrix {
96      get { return DistanceMatrixParameter.Value; }
97      set { DistanceMatrixParameter.Value = value; }
98    }
99    public BoolValue UseDistanceMatrix {
100      get { return UseDistanceMatrixParameter.Value; }
101      set { UseDistanceMatrixParameter.Value = value; }
102    }
103    public IPermutationCreator SolutionCreator {
104      get { return SolutionCreatorParameter.Value; }
105      set { SolutionCreatorParameter.Value = value; }
106    }
107    ISolutionCreator IProblem.SolutionCreator {
108      get { return SolutionCreatorParameter.Value; }
109    }
110    public ITSPEvaluator Evaluator {
111      get { return EvaluatorParameter.Value; }
112      set { EvaluatorParameter.Value = value; }
113    }
114    ISingleObjectiveEvaluator ISingleObjectiveProblem.Evaluator {
115      get { return EvaluatorParameter.Value; }
116    }
117    IEvaluator IProblem.Evaluator {
118      get { return EvaluatorParameter.Value; }
119    }
120    public ITSPSolutionsVisualizer Visualizer {
121      get { return VisualizerParameter.Value; }
122      set { VisualizerParameter.Value = value; }
123    }
124    ISolutionsVisualizer IProblem.Visualizer {
125      get { return VisualizerParameter.Value; }
126    }
127    public DoubleValue BestKnownQuality {
128      get { return BestKnownQualityParameter.Value; }
129      set { BestKnownQualityParameter.Value = value; }
130    }
131    public Permutation BestKnownSolution {
132      get { return BestKnownSolutionParameter.Value; }
133      set { BestKnownSolutionParameter.Value = value; }
134    }
135    private List<IPermutationOperator> operators;
136    public IEnumerable<IOperator> Operators {
137      get { return operators.Cast<IOperator>(); }
138    }
139    #endregion
140
141    public TravelingSalesmanProblem()
142      : base() {
143      RandomPermutationCreator creator = new RandomPermutationCreator();
144      TSPRoundedEuclideanPathEvaluator evaluator = new TSPRoundedEuclideanPathEvaluator();
145      BestPathTSPTourVisualizer visualizer = new BestPathTSPTourVisualizer();
146
147      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to false as the Traveling Salesman Problem is a minimization problem.", new BoolValue(false)));
148      Parameters.Add(new ValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.", new DoubleMatrix(0, 0)));
149      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
150      Parameters.Add(new ValueParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false.", new BoolValue(true)));
151      Parameters.Add(new ValueParameter<IPermutationCreator>("SolutionCreator", "The operator which should be used to create new TSP solutions.", creator));
152      Parameters.Add(new ValueParameter<ITSPEvaluator>("Evaluator", "The operator which should be used to evaluate TSP solutions.", evaluator));
153      Parameters.Add(new OptionalValueParameter<ITSPSolutionsVisualizer>("Visualizer", "The operator which should be used to visualize TSP solutions.", visualizer));
154      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this TSP instance."));
155      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));
156
157      creator.PermutationParameter.ActualName = "TSPTour";
158      evaluator.QualityParameter.ActualName = "TSPTourLength";
159      ParameterizeSolutionCreator();
160      ParameterizeEvaluator();
161      ParameterizeVisualizer();
162
163      Initialize();
164    }
165    [StorableConstructor]
166    private TravelingSalesmanProblem(bool deserializing) : base() { }
167
168    public override IDeepCloneable Clone(Cloner cloner) {
169      TravelingSalesmanProblem clone = (TravelingSalesmanProblem)base.Clone(cloner);
170      clone.Initialize();
171      return clone;
172    }
173
174    public void ImportFromTSPLIB(string tspFileName, string optimalTourFileName) {
175      TSPLIBParser tspParser = new TSPLIBParser(tspFileName);
176      tspParser.Parse();
177      Name = tspParser.Name + " TSP (imported from TSPLIB)";
178      if (!string.IsNullOrEmpty(tspParser.Comment)) Description = tspParser.Comment;
179      Coordinates = new DoubleMatrix(tspParser.Vertices);
180      if (tspParser.WeightType == TSPLIBParser.TSPLIBEdgeWeightType.EUC_2D) {
181        TSPRoundedEuclideanPathEvaluator evaluator = new TSPRoundedEuclideanPathEvaluator();
182        evaluator.QualityParameter.ActualName = "TSPTourLength";
183        Evaluator = evaluator;
184      } else if (tspParser.WeightType == TSPLIBParser.TSPLIBEdgeWeightType.GEO) {
185        TSPGeoPathEvaluator evaluator = new TSPGeoPathEvaluator();
186        evaluator.QualityParameter.ActualName = "TSPTourLength";
187        Evaluator = evaluator;
188      }
189      BestKnownQuality = null;
190      BestKnownSolution = null;
191
192      if (!string.IsNullOrEmpty(optimalTourFileName)) {
193        TSPLIBTourParser tourParser = new TSPLIBTourParser(optimalTourFileName);
194        tourParser.Parse();
195        if (tourParser.Tour.Length != Coordinates.Rows) throw new InvalidDataException("Length of optimal tour is not equal to number of cities.");
196        BestKnownSolution = new Permutation(PermutationTypes.RelativeUndirected, tourParser.Tour);
197      }
198    }
199    public void ImportFromTSPLIB(string tspFileName, string optimalTourFileName, double bestKnownQuality) {
200      ImportFromTSPLIB(tspFileName, optimalTourFileName);
201      BestKnownQuality = new DoubleValue(bestKnownQuality);
202    }
203
204    #region Events
205    public event EventHandler SolutionCreatorChanged;
206    private void OnSolutionCreatorChanged() {
207      if (SolutionCreatorChanged != null)
208        SolutionCreatorChanged(this, EventArgs.Empty);
209    }
210    public event EventHandler EvaluatorChanged;
211    private void OnEvaluatorChanged() {
212      if (EvaluatorChanged != null)
213        EvaluatorChanged(this, EventArgs.Empty);
214    }
215    public event EventHandler VisualizerChanged;
216    private void OnVisualizerChanged() {
217      if (VisualizerChanged != null)
218        VisualizerChanged(this, EventArgs.Empty);
219    }
220    public event EventHandler OperatorsChanged;
221    private void OnOperatorsChanged() {
222      if (OperatorsChanged != null)
223        OperatorsChanged(this, EventArgs.Empty);
224    }
225
226    private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) {
227      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
228      Coordinates.Reset += new EventHandler(Coordinates_Reset);
229      ParameterizeSolutionCreator();
230      ClearDistanceMatrix();
231    }
232    private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) {
233      ClearDistanceMatrix();
234    }
235    private void Coordinates_Reset(object sender, EventArgs e) {
236      ParameterizeSolutionCreator();
237      ClearDistanceMatrix();
238    }
239    private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
240      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
241      ParameterizeSolutionCreator();
242      ParameterizeEvaluator();
243      ParameterizeVisualizer();
244      ParameterizeOperators();
245      OnSolutionCreatorChanged();
246    }
247    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
248      ParameterizeEvaluator();
249      ParameterizeVisualizer();
250      ParameterizeOperators();
251    }
252    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
253      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
254      ParameterizeEvaluator();
255      UpdateMoveEvaluators();
256      ParameterizeVisualizer();
257      ClearDistanceMatrix();
258      OnEvaluatorChanged();
259    }
260    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
261      ParameterizeVisualizer();
262    }
263    private void VisualizerParameter_ValueChanged(object sender, EventArgs e) {
264      ParameterizeVisualizer();
265      OnVisualizerChanged();
266    }
267    private void MoveGenerator_InversionMoveParameter_ActualNameChanged(object sender, EventArgs e) {
268      string name = ((ILookupParameter<InversionMove>)sender).ActualName;
269      foreach (IPermutationInversionMoveOperator op in Operators.OfType<IPermutationInversionMoveOperator>()) {
270        op.InversionMoveParameter.ActualName = name;
271      }
272    }
273    private void MoveGenerator_TranslocationMoveParameter_ActualNameChanged(object sender, EventArgs e) {
274      string name = ((ILookupParameter<TranslocationMove>)sender).ActualName;
275      foreach (IPermutationTranslocationMoveOperator op in Operators.OfType<IPermutationTranslocationMoveOperator>()) {
276        op.TranslocationMoveParameter.ActualName = name;
277      }
278    }
279    #endregion
280
281    #region Helpers
282    [StorableHook(HookType.AfterDeserialization)]
283    private void Initialize() {
284      InitializeOperators();
285      CoordinatesParameter.ValueChanged += new EventHandler(CoordinatesParameter_ValueChanged);
286      Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged);
287      Coordinates.Reset += new EventHandler(Coordinates_Reset);
288      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
289      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
290      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
291      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
292      VisualizerParameter.ValueChanged += new EventHandler(VisualizerParameter_ValueChanged);
293    }
294
295    private void InitializeOperators() {
296      operators = new List<IPermutationOperator>();
297      operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>());
298      ParameterizeOperators();
299      UpdateMoveEvaluators();
300      InitializeMoveGenerators();
301    }
302    private void InitializeMoveGenerators() {
303      foreach (IPermutationInversionMoveOperator op in Operators.OfType<IPermutationInversionMoveOperator>()) {
304        if (op is IMoveGenerator) {
305          op.InversionMoveParameter.ActualNameChanged += new EventHandler(MoveGenerator_InversionMoveParameter_ActualNameChanged);
306        }
307      }
308      foreach (IPermutationTranslocationMoveOperator op in Operators.OfType<IPermutationTranslocationMoveOperator>()) {
309        if (op is IMoveGenerator) {
310          op.TranslocationMoveParameter.ActualNameChanged += new EventHandler(MoveGenerator_TranslocationMoveParameter_ActualNameChanged);
311        }
312      }
313    }
314    private void UpdateMoveEvaluators() {
315      foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>().ToList())
316        operators.Remove(op);
317      foreach (ITSPPathMoveEvaluator op in ApplicationManager.Manager.GetInstances<ITSPPathMoveEvaluator>())
318        if (op.EvaluatorType == Evaluator.GetType()) {
319          operators.Add(op);
320        }
321      ParameterizeOperators();
322      OnOperatorsChanged();
323    }
324    private void ParameterizeSolutionCreator() {
325      SolutionCreator.LengthParameter.Value = new IntValue(Coordinates.Rows);
326      SolutionCreator.PermutationTypeParameter.Value = new PermutationType(PermutationTypes.RelativeUndirected);
327    }
328    private void ParameterizeEvaluator() {
329      if (Evaluator is ITSPPathEvaluator)
330        ((ITSPPathEvaluator)Evaluator).PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
331      if (Evaluator is ITSPCoordinatesPathEvaluator) {
332        ITSPCoordinatesPathEvaluator evaluator = (ITSPCoordinatesPathEvaluator)Evaluator;
333        evaluator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
334        evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
335        evaluator.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
336      }
337    }
338    private void ParameterizeVisualizer() {
339      if (Visualizer != null) {
340        Visualizer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
341        if (Visualizer is ICoordinatesTSPSolutionsVisualizer)
342          ((ICoordinatesTSPSolutionsVisualizer)Visualizer).CoordinatesParameter.ActualName = CoordinatesParameter.Name;
343        if (Visualizer is IPathCoordinatesTSPSolutionsVisualizer)
344          ((IPathCoordinatesTSPSolutionsVisualizer)Visualizer).PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
345      }
346    }
347    private void ParameterizeOperators() {
348      foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>()) {
349        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
350        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
351      }
352      foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>()) {
353        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
354      }
355      foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>()) {
356        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
357      }
358      foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>()) {
359        op.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
360        op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
361        op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
362        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
363        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
364      }
365      string inversionMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationInversionMoveOperator>().First().InversionMoveParameter.ActualName;
366      foreach (IPermutationInversionMoveOperator op in Operators.OfType<IPermutationInversionMoveOperator>())
367        op.InversionMoveParameter.ActualName = inversionMove;
368      string translocationMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationTranslocationMoveOperator>().First().TranslocationMoveParameter.ActualName;
369      foreach (IPermutationTranslocationMoveOperator op in Operators.OfType<IPermutationTranslocationMoveOperator>())
370        op.TranslocationMoveParameter.ActualName = translocationMove;
371    }
372
373    private void ClearDistanceMatrix() {
374      DistanceMatrixParameter.Value = null;
375    }
376    #endregion
377  }
378}
Note: See TracBrowser for help on using the repository browser.