Changeset 17241


Ignore:
Timestamp:
09/10/19 21:55:35 (13 days ago)
Author:
abeham
Message:

#2521: worked on refactoring TSP

Location:
branches/2521_ProblemRefactoring
Files:
2 added
21 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • branches/2521_ProblemRefactoring/HeuristicLab.Optimizer/3.3/StartPage.cs

    r17226 r17241  
    110110        }
    111111
     112      } catch {
     113      } finally {
    112114        OnAllSamplesLoaded();
    113       } finally {
    114115        Progress.HideFromControl(samplesListView);
    115116      }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj

    r16723 r17241  
    128128    </Compile>
    129129    <Compile Include="Plugin.cs" />
    130     <Compile Include="TravelingSalesmanProblemView.cs">
    131       <SubType>UserControl</SubType>
    132     </Compile>
    133     <Compile Include="TravelingSalesmanProblemView.Designer.cs">
    134       <DependentUpon>TravelingSalesmanProblemView.cs</DependentUpon>
    135     </Compile>
    136130    <Compile Include="Properties\AssemblyInfo.cs" />
    137131  </ItemGroup>
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/PathTSPTourView.cs

    r17226 r17241  
    2121
    2222using System;
     23using System.ComponentModel;
    2324using System.Drawing;
    2425using System.Windows.Forms;
     
    4849
    4950    protected override void DeregisterContentEvents() {
    50       Content.QualityChanged -= new EventHandler(Content_QualityChanged);
    51       Content.CoordinatesChanged -= new EventHandler(Content_CoordinatesChanged);
    52       Content.PermutationChanged -= new EventHandler(Content_PermutationChanged);
     51      Content.PropertyChanged -= ContentOnPropertyChanged;
    5352      base.DeregisterContentEvents();
    5453    }
    5554    protected override void RegisterContentEvents() {
    5655      base.RegisterContentEvents();
    57       Content.QualityChanged += new EventHandler(Content_QualityChanged);
    58       Content.CoordinatesChanged += new EventHandler(Content_CoordinatesChanged);
    59       Content.PermutationChanged += new EventHandler(Content_PermutationChanged);
     56      Content.PropertyChanged += ContentOnPropertyChanged;
    6057    }
    6158
     
    6764        tourViewHost.Content = null;
    6865      } else {
    69         qualityViewHost.Content = Content.Quality;
     66        qualityViewHost.Content = Content.TourLength;
    7067        GenerateImage();
    71         tourViewHost.Content = Content.Permutation;
     68        tourViewHost.Content = Content.Tour;
    7269      }
    7370    }
     
    8683        } else {
    8784          DoubleMatrix coordinates = Content.Coordinates;
    88           Permutation permutation = Content.Permutation;
     85          Permutation permutation = Content.Tour;
    8986          Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
    9087
     
    133130    }
    134131
    135     private void Content_QualityChanged(object sender, EventArgs e) {
     132    private void ContentOnPropertyChanged(object sender, PropertyChangedEventArgs e) {
    136133      if (InvokeRequired)
    137         Invoke(new EventHandler(Content_QualityChanged), sender, e);
    138       else
    139         qualityViewHost.Content = Content.Quality;
    140     }
    141     private void Content_CoordinatesChanged(object sender, EventArgs e) {
    142       if (InvokeRequired)
    143         Invoke(new EventHandler(Content_CoordinatesChanged), sender, e);
    144       else
    145         GenerateImage();
    146     }
    147     private void Content_PermutationChanged(object sender, EventArgs e) {
    148       if (InvokeRequired)
    149         Invoke(new EventHandler(Content_PermutationChanged), sender, e);
     134        Invoke((Action<object, PropertyChangedEventArgs>)ContentOnPropertyChanged, sender, e);
    150135      else {
    151         GenerateImage();
    152         tourViewHost.Content = Content.Permutation;
     136        switch (e.PropertyName) {
     137          case nameof(Content.Coordinates):
     138            GenerateImage();
     139            break;
     140          case nameof(Content.Tour):
     141            GenerateImage();
     142            tourViewHost.Content = Content.Tour;
     143            break;
     144          case nameof(Content.TourLength):
     145            qualityViewHost.Content = Content.TourLength;
     146            break;
     147        }
    153148      }
    154149    }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPAlleleFrequencyAnalyzer.cs

    r17226 r17241  
    2020#endregion
    2121
    22 using System;
     22using HEAL.Attic;
    2323using HeuristicLab.Analysis;
    2424using HeuristicLab.Common;
    2525using HeuristicLab.Core;
    26 using HeuristicLab.Data;
    2726using HeuristicLab.Encodings.PermutationEncoding;
    2827using HeuristicLab.Parameters;
    29 using HEAL.Attic;
    3028
    3129namespace HeuristicLab.Problems.TravelingSalesman {
     
    3432  /// </summary>
    3533  [Item("TSPAlleleFrequencyAnalyzer", "An operator for analyzing the frequency of alleles in solutions of Traveling Salesman Problems given in path representation.")]
    36   [StorableType("C1BBEC5A-27EF-4882-AEC6-0919FC2EF1DB")]
     34  [StorableType("43a9ec34-c917-43f8-bd14-4d42e2d0a458")]
    3735  public sealed class TSPAlleleFrequencyAnalyzer : AlleleFrequencyAnalyzer<Permutation> {
    38     public LookupParameter<DoubleMatrix> CoordinatesParameter {
    39       get { return (LookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
    40     }
    41     public LookupParameter<DistanceMatrix> DistanceMatrixParameter {
    42       get { return (LookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
    43     }
     36    [Storable] public ILookupParameter<ITSPData> TSPDataParameter { get; private set; }
    4437
    4538    [StorableConstructor]
    4639    private TSPAlleleFrequencyAnalyzer(StorableConstructorFlag _) : base(_) { }
    47     private TSPAlleleFrequencyAnalyzer(TSPAlleleFrequencyAnalyzer original, Cloner cloner) : base(original, cloner) { }
     40    private TSPAlleleFrequencyAnalyzer(TSPAlleleFrequencyAnalyzer original, Cloner cloner)
     41      : base(original, cloner) {
     42      TSPDataParameter = cloner.Clone(original.TSPDataParameter);
     43    }
    4844    public TSPAlleleFrequencyAnalyzer()
    4945      : base() {
    50       Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The x- and y-coordinates of the cities."));
    51       Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
     46      Parameters.Add(TSPDataParameter = new LookupParameter<ITSPData>("TSPData", "The main parameters of the TSP."));
    5247    }
    5348
     
    5752
    5853    protected override Allele[] CalculateAlleles(Permutation solution) {
     54      var tspData = TSPDataParameter.ActualValue;
    5955      Allele[] alleles = new Allele[solution.Length];
    60       DoubleMatrix coords = CoordinatesParameter.ActualValue;
    61       DistanceMatrix dm = DistanceMatrixParameter.ActualValue;
    62       if (dm == null && coords == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given.");
    6356      int source, target, h;
    6457      double impact;
     
    6861        target = solution[i + 1];
    6962        if (source > target) { h = source; source = target; target = h; }
    70         impact = dm != null ? dm[source, target] : CalculateLength(coords[source, 0], coords[source, 1], coords[target, 0], coords[target, 1]);
     63        impact = tspData.GetDistance(source, target);
    7164        alleles[i] = new Allele(source.ToString() + "-" + target.ToString(), impact);
    7265      }
     
    7467      target = solution[0];
    7568      if (source > target) { h = source; source = target; target = h; }
    76       impact = dm != null ? dm[source, target] : CalculateLength(coords[source, 0], coords[source, 1], coords[target, 0], coords[target, 1]);
     69      impact = tspData.GetDistance(source, target);
    7770      alleles[alleles.Length - 1] = new Allele(source.ToString() + "-" + target.ToString(), impact);
    7871
    7972      return alleles;
    8073    }
    81 
    82     private double CalculateLength(double x1, double y1, double x2, double y2) {
    83       return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    84     }
    8574  }
    8675}
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj

    r17239 r17241  
    118118  </ItemGroup>
    119119  <ItemGroup>
    120     <Compile Include="Analyzers\BestTSPSolutionAnalyzer.cs" />
    121     <Compile Include="Analyzers\TSPPopulationDiversityAnalyzer.cs" />
    122120    <Compile Include="Analyzers\TSPAlleleFrequencyAnalyzer.cs" />
    123     <Compile Include="DistanceMatrix.cs" />
    124     <Compile Include="Evaluators\TSPDistanceMatrixEvaluator.cs" />
    125     <Compile Include="Evaluators\TSPEuclideanPathEvaluator.cs" />
    126     <Compile Include="Evaluators\TSPGeoPathEvaluator.cs" />
    127     <Compile Include="Evaluators\TSPUpperEuclideanPathEvaluator.cs" />
    128121    <Compile Include="Improvers\TSPImprovementOperator.cs" />
    129     <Compile Include="Interfaces\ITSPDistanceMatrixEvaluator.cs" />
    130     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveDistanceMatrixEvaluator.cs" />
    131     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveEuclideanPathEvaluator.cs" />
    132     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveGeoPathEvaluator.cs" />
    133     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMovePathEvaluator.cs" />
    134     <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveRoundedEuclideanPathEvaluator.cs" />
    135     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveEuclideanPathEvaluator.cs" />
    136     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveGeoPathEvaluator.cs" />
    137     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveDistanceMatrixEvaluator.cs" />
    138     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMovePathEvaluator.cs" />
    139     <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveRoundedEuclideanPathEvaluator.cs" />
     122    <Compile Include="MoveEvaluators\ThreeOpt\TSPTranslocationMoveEvaluator.cs" />
     123    <Compile Include="MoveEvaluators\TSPMoveEvaluator.cs" />
     124    <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveEvaluator.cs" />
    140125    <Compile Include="PathRelinkers\TSPMultipleGuidesPathRelinker.cs" />
    141126    <Compile Include="PathRelinkers\TSPPathRelinker.cs" />
    142127    <Compile Include="PathRelinkers\TSPSimultaneousPathRelinker.cs" />
    143128    <Compile Include="Plugin.cs" />
    144     <Compile Include="SimilarityCalculators\TSPSimilarityCalculator.cs" />
    145     <Compile Include="TravelingSalesmanProblem.cs" />
    146     <Compile Include="PathTSPTour.cs" />
    147     <Compile Include="Evaluators\TSPCoordinatesPathEvaluator.cs" />
    148     <Compile Include="Evaluators\TSPEvaluator.cs" />
    149     <Compile Include="Evaluators\TSPRoundedEuclideanPathEvaluator.cs" />
    150     <Compile Include="Interfaces\ITSPCoordinatesPathEvaluator.cs" />
    151     <Compile Include="Interfaces\ITSPEvaluator.cs" />
    152     <Compile Include="Interfaces\ITSPMoveEvaluator.cs" />
    153     <Compile Include="Interfaces\ITSPPathEvaluator.cs" />
    154     <Compile Include="Interfaces\ITSPPathMoveEvaluator.cs" />
    155     <Compile Include="MoveEvaluators\TSPPathMoveEvaluator.cs" />
    156     <Compile Include="MoveEvaluators\TSPMoveEvaluator.cs" />
    157129    <Compile Include="Properties\AssemblyInfo.cs" />
    158130    <Compile Include="TSP.cs" />
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/Improvers/TSPImprovementOperator.cs

    r17226 r17241  
    2121
    2222using System;
     23using HEAL.Attic;
    2324using HeuristicLab.Common;
    2425using HeuristicLab.Core;
     
    2829using HeuristicLab.Optimization;
    2930using HeuristicLab.Parameters;
    30 using HEAL.Attic;
    3131
    3232namespace HeuristicLab.Problems.TravelingSalesman {
     
    3838  /// </remarks>
    3939  [Item("TSPImprovementOperator", "An operator that improves traveling salesman solutions. The operator tries to improve the traveling salesman solution by swapping two randomly chosen edges for a certain number of times.")]
    40   [StorableType("9C3B53A4-8FE7-45FC-833B-FF3DAE578010")]
     40  [StorableType("1b3cbc66-6dcc-4f61-9cbe-8b50cc54413a")]
    4141  public sealed class TSPImprovementOperator : SingleSuccessorOperator, ISingleObjectiveImprovementOperator {
    42     #region Parameter properties
    43     public ScopeParameter CurrentScopeParameter {
    44       get { return (ScopeParameter)Parameters["CurrentScope"]; }
     42   
     43    [Storable] public ILookupParameter<ITSPData> TSPDataParameter { get; private set; }
     44    [Storable] public IValueParameter<IntValue> ImprovementAttemptsParameter { get; private set; }
     45    [Storable] public ILookupParameter<IRandom> RandomParameter { get; private set; }
     46    [Storable] public IValueLookupParameter<IItem> SolutionParameter { get; private set; }
     47
     48    public int ImprovementAttempts {
     49      get { return ImprovementAttemptsParameter.Value.Value; }
     50      set { ImprovementAttemptsParameter.Value.Value = value; }
    4551    }
    46     public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
    47       get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
    48     }
    49     public IValueParameter<IntValue> ImprovementAttemptsParameter {
    50       get { return (IValueParameter<IntValue>)Parameters["ImprovementAttempts"]; }
    51     }
    52     public ILookupParameter<IRandom> RandomParameter {
    53       get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
    54     }
    55     public IValueLookupParameter<IItem> SolutionParameter {
    56       get { return (IValueLookupParameter<IItem>)Parameters["Solution"]; }
    57     }
    58     #endregion
    59 
    60     #region Properties
    61     public IScope CurrentScope {
    62       get { return CurrentScopeParameter.ActualValue; }
    63     }
    64     public DistanceMatrix DistanceMatrix {
    65       get { return DistanceMatrixParameter.ActualValue; }
    66       set { DistanceMatrixParameter.ActualValue = value; }
    67     }
    68     public IntValue ImprovementAttempts {
    69       get { return ImprovementAttemptsParameter.Value; }
    70       set { ImprovementAttemptsParameter.Value = value; }
    71     }
    72     public IRandom Random {
    73       get { return RandomParameter.ActualValue; }
    74       set { RandomParameter.ActualValue = value; }
    75     }
    76     #endregion
    7752
    7853    [StorableConstructor]
    7954    private TSPImprovementOperator(StorableConstructorFlag _) : base(_) { }
    80     private TSPImprovementOperator(TSPImprovementOperator original, Cloner cloner) : base(original, cloner) { }
     55    private TSPImprovementOperator(TSPImprovementOperator original, Cloner cloner)
     56      : base(original, cloner) {
     57      TSPDataParameter = cloner.Clone(original.TSPDataParameter);
     58      ImprovementAttemptsParameter = cloner.Clone(original.ImprovementAttemptsParameter);
     59      RandomParameter = cloner.Clone(original.RandomParameter);
     60      SolutionParameter = cloner.Clone(original.SolutionParameter);
     61    }
    8162    public TSPImprovementOperator()
    8263      : base() {
    8364      #region Create parameters
    84       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the solution to be improved."));
    85       Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
    86       Parameters.Add(new ValueParameter<IntValue>("ImprovementAttempts", "The number of improvement attempts the operator should perform.", new IntValue(100)));
    87       Parameters.Add(new LookupParameter<IRandom>("Random", "A pseudo random number generator."));
    88       Parameters.Add(new ValueLookupParameter<IItem>("Solution", "The solution to be improved. This parameter is used for name translation only."));
     65      Parameters.Add(TSPDataParameter = new LookupParameter<ITSPData>("TSPData", "The main parameters of the TSP."));
     66      Parameters.Add(ImprovementAttemptsParameter = new ValueParameter<IntValue>("ImprovementAttempts", "The number of improvement attempts the operator should perform.", new IntValue(100)));
     67      Parameters.Add(RandomParameter = new LookupParameter<IRandom>("Random", "A pseudo random number generator."));
     68      Parameters.Add(SolutionParameter = new ValueLookupParameter<IItem>("Solution", "The solution to be improved. This parameter is used for name translation only."));
    8969      #endregion
    9070    }
     
    9575
    9676    public override IOperation Apply() {
    97       var solution = CurrentScope.Variables[SolutionParameter.ActualName].Value as Permutation;
     77      var random = RandomParameter.ActualValue;
     78      var solution = ExecutionContext.Scope.Variables[SolutionParameter.ActualName].Value as Permutation;
    9879      if (solution == null)
    9980        throw new ArgumentException("Cannot improve solution because it has the wrong type.");
    10081      if (solution.PermutationType != PermutationTypes.RelativeUndirected)
    10182        throw new ArgumentException("Cannot improve solution because the permutation type is not supported.");
     83      var tspData = TSPDataParameter.ActualValue;
    10284
    103       for (int i = 0; i < ImprovementAttempts.Value; i++) {
    104         var move = StochasticInversionSingleMoveGenerator.Apply(solution, Random);
    105         double moveQualtiy = TSPInversionMovePathEvaluator.EvaluateByDistanceMatrix(solution, move, DistanceMatrix);
     85      for (int i = 0; i < ImprovementAttempts; i++) {
     86        var move = StochasticInversionSingleMoveGenerator.Apply(solution, random);
     87        double moveQualtiy = TSPInversionMoveEvaluator.CalculateTourLengthDelta(tspData, solution, move);
    10688        if (moveQualtiy < 0)
    10789          InversionManipulator.Apply(solution, move.Index1, move.Index2);
    10890      }
    10991
    110       CurrentScope.Variables.Add(new Variable("LocalEvaluatedSolutions", ImprovementAttempts));
     92      ExecutionContext.Scope.Variables.Add(new Variable("LocalEvaluatedSolutions", new IntValue(ImprovementAttempts)));
    11193
    11294      return base.Apply();
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs

    r17226 r17241  
    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 
    22 using System;
     1using HEAL.Attic;
    232using HeuristicLab.Common;
    243using HeuristicLab.Core;
    254using HeuristicLab.Data;
     5using HeuristicLab.Encodings.PermutationEncoding;
    266using HeuristicLab.Operators;
    27 using HeuristicLab.Optimization;
    287using HeuristicLab.Parameters;
    29 using HEAL.Attic;
    308
    319namespace HeuristicLab.Problems.TravelingSalesman {
    32   /// <summary>
    33   /// A base class for operators which evaluate TSP solutions.
    34   /// </summary>
    35   [Item("TSPMoveEvaluator", "A base class for operators which evaluate TSP moves.")]
    36   [StorableType("25573174-DE4B-4076-B439-CCB5F01CE652")]
    37   public abstract class TSPMoveEvaluator : SingleSuccessorOperator, ITSPMoveEvaluator, IMoveOperator {
     10  [StorableType("17477ad2-2c84-4b02-b5ac-f35ef6cc667f")]
     11  public interface ITSPMoveEvaluator : IOperator {
     12    ILookupParameter<Permutation> TSPTourParameter { get; }
     13    ILookupParameter<ITSPData> TSPDataParameter { get; }
     14    ILookupParameter<DoubleValue> TourLengthParameter { get; }
     15    ILookupParameter<DoubleValue> TourLengthWithMoveParameter { get; }
     16  }
    3817
    39     public abstract Type EvaluatorType { get; }
    40     public override bool CanChangeName {
    41       get { return false; }
    42     }
    43 
    44     public ILookupParameter<DoubleValue> QualityParameter {
    45       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
    46     }
    47     public ILookupParameter<DoubleValue> MoveQualityParameter {
    48       get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
    49     }
     18  [Item("TSP Move Evaluator", "Base class for all move evaluators of the TSP.")]
     19  [StorableType("44af3845-ccdf-4014-805a-5878c64f67f5")]
     20  public abstract class TSPMoveEvaluator : SingleSuccessorOperator, ITSPMoveEvaluator {
     21    [Storable] public ILookupParameter<Permutation> TSPTourParameter { get; private set; }
     22    [Storable] public ILookupParameter<ITSPData> TSPDataParameter { get; private set; }
     23    [Storable] public ILookupParameter<DoubleValue> TourLengthParameter { get; private set; }
     24    [Storable] public ILookupParameter<DoubleValue> TourLengthWithMoveParameter { get; private set; }
    5025
    5126    [StorableConstructor]
    5227    protected TSPMoveEvaluator(StorableConstructorFlag _) : base(_) { }
    53     protected TSPMoveEvaluator(TSPMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
    54     protected TSPMoveEvaluator()
    55       : base() {
    56       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a TSP solution."));
    57       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a TSP solution."));
     28    protected TSPMoveEvaluator(TSPMoveEvaluator original, Cloner cloner)
     29      : base(original, cloner) {
     30      TSPTourParameter = cloner.Clone(original.TSPTourParameter);
     31      TSPDataParameter = cloner.Clone(original.TSPDataParameter);
     32      TourLengthParameter = cloner.Clone(original.TourLengthParameter);
     33      TourLengthWithMoveParameter = cloner.Clone(original.TourLengthWithMoveParameter);
    5834    }
     35    public TSPMoveEvaluator() {
     36      Parameters.Add(TSPTourParameter = new LookupParameter<Permutation>("TSPTour", "The tour that describes a solution to the TSP."));
     37      Parameters.Add(TSPDataParameter = new LookupParameter<ITSPData>("TSPData", "The main parameters of the TSP."));
     38      Parameters.Add(TourLengthParameter = new LookupParameter<DoubleValue>("TourLength", "The length of a TSP tour."));
     39      Parameters.Add(TourLengthWithMoveParameter = new LookupParameter<DoubleValue>("TourLengthWithMove", "The length of the TSP tour if the move was applied."));
     40    }
     41
     42    public sealed override IOperation Apply() {
     43      var tour = TSPTourParameter.ActualValue;
     44      var tspData = TSPDataParameter.ActualValue;
     45      var tourLength = TourLengthParameter.ActualValue.Value;
     46      TourLengthWithMoveParameter.ActualValue = new DoubleValue(
     47        CalculateTourLengthWithMove(tspData, tour, tourLength)
     48      );
     49      return base.Apply();
     50    }
     51
     52    protected abstract double CalculateTourLengthWithMove(ITSPData tspData, Permutation tspTour, double tourLength);
    5953  }
    6054}
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPMultipleGuidesPathRelinker.cs

    r17226 r17241  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using HEAL.Attic;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    2930using HeuristicLab.Optimization.Operators;
    3031using HeuristicLab.Parameters;
    31 using HEAL.Attic;
    3232
    3333namespace HeuristicLab.Problems.TravelingSalesman {
     
    3939  /// </remarks>
    4040  [Item("TSPMultipleGuidesPathRelinker", "An operator that relinks paths between traveling salesman solutions using a multiple guiding strategy. The operator incrementally changes the initiating solution towards the guiding solution by correcting edges as needed. For each city it choses the best edge from all guiding solutions.")]
    41   [StorableType("6B5B2622-AB1D-47E6-8BBC-C6088D393149")]
     41  [StorableType("13e879fd-7621-402e-9345-7dbfdd78e3b6")]
    4242  public sealed class TSPMultipleGuidesPathRelinker : SingleObjectivePathRelinker {
    43     #region Parameter properties
    44     public ILookupParameter<DistanceMatrix> DistanceMatrixParameter {
    45       get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; }
    46     }
    47     #endregion
    48 
    49     #region Properties
    50     public DistanceMatrix DistanceMatrix {
    51       get { return DistanceMatrixParameter.ActualValue; }
    52     }
    53     #endregion
     43    [Storable] public ILookupParameter<ITSPData> TSPDataParameter { get; private set; }
    5444
    5545    [StorableConstructor]
    5646    private TSPMultipleGuidesPathRelinker(StorableConstructorFlag _) : base(_) { }
    57     private TSPMultipleGuidesPathRelinker(TSPMultipleGuidesPathRelinker original, Cloner cloner) : base(original, cloner) { }
     47    private TSPMultipleGuidesPathRelinker(TSPMultipleGuidesPathRelinker original, Cloner cloner)
     48      : base(original, cloner) {
     49      TSPDataParameter = cloner.Clone(original.TSPDataParameter);
     50    }
    5851    public TSPMultipleGuidesPathRelinker()
    5952      : base() {
    60       #region Create parameters
    61       Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
    62       #endregion
     53      Parameters.Add(TSPDataParameter = new LookupParameter<ITSPData>("TSPData", "The main parameters of the TSP."));
    6354    }
    6455
     
    6758    }
    6859
    69     public static ItemArray<IItem> Apply(IItem initiator, IItem[] guides, DistanceMatrix distances, PercentValue n) {
     60    public static ItemArray<IItem> Apply(IItem initiator, IItem[] guides, ITSPData tspData, PercentValue n) {
    7061      if (!(initiator is Permutation) || guides.Any(x => !(x is Permutation)))
    7162        throw new ArgumentException("Cannot relink path because some of the provided solutions have the wrong type.");
     
    8475        int currCityIndex = i;
    8576        int bestCityIndex = (i + 1) % v1.Length;
    86         double currDistance = distances[v1[currCityIndex], v1[bestCityIndex]];
     77        double currDistance = tspData.GetDistance(v1[currCityIndex], v1[bestCityIndex]);
    8778        // check each guiding solution
    8879        targets.ToList().ForEach(solution => {
     
    9283          int succ = solution[(node.Index + 1) % solution.Length];
    9384          // get distances to neighbors
    94           var results = new[] { pred, succ }.Select(x => new { Id = x, Distance = distances[x, node.Id] });
     85          var results = new[] { pred, succ }.Select(x => new { Id = x, Distance = tspData.GetDistance(x, node.Id) });
    9586          var bestCity = results.Where(x => x.Distance < currDistance).OrderBy(x => x.Distance).FirstOrDefault();
    9687          if (bestCity != null) {
     
    129120      if (parents.Length < 2)
    130121        throw new ArgumentException("The number of parents is smaller than 2.");
    131       return Apply(parents[0], parents.Skip(1).ToArray(), DistanceMatrix, n);
     122      return Apply(parents[0], parents.Skip(1).ToArray(), TSPDataParameter.ActualValue, n);
    132123    }
    133124  }
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPPathRelinker.cs

    r17226 r17241  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using HEAL.Attic;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    2829using HeuristicLab.Encodings.PermutationEncoding;
    2930using HeuristicLab.Optimization.Operators;
    30 using HEAL.Attic;
    3131
    3232namespace HeuristicLab.Problems.TravelingSalesman {
     33
    3334  /// <summary>
    3435  /// An operator that relinks paths between traveling salesman solutions.
     
    3839  /// </remarks>
    3940  [Item("TSPPathRelinker", "An operator that relinks paths between traveling salesman solutions. The operator incrementally assimilates the initiating solution into the guiding solution by correcting edges as needed.")]
    40   [StorableType("0997A24C-0592-4CE4-A681-70C97890D3F7")]
     41  [StorableType("a2c5de50-a050-4269-b80e-1c995eb51626")]
    4142  public sealed class TSPPathRelinker : SingleObjectivePathRelinker {
    4243    [StorableConstructor]
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/PathRelinkers/TSPSimultaneousPathRelinker.cs

    r17226 r17241  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using HEAL.Attic;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    2829using HeuristicLab.Encodings.PermutationEncoding;
    2930using HeuristicLab.Optimization.Operators;
    30 using HEAL.Attic;
    3131
    3232namespace HeuristicLab.Problems.TravelingSalesman {
     
    3838  /// </remarks>
    3939  [Item("TSPSimultaneousPathRelinker", "An operator that relinks paths between traveling salesman solutions starting from both ends. The operator incrementally assimilates the initiating solution into the guiding solution and vice versa by correcting edges as needed.")]
    40   [StorableType("D44D112E-5139-4848-8A2B-66CFC5784EE4")]
     40  [StorableType("73457ec0-1d71-4d9f-b646-2ba3639317e2")]
    4141  public sealed class TSPSimultaneousPathRelinker : SingleObjectivePathRelinker {
    4242    [StorableConstructor]
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs

    r17239 r17241  
    11using System;
     2using System.Linq;
    23using HEAL.Attic;
    34using HeuristicLab.Common;
     
    67using HeuristicLab.Encodings.PermutationEncoding;
    78using HeuristicLab.Optimization;
     9using HeuristicLab.Parameters;
     10using HeuristicLab.PluginInfrastructure;
    811using HeuristicLab.Problems.Instances;
    912
     
    1114  [Item("Traveling Salesman Problem (TSP)", "Represents a symmetric Traveling Salesman Problem.")]
    1215  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 100)]
    13   [StorableType("60511a03-b8b4-47cd-a119-78f97358a6b0")]
    14   public class TSP : SingleObjectiveProblem<PermutationEncoding, Permutation>, IProblemInstanceConsumer<TSPData> {
     16  [StorableType("8415476a-69de-45ad-95be-298ed7c97e84")]
     17  public class TSP : PermutationProblem, IProblemInstanceConsumer<TSPData> {
     18    /// <summary>
     19    /// This limit governs when a distance matrix is used. For all problems smaller than that, the distance matrix is
     20    /// computed. This greatly speeds up computation time.
     21    /// </summary>
    1522    public static int DistanceMatrixSizeLimit { get; set; } = 1000;
    1623
    1724    public override bool Maximization => false;
    1825
    19     [Storable]
    20     private IValueParameter<ITSPData> tspDataParameter;
    21     public IValueParameter<ITSPData> TSPDataParameter {
    22       get { return tspDataParameter; }
    23     }
    24     [Storable]
    25     private IValueParameter<Permutation> bestKnownSolutionParameter;
    26     public IValueParameter<Permutation> BestKnownSolutionParameter {
    27       get { return bestKnownSolutionParameter; }
    28     }
     26    [Storable] public IValueParameter<ITSPData> TSPDataParameter { get; private set; }
     27    [Storable] public IValueParameter<Permutation> BestKnownSolutionParameter { get; private set; }
    2928
    3029    public ITSPData TSPData {
    31       get { return tspDataParameter.Value; }
    32       set { tspDataParameter.Value = value; }
     30      get { return TSPDataParameter.Value; }
     31      set { TSPDataParameter.Value = value; }
    3332    }
    3433    public Permutation BestKnownSolution {
    35       get { return bestKnownSolutionParameter.Value; }
    36       set { bestKnownSolutionParameter.Value = value; }
     34      get { return BestKnownSolutionParameter.Value; }
     35      set { BestKnownSolutionParameter.Value = value; }
    3736    }
    3837
     
    4241    protected TSP(TSP original, Cloner cloner)
    4342      : base(original, cloner) {
    44       tspDataParameter = cloner.Clone(original.tspDataParameter);
    45       bestKnownSolutionParameter = cloner.Clone(original.bestKnownSolutionParameter);
     43      TSPDataParameter = cloner.Clone(original.TSPDataParameter);
     44      BestKnownSolutionParameter = cloner.Clone(original.BestKnownSolutionParameter);
    4645    }
    4746
    4847    public TSP() : base(new PermutationEncoding("Tour", 16, PermutationTypes.RelativeUndirected)) {
    49       TSPData = new RoundedEuclideanCoordinatesTSPData() {
     48      Parameters.Add(TSPDataParameter = new ValueParameter<ITSPData>("TSPData", "The main parameters of the TSP."));
     49      Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution."));
     50     
     51      TSPData = new EuclideanTSPData() {
    5052        Coordinates = new DoubleMatrix(new double[,] {
    5153        { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
     
    5355        { 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },
    5456        { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
    55         })
     57        }),
     58        Rounding = EuclideanTSPData.RoundingMode.Midpoint
    5659      };
     60
     61      InitializeOperators();
    5762    }
    5863
     
    7277      tourLength += TSPData.GetDistance(tour[tour.Length - 1], tour[0]);
    7378      return tourLength;
     79    }
     80
     81    public override void Analyze(Permutation[] solutions, double[] qualities, ResultCollection results, IRandom random) {
     82      base.Analyze(solutions, qualities, results, random);
     83      int i = -1;
     84      if (!Maximization)
     85        i = qualities.Select((x, index) => new { index, Fitness = x }).OrderBy(x => x.Fitness).First().index;
     86      else i = qualities.Select((x, index) => new { index, Fitness = x }).OrderByDescending(x => x.Fitness).First().index;
     87
     88      if (double.IsNaN(BestKnownQuality) ||
     89          Maximization && qualities[i] > BestKnownQuality ||
     90          !Maximization && qualities[i] < BestKnownQuality) {
     91        BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[i]);
     92        BestKnownSolutionParameter.ActualValue = (Permutation)solutions[i].Clone();
     93      }
     94
     95      var solution = TSPData.GetSolution(solutions[i], qualities[i]);
     96      results.AddOrUpdateResult("Best TSP Solution", solution);
    7497    }
    7598
     
    84107        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.");
    85108
     109      Encoding.Length = data.Dimension;
    86110      Name = data.Name;
    87111      Description = data.Description;
     
    97121        switch (data.DistanceMeasure) {
    98122          case DistanceMeasure.Euclidean:
    99             throw new NotImplementedException();
     123            TSPData = new EuclideanTSPData(data.Coordinates) { Rounding = EuclideanTSPData.RoundingMode.None };
    100124            break;
    101125          case DistanceMeasure.RoundedEuclidean:
    102             TSPData = new RoundedEuclideanCoordinatesTSPData(data.Coordinates);
     126            TSPData = new EuclideanTSPData(data.Coordinates) { Rounding = EuclideanTSPData.RoundingMode.Midpoint };
    103127            break;
    104128          case DistanceMeasure.UpperEuclidean:
    105             throw new NotImplementedException();
     129            TSPData = new EuclideanTSPData(data.Coordinates) { Rounding = EuclideanTSPData.RoundingMode.Ceiling };
    106130            break;
    107131          case DistanceMeasure.Geo:
    108             throw new NotImplementedException();
     132            TSPData = new GeoTSPData(data.Coordinates);
    109133            break;
    110134          default:
     
    128152      OnReset();
    129153    }
     154
     155    protected override void OnEncodingChanged() {
     156      base.OnEncodingChanged();
     157      ParameterizeOperators();
     158    }
     159
     160    protected override void OnEvaluatorChanged() {
     161      base.OnEvaluatorChanged();
     162      ParameterizeOperators();
     163    }
     164
     165    private void InitializeOperators() {
     166      Operators.Add(new TSPImprovementOperator());
     167      Operators.Add(new TSPMultipleGuidesPathRelinker());
     168      Operators.Add(new TSPPathRelinker());
     169      Operators.Add(new TSPSimultaneousPathRelinker());
     170
     171      Operators.Add(new TSPAlleleFrequencyAnalyzer());
     172      foreach (var op in ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>())
     173        Operators.Add(op);
     174
     175      ParameterizeOperators();
     176    }
     177
     178    private void ParameterizeOperators() {
     179      foreach (var op in Operators.OfType<TSPAlleleFrequencyAnalyzer>()) {
     180        op.MaximizationParameter.ActualName = MaximizationParameter.Name;
     181        op.TSPDataParameter.ActualName = TSPDataParameter.Name;
     182        op.SolutionParameter.ActualName = Encoding.Name;
     183        op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
     184        op.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
     185        op.ResultsParameter.ActualName = "Results";
     186      }
     187      foreach (var op in Operators.OfType<ITSPMoveEvaluator>()) {
     188        op.TSPDataParameter.ActualName = TSPDataParameter.Name;
     189        op.TSPDataParameter.Hidden = true;
     190        op.TourLengthParameter.ActualName = Evaluator.QualityParameter.ActualName;
     191        op.TourLengthParameter.Hidden = true;
     192        op.TSPTourParameter.ActualName = Encoding.Name;
     193        op.TSPTourParameter.Hidden = true;
     194      }
     195      foreach (var op in Operators.OfType<ISingleObjectiveImprovementOperator>()) {
     196        op.SolutionParameter.ActualName = Encoding.Name;
     197        op.SolutionParameter.Hidden = true;
     198      }
     199      foreach (ISingleObjectivePathRelinker op in Operators.OfType<ISingleObjectivePathRelinker>()) {
     200        op.ParentsParameter.ActualName = Encoding.Name;
     201        op.ParentsParameter.Hidden = true;
     202      }
     203      foreach (ISolutionSimilarityCalculator op in Operators.OfType<ISolutionSimilarityCalculator>()) {
     204        op.SolutionVariableName = Encoding.Name;
     205        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
     206      }
     207    }
    130208  }
    131209}
  • branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs

    r17239 r17241  
    11using System;
     2using System.ComponentModel;
     3using System.Drawing;
    24using HEAL.Attic;
    35using HeuristicLab.Common;
    46using HeuristicLab.Core;
    57using HeuristicLab.Data;
     8using HeuristicLab.Encodings.PermutationEncoding;
    69
    710namespace HeuristicLab.Problems.TravelingSalesman {
     
    912  public interface ITSPData : IItem {
    1013    double GetDistance(int fromCity, int toCity);
    11   }
    12 
    13   [Item("Coordinates-based TSP Data", "TSP that is represented by coordinates of cities.")]
    14   [StorableType("3955d07a-d43c-4a01-9505-d2effb1ea865")]
    15   public abstract class CoordinatesTSPData : Item, ITSPData {
    16     [Storable]
    17     public DoubleMatrix Coordinates { get; set; }
    18 
    19     [StorableConstructor]
    20     protected CoordinatesTSPData(StorableConstructorFlag _) : base(_) { }
    21     protected CoordinatesTSPData(CoordinatesTSPData original, Cloner cloner) : base(original, cloner) {
    22       Coordinates = cloner.Clone(original.Coordinates);
    23     }
    24     protected CoordinatesTSPData() : base() {
    25       Coordinates = new DoubleMatrix();
    26     }
    27     protected CoordinatesTSPData(double[,] coordinates) : base() {
    28       if (coordinates == null) throw new ArgumentNullException(nameof(coordinates));
    29       if (coordinates.GetLength(1) != 2) throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
    30       Coordinates = new DoubleMatrix(coordinates);
    31     }
    32 
    33     public double GetDistance(int fromCity, int toCity) {
    34       return GetDistance(Coordinates[fromCity, 0], Coordinates[fromCity, 1],
    35         Coordinates[toCity, 0], Coordinates[toCity, 1]);
    36     }
    37 
    38     public abstract double GetDistance(double fromX, double fromY, double toX, double toY);
    39   }
    40 
    41   [Item("Euclidean (rounded) TSP Data", "TSP that is represented by coordinates and a rounded euclidean distance measure.")]
    42   [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")]
    43   public sealed class RoundedEuclideanCoordinatesTSPData : CoordinatesTSPData {
    44 
    45     [StorableConstructor]
    46     private RoundedEuclideanCoordinatesTSPData(StorableConstructorFlag _) : base(_) { }
    47     private RoundedEuclideanCoordinatesTSPData(RoundedEuclideanCoordinatesTSPData original, Cloner cloner) : base(original, cloner) { }
    48     public RoundedEuclideanCoordinatesTSPData() : base() { }
    49     public RoundedEuclideanCoordinatesTSPData(double[,] coordinates) : base(coordinates) { }
    50 
    51     public override IDeepCloneable Clone(Cloner cloner) {
    52       return new RoundedEuclideanCoordinatesTSPData(this, cloner);
    53     }
    54 
    55     public override double GetDistance(double fromX, double fromY, double toX, double toY) {
    56       return Math.Round(Math.Sqrt((fromX - toX) * (fromX - toX) + (fromY - toY) * (fromY - toY)));
    57     }
     14    ITSPSolution GetSolution(Permutation tspTour, double tourLength);
     15  }
     16
     17  [StorableType("f08a63d9-0b83-4944-9251-42925baeb872")]
     18  public interface ITSPSolution : IItem {
     19    DoubleMatrix Coordinates { get; }
     20    Permutation Tour { get; }
     21    DoubleValue TourLength { get; }
    5822  }
    5923
     
    8448      if (DisplayCoordinates != null && DisplayCoordinates.Rows != Matrix.GetLength(0))
    8549        throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
     50    }
     51
     52    public ITSPSolution GetSolution(Permutation tour, double tourLength) {
     53      return new PathTSPTour(DisplayCoordinates, tour, new DoubleValue(tourLength));
    8654    }
    8755
     
    11179    public double GetDistance(int fromCity, int toCity) => Matrix[fromCity, toCity];
    11280  }
     81
     82  [Item("Coordinates-based TSP Data", "TSP that is represented by coordinates of locations.")]
     83  [StorableType("3955d07a-d43c-4a01-9505-d2effb1ea865")]
     84  public abstract class CoordinatesTSPData : Item, ITSPData {
     85    [Storable]
     86    public DoubleMatrix Coordinates { get; set; }
     87
     88    [StorableConstructor]
     89    protected CoordinatesTSPData(StorableConstructorFlag _) : base(_) { }
     90    protected CoordinatesTSPData(CoordinatesTSPData original, Cloner cloner) : base(original, cloner) {
     91      Coordinates = cloner.Clone(original.Coordinates);
     92    }
     93    protected CoordinatesTSPData() : base() {
     94      Coordinates = new DoubleMatrix();
     95    }
     96    protected CoordinatesTSPData(double[,] coordinates) : base() {
     97      if (coordinates == null) throw new ArgumentNullException(nameof(coordinates));
     98      if (coordinates.GetLength(1) != 2) throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
     99      Coordinates = new DoubleMatrix(coordinates);
     100    }
     101
     102    public double GetDistance(int fromCity, int toCity) {
     103      return GetDistance(Coordinates[fromCity, 0], Coordinates[fromCity, 1],
     104        Coordinates[toCity, 0], Coordinates[toCity, 1]);
     105    }
     106
     107    public abstract double GetDistance(double fromX, double fromY, double toX, double toY);
     108
     109    public ITSPSolution GetSolution(Permutation tour, double tourLength) {
     110      return new PathTSPTour(Coordinates, tour, new DoubleValue(tourLength));
     111    }
     112  }
     113
     114  [Item("Euclidean TSP Data", "TSP that is represented by coordinates in an Euclidean plane.")]
     115  [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")]
     116  public sealed class EuclideanTSPData : CoordinatesTSPData {
     117    public enum RoundingMode { None, Midpoint, Ceiling }
     118
     119    [Storable]
     120    public RoundingMode Rounding { get; set; }
     121
     122    [StorableConstructor]
     123    private EuclideanTSPData(StorableConstructorFlag _) : base(_) { }
     124    private EuclideanTSPData(EuclideanTSPData original, Cloner cloner) : base(original, cloner) {
     125      Rounding = original.Rounding;
     126    }
     127    public EuclideanTSPData() : base() { }
     128    public EuclideanTSPData(double[,] coordinates) : base(coordinates) { }
     129
     130    public override IDeepCloneable Clone(Cloner cloner) {
     131      return new EuclideanTSPData(this, cloner);
     132    }
     133
     134    public override double GetDistance(double fromX, double fromY, double toX, double toY) {
     135      var dist = Math.Sqrt((fromX - toX) * (fromX - toX) + (fromY - toY) * (fromY - toY));
     136      switch (Rounding) {
     137        case RoundingMode.None: return dist;
     138        case RoundingMode.Midpoint: return Math.Round(dist);
     139        case RoundingMode.Ceiling: return Math.Ceiling(dist);
     140        default: throw new InvalidOperationException("Unknown rounding mode " + Rounding);
     141      }
     142    }
     143  }
     144
     145  [Item("Geo TSP Data", "TSP that is represented by geo coordinates.")]
     146  [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")]
     147  public sealed class GeoTSPData : CoordinatesTSPData {
     148    public const double PI = 3.141592;
     149    public const double RADIUS = 6378.388;
     150
     151    [StorableConstructor]
     152    private GeoTSPData(StorableConstructorFlag _) : base(_) { }
     153    private GeoTSPData(GeoTSPData original, Cloner cloner) : base(original, cloner) { }
     154    public GeoTSPData() : base() { }
     155    public GeoTSPData(double[,] coordinates) : base(coordinates) { }
     156
     157    public override IDeepCloneable Clone(Cloner cloner) {
     158      return new GeoTSPData(this, cloner);
     159    }
     160
     161    public override double GetDistance(double fromX, double fromY, double toX, double toY) {
     162      double latitude1, longitude1, latitude2, longitude2;
     163      double q1, q2, q3;
     164      double length;
     165
     166      latitude1 = ConvertToRadian(fromX);
     167      longitude1 = ConvertToRadian(fromY);
     168      latitude2 = ConvertToRadian(toX);
     169      longitude2 = ConvertToRadian(toY);
     170
     171      q1 = Math.Cos(longitude1 - longitude2);
     172      q2 = Math.Cos(latitude1 - latitude2);
     173      q3 = Math.Cos(latitude1 + latitude2);
     174
     175      length = (int)(RADIUS * Math.Acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3)) + 1.0);
     176      return (length);
     177    }
     178
     179    private double ConvertToRadian(double x) {
     180      return PI * (Math.Truncate(x) + 5.0 * (x - Math.Truncate(x)) / 3.0) / 180.0;
     181    }
     182  }
     183  /// <summary>
     184  /// Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.
     185  /// </summary>
     186  [Item("PathTSPTour", "Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.")]
     187  [StorableType("2CAE7C49-751B-4802-9025-62E2268E47AE")]
     188  public sealed class PathTSPTour : Item, ITSPSolution, INotifyPropertyChanged {
     189    public static new Image StaticItemImage {
     190      get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; }
     191    }
     192
     193    [Storable]
     194    private DoubleMatrix coordinates;
     195    public DoubleMatrix Coordinates {
     196      get { return coordinates; }
     197      set {
     198        if (coordinates == value) return;
     199        coordinates = value;
     200        OnPropertyChanged(nameof(Coordinates));
     201      }
     202    }
     203
     204    [Storable(Name = "tour", OldName = "permutation")]
     205    private Permutation tour;
     206    public Permutation Tour {
     207      get { return tour; }
     208      set {
     209        if (tour == value) return;
     210        tour = value;
     211        OnPropertyChanged(nameof(Tour));
     212      }
     213    }
     214    [Storable(Name = "tourLength", OldName = "quality")]
     215    private DoubleValue tourLength;
     216    public DoubleValue TourLength {
     217      get { return tourLength; }
     218      set {
     219        if (tourLength == value) return;
     220        tourLength = value;
     221        OnPropertyChanged(nameof(TourLength));
     222      }
     223    }
     224
     225    [StorableConstructor]
     226    private PathTSPTour(StorableConstructorFlag _) : base(_) { }
     227    private PathTSPTour(PathTSPTour original, Cloner cloner)
     228      : base(original, cloner) {
     229      this.coordinates = cloner.Clone(original.coordinates);
     230      this.tour = cloner.Clone(original.tour);
     231      this.tourLength = cloner.Clone(original.tourLength);
     232    }
     233    public PathTSPTour() : base() { }
     234    public PathTSPTour(DoubleMatrix coordinates)
     235      : base() {
     236      this.coordinates = coordinates;
     237    }
     238    public PathTSPTour(DoubleMatrix coordinates, Permutation permutation)
     239      : base() {
     240      this.coordinates = coordinates;
     241      this.tour = permutation;
     242    }
     243    public PathTSPTour(DoubleMatrix coordinates, Permutation permutation, DoubleValue quality)
     244      : base() {
     245      this.coordinates = coordinates;
     246      this.tour = permutation;
     247      this.tourLength = quality;
     248    }
     249
     250    public override IDeepCloneable Clone(Cloner cloner) {
     251      return new PathTSPTour(this, cloner);
     252    }
     253
     254    public event PropertyChangedEventHandler PropertyChanged;
     255    private void OnPropertyChanged(string property) {
     256      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
     257    }
     258  }
    113259}
Note: See TracChangeset for help on using the changeset viewer.