- Timestamp:
- 12/05/16 16:06:18 (8 years ago)
- Location:
- branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3
- Files:
-
- 9 deleted
- 8 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/DistanceMatrix.cs
r14185 r14454 44 44 public DistanceMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { } 45 45 public DistanceMatrix(double[,] elements) : base(elements) { } 46 public DistanceMatrix(double[,] elements, bool readOnly) : base(elements) { 47 this.readOnly = readOnly; 48 } 46 49 public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { } 47 50 public DistanceMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { } -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/HeuristicLab.Problems.TravelingSalesman-3.3.csproj
r12978 r14454 122 122 <Compile Include="Analyzers\TSPAlleleFrequencyAnalyzer.cs" /> 123 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" />128 124 <Compile Include="Improvers\TSPImprovementOperator.cs" /> 129 125 <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 126 <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 127 <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMovePathEvaluator.cs" /> 139 <Compile Include="MoveEvaluators\TwoOpt\TSPInversionMoveRoundedEuclideanPathEvaluator.cs" />140 128 <Compile Include="PathRelinkers\TSPMultipleGuidesPathRelinker.cs" /> 141 129 <Compile Include="PathRelinkers\TSPPathRelinker.cs" /> … … 145 133 <Compile Include="TravelingSalesmanProblem.cs" /> 146 134 <Compile Include="PathTSPTour.cs" /> 147 <Compile Include="Evaluators\TSPCoordinatesPathEvaluator.cs" />148 <Compile Include="Evaluators\TSPEvaluator.cs" />149 <Compile Include="Evaluators\TSPRoundedEuclideanPathEvaluator.cs" />150 135 <Compile Include="Interfaces\ITSPCoordinatesPathEvaluator.cs" /> 151 136 <Compile Include="Interfaces\ITSPEvaluator.cs" /> -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPMoveEvaluator.cs
r14185 r14454 24 24 25 25 namespace HeuristicLab.Problems.TravelingSalesman { 26 public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator { 27 Type EvaluatorType { get; } 28 } 26 public interface ITSPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator { } 29 27 } -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/Interfaces/ITSPPathMoveEvaluator.cs
r14185 r14454 26 26 namespace HeuristicLab.Problems.TravelingSalesman { 27 27 public interface ITSPPathMoveEvaluator : ITSPMoveEvaluator, IPermutationMoveOperator { 28 ILookupParameter<EnumValue<TSPDistanceFunction>> DistanceFunctionParameter { get; } 28 29 ILookupParameter<DoubleMatrix> CoordinatesParameter { get; } 29 30 ILookupParameter<DistanceMatrix> DistanceMatrixParameter { get; } -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPMoveEvaluator.cs
r14185 r14454 36 36 [StorableClass] 37 37 public abstract class TSPMoveEvaluator : SingleSuccessorOperator, ITSPMoveEvaluator, IMoveOperator { 38 39 public abstract Type EvaluatorType { get; } 38 40 39 public override bool CanChangeName { 41 40 get { return false; } -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TSPPathMoveEvaluator.cs
r14185 r14454 47 47 get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; } 48 48 } 49 public ILookupParameter<EnumValue<TSPDistanceFunction>> DistanceFunctionParameter { 50 get { return (ILookupParameter<EnumValue<TSPDistanceFunction>>)Parameters["DistanceFunction"]; } 51 } 49 52 50 53 [StorableConstructor] … … 57 60 Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities.")); 58 61 Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated (if it does not exist already) and used for evaluation, otherwise false.")); 59 } 60 61 [StorableHook(HookType.AfterDeserialization)] 62 private void AfterDeserialization() { 63 // BackwardsCompatibility3.3 64 #region Backwards compatible code (remove with 3.4) 65 LookupParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as LookupParameter<DoubleMatrix>; 66 if (oldDistanceMatrixParameter != null) { 67 Parameters.Remove(oldDistanceMatrixParameter); 68 Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities.")); 69 DistanceMatrixParameter.ActualName = oldDistanceMatrixParameter.ActualName; 70 } 71 #endregion 62 Parameters.Add(new LookupParameter<EnumValue<TSPDistanceFunction>>("DistanceFunction", "The distance function to use when the distance matrix is not being used.")); 72 63 } 73 64 74 65 public override IOperation Apply() { 75 Permutation permutation = PermutationParameter.ActualValue; 76 DoubleMatrix coordinates = CoordinatesParameter.ActualValue; 66 var permutation = PermutationParameter.ActualValue; 67 var coordinates = CoordinatesParameter.ActualValue; 68 var distanceFunction = DistanceFunctionParameter.ActualValue.Value; 77 69 double relativeQualityDifference = 0; 78 70 if (UseDistanceMatrixParameter.ActualValue.Value) { 79 71 DistanceMatrix distanceMatrix = DistanceMatrixParameter.ActualValue; 80 72 if (distanceMatrix == null) { 81 if (coordinates == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given."); 82 distanceMatrix = CalculateDistanceMatrix(coordinates); 83 DistanceMatrixParameter.ActualValue = distanceMatrix; 73 throw new InvalidOperationException("Distance matrix is not given."); 84 74 } 85 75 relativeQualityDifference = EvaluateByDistanceMatrix(permutation, distanceMatrix); 86 76 } else { 87 77 if (coordinates == null) throw new InvalidOperationException("No coordinates were given."); 88 relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates );78 relativeQualityDifference = EvaluateByCoordinates(permutation, coordinates, distanceFunction); 89 79 } 90 80 DoubleValue moveQuality = MoveQualityParameter.ActualValue; … … 93 83 return base.Apply(); 94 84 } 95 96 protected abstract double CalculateDistance(double x1, double y1, double x2, double y2);97 85 protected abstract double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix); 98 protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates); 99 100 private DistanceMatrix CalculateDistanceMatrix(DoubleMatrix c) { 101 DistanceMatrix distanceMatrix = new DistanceMatrix(c.Rows, c.Rows); 102 for (int i = 0; i < distanceMatrix.Rows; i++) { 103 for (int j = 0; j < distanceMatrix.Columns; j++) 104 distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]); 105 } 106 return (DistanceMatrix)distanceMatrix.AsReadOnly(); 107 } 86 protected abstract double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction); 108 87 } 109 88 } -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/ThreeOpt/TSPTranslocationMovePathEvaluator.cs
r14185 r14454 46 46 } 47 47 48 public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSP TranslocationMovePathEvaluator evaluator) {48 public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) { 49 49 if (move.Index1 == move.Index3 50 50 || move.Index2 == permutation.Length - 1 && move.Index3 == 0 … … 65 65 double moveQuality = 0; 66 66 // remove three edges 67 moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],67 moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1], 68 68 coordinates[edge1target, 0], coordinates[edge1target, 1]); 69 moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],69 moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge2source, 0], coordinates[edge2source, 1], 70 70 coordinates[edge2target, 0], coordinates[edge2target, 1]); 71 moveQuality -= evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],71 moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge3source, 0], coordinates[edge3source, 1], 72 72 coordinates[edge3target, 0], coordinates[edge3target, 1]); 73 73 // add three edges 74 moveQuality += evaluator.CalculateDistance(coordinates[edge3source, 0], coordinates[edge3source, 1],74 moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge3source, 0], coordinates[edge3source, 1], 75 75 coordinates[edge1target, 0], coordinates[edge1target, 1]); 76 moveQuality += evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],76 moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge2source, 0], coordinates[edge2source, 1], 77 77 coordinates[edge3target, 0], coordinates[edge3target, 1]); 78 moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],78 moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1], 79 79 coordinates[edge2target, 0], coordinates[edge2target, 1]); 80 80 return moveQuality; … … 110 110 } 111 111 112 protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates ) {113 return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, this);112 protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) { 113 return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, distanceFunction); 114 114 } 115 115 -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/MoveEvaluators/TwoOpt/TSPInversionMovePathEvaluator.cs
r14185 r14454 33 33 [Item("TSPInversionMovePathEvaluator", "Evaluates an inversion move (2-opt) by summing up the length of all added edges and subtracting the length of all deleted edges.")] 34 34 [StorableClass] 35 public abstractclass TSPInversionMovePathEvaluator : TSPPathMoveEvaluator, IPermutationInversionMoveOperator {35 public class TSPInversionMovePathEvaluator : TSPPathMoveEvaluator, IPermutationInversionMoveOperator { 36 36 public ILookupParameter<InversionMove> InversionMoveParameter { 37 37 get { return (ILookupParameter<InversionMove>)Parameters["InversionMove"]; } … … 46 46 } 47 47 48 public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPInversionMovePathEvaluator evaluator) { 48 public override IDeepCloneable Clone(Cloner cloner) { 49 return new TSPInversionMovePathEvaluator(this, cloner); 50 } 51 52 public static double EvaluateByCoordinates(Permutation permutation, InversionMove move, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) { 49 53 int edge1source = permutation.GetCircular(move.Index1 - 1); 50 54 int edge1target = permutation[move.Index1]; … … 54 58 double moveQuality = 0; 55 59 // remove two edges 56 moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],60 moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1], 57 61 coordinates[edge1target, 0], coordinates[edge1target, 1]); 58 moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],62 moveQuality -= TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge2source, 0], coordinates[edge2source, 1], 59 63 coordinates[edge2target, 0], coordinates[edge2target, 1]); 60 64 // add two edges 61 moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],65 moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1source, 0], coordinates[edge1source, 1], 62 66 coordinates[edge2source, 0], coordinates[edge2source, 1]); 63 moveQuality += evaluator.CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],67 moveQuality += TravelingSalesmanProblem.CalculateDistance(distanceFunction, coordinates[edge1target, 0], coordinates[edge1target, 1], 64 68 coordinates[edge2target, 0], coordinates[edge2target, 1]); 65 69 return moveQuality; … … 82 86 } 83 87 84 protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates ) {85 return EvaluateByCoordinates(permutation, InversionMoveParameter.ActualValue, coordinates, this);88 protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, TSPDistanceFunction distanceFunction) { 89 return EvaluateByCoordinates(permutation, InversionMoveParameter.ActualValue, coordinates, distanceFunction); 86 90 } 87 91 -
branches/MemPRAlgorithm/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs
r14453 r14454 21 21 22 22 using System; 23 using System.Collections.Generic;24 23 using System.IO; 25 24 using System.Linq; … … 37 36 38 37 namespace HeuristicLab.Problems.TravelingSalesman { 38 public enum TSPDistanceFunction { Euclidean, RoundedEuclidean, UpperEuclidean, Geo, DistanceMatrix }; 39 39 40 [Item("Traveling Salesman Problem (TSP)", "Represents a symmetric Traveling Salesman Problem.")] 40 [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 100)]41 [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 999)] 41 42 [StorableClass] 42 public sealed class TravelingSalesmanProblem : SingleObjectiveHeuristicOptimizationProblem<ITSPEvaluator, IPermutationCreator>, IStorableContent, 43 IProblemInstanceConsumer<TSPData> { 43 public sealed class TravelingSalesmanProblem : SingleObjectiveBasicProblem<PermutationEncoding>, IStorableContent, IProblemInstanceConsumer<TSPData> { 44 public const double PI = 3.141592; 45 public const double RADIUS = 6378.388; 44 46 private static readonly int DistanceMatrixSizeLimit = 1000; 45 public string Filename { get; set; } 47 48 public override bool Maximization { 49 get { return false; } 50 } 46 51 47 52 #region Parameter Properties 53 [Storable] 54 private IFixedValueParameter<EnumValue<TSPDistanceFunction>> distanceFunctionParameter; 55 public IFixedValueParameter<EnumValue<TSPDistanceFunction>> DistanceFunctionParameter { 56 get { return distanceFunctionParameter; } 57 } 58 [Storable] 59 private OptionalValueParameter<DoubleMatrix> coordinatesParameter; 48 60 public OptionalValueParameter<DoubleMatrix> CoordinatesParameter { 49 get { return (OptionalValueParameter<DoubleMatrix>)Parameters["Coordinates"]; } 50 } 61 get { return coordinatesParameter; } 62 } 63 [Storable] 64 private OptionalValueParameter<DistanceMatrix> distanceMatrixParameter; 51 65 public OptionalValueParameter<DistanceMatrix> DistanceMatrixParameter { 52 get { return (OptionalValueParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; } 53 } 54 public ValueParameter<BoolValue> UseDistanceMatrixParameter { 55 get { return (ValueParameter<BoolValue>)Parameters["UseDistanceMatrix"]; } 56 } 66 get { return distanceMatrixParameter; } 67 } 68 [Storable] 69 private IFixedValueParameter<BoolValue> useDistanceMatrixParameter; 70 public IFixedValueParameter<BoolValue> UseDistanceMatrixParameter { 71 get { return useDistanceMatrixParameter; } 72 } 73 [Storable] 74 private OptionalValueParameter<Permutation> bestKnownSolutionParameter; 57 75 public OptionalValueParameter<Permutation> BestKnownSolutionParameter { 58 get { return (OptionalValueParameter<Permutation>)Parameters["BestKnownSolution"]; }76 get { return bestKnownSolutionParameter; } 59 77 } 60 78 #endregion 61 79 62 80 #region Properties 81 public TSPDistanceFunction DistanceFunction { 82 get { return distanceFunctionParameter.Value.Value; } 83 set { distanceFunctionParameter.Value.Value = value; } 84 } 63 85 public DoubleMatrix Coordinates { 64 get { return CoordinatesParameter.Value; }65 set { CoordinatesParameter.Value = value; }86 get { return coordinatesParameter.Value; } 87 set { coordinatesParameter.Value = value; } 66 88 } 67 89 public DistanceMatrix DistanceMatrix { 68 get { return DistanceMatrixParameter.Value; }69 set { DistanceMatrixParameter.Value = value; }70 } 71 public BoolValueUseDistanceMatrix {72 get { return UseDistanceMatrixParameter.Value; }73 set { UseDistanceMatrixParameter.Value = value; }90 get { return distanceMatrixParameter.Value; } 91 set { distanceMatrixParameter.Value = value; } 92 } 93 public bool UseDistanceMatrix { 94 get { return useDistanceMatrixParameter.Value.Value; } 95 set { useDistanceMatrixParameter.Value.Value = value; } 74 96 } 75 97 public Permutation BestKnownSolution { 76 get { return BestKnownSolutionParameter.Value; }77 set { BestKnownSolutionParameter.Value = value; }98 get { return bestKnownSolutionParameter.Value; } 99 set { bestKnownSolutionParameter.Value = value; } 78 100 } 79 101 private BestTSPSolutionAnalyzer BestTSPSolutionAnalyzer { … … 82 104 private TSPAlleleFrequencyAnalyzer TSPAlleleFrequencyAnalyzer { 83 105 get { return Operators.OfType<TSPAlleleFrequencyAnalyzer>().FirstOrDefault(); } 84 }85 #endregion86 87 // BackwardsCompatibility3.388 #region Backwards compatible code, remove with 3.489 [Obsolete]90 [Storable(Name = "operators")]91 private IEnumerable<IOperator> oldOperators {92 get { return null; }93 set {94 if (value != null && value.Any())95 Operators.AddRange(value);96 }97 106 } 98 107 #endregion … … 102 111 private TravelingSalesmanProblem(TravelingSalesmanProblem original, Cloner cloner) 103 112 : base(original, cloner) { 113 distanceFunctionParameter = cloner.Clone(original.distanceFunctionParameter); 114 coordinatesParameter = cloner.Clone(original.coordinatesParameter); 115 distanceMatrixParameter = cloner.Clone(original.distanceMatrixParameter); 116 useDistanceMatrixParameter = cloner.Clone(original.useDistanceMatrixParameter); 117 bestKnownSolutionParameter = cloner.Clone(original.bestKnownSolutionParameter); 104 118 RegisterEventHandlers(); 105 119 } … … 107 121 return new TravelingSalesmanProblem(this, cloner); 108 122 } 109 public TravelingSalesmanProblem() 110 : base(new TSPRoundedEuclideanPathEvaluator(), new RandomPermutationCreator()) {111 Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.")); 112 Parameters.Add( new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));113 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)));114 Parameters.Add( new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance."));115 116 Maximization.Value = false;117 MaximizationParameter.Hidden = true;118 UseDistanceMatrixParameter.Hidden = true;119 DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;123 public TravelingSalesmanProblem() : base() { 124 Encoding = new PermutationEncoding("TSPTour") { Length = 16 }; 125 126 Parameters.Add(distanceFunctionParameter = new FixedValueParameter<EnumValue<TSPDistanceFunction>>("DistanceFunction", "The distance function that is used to calculate distance among the coordinates.", new EnumValue<TSPDistanceFunction>(TSPDistanceFunction.RoundedEuclidean))); 127 Parameters.Add(coordinatesParameter = new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.")); 128 Parameters.Add(distanceMatrixParameter = new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities.")); 129 Parameters.Add(useDistanceMatrixParameter = new FixedValueParameter<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))); 130 Parameters.Add(bestKnownSolutionParameter = new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution of this TSP instance.")); 131 132 useDistanceMatrixParameter.Hidden = true; 133 distanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false; 120 134 121 135 Coordinates = new DoubleMatrix(new double[,] { … … 125 139 { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 } 126 140 }); 127 128 SolutionCreator.PermutationParameter.ActualName = "TSPTour"; 141 129 142 Evaluator.QualityParameter.ActualName = "TSPTourLength"; 130 ParameterizeSolutionCreator();131 ParameterizeEvaluator();132 143 133 144 InitializeOperators(); 134 145 RegisterEventHandlers(); 135 146 } 136 137 #region Events 138 protected override void OnSolutionCreatorChanged() { 139 base.OnSolutionCreatorChanged(); 140 SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged); 141 ParameterizeSolutionCreator(); 142 ParameterizeEvaluator(); 147 148 #region Helpers 149 [StorableHook(HookType.AfterDeserialization)] 150 private void AfterDeserialization() { 151 RegisterEventHandlers(); 152 } 153 154 public override double Evaluate(Individual individual, IRandom random) { 155 var tour = individual.Permutation(Encoding.Name); 156 return Evaluate(tour); 157 } 158 159 public double Evaluate(Permutation tour) { 160 if (UseDistanceMatrix) return EvaluateWithDistanceMatrix(tour); 161 162 switch (DistanceFunction) { 163 case TSPDistanceFunction.DistanceMatrix: 164 return EvaluateWithDistanceMatrix(tour); 165 case TSPDistanceFunction.Euclidean: 166 case TSPDistanceFunction.RoundedEuclidean: 167 case TSPDistanceFunction.UpperEuclidean: 168 case TSPDistanceFunction.Geo: 169 return EvaluateWithDistanceCalculation(tour); 170 default: throw new InvalidOperationException(string.Format("Unknown distance function: {0}", DistanceFunction)); 171 } 172 } 173 174 private double EvaluateWithDistanceMatrix(Permutation tour) { 175 var distances = DistanceMatrix; 176 double length = 0; 177 for (var i = 0; i < tour.Length - 1; i++) 178 length += distances[tour[i], tour[i + 1]]; 179 length += distances[tour[tour.Length - 1], tour[0]]; 180 return length; 181 } 182 183 private double EvaluateWithDistanceCalculation(Permutation tour) { 184 var coordinates = Coordinates; 185 var distanceFunction = DistanceFunction; 186 double length = 0; 187 for (var i = 0; i < tour.Length - 1; i++) 188 length += CalculateDistance(distanceFunction, coordinates[tour[i], 0], coordinates[tour[i], 1], coordinates[tour[i + 1], 0], coordinates[tour[i + 1], 1]); 189 length += CalculateDistance(distanceFunction, coordinates[tour[tour.Length - 1], 0], coordinates[tour[tour.Length - 1], 1], coordinates[tour[0], 0], coordinates[tour[0], 1]); 190 return length; 191 } 192 193 private void RegisterEventHandlers() { 194 coordinatesParameter.ValueChanged += coordinatesParameter_ValueChanged; 195 if (Coordinates != null) { 196 Coordinates.ItemChanged += Coordinates_ItemChanged; 197 Coordinates.Reset += Coordinates_Reset; 198 } 199 Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged; 200 } 201 202 private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) { 143 203 ParameterizeAnalyzers(); 144 204 ParameterizeOperators(); 145 205 } 146 protected override void OnEvaluatorChanged() { 147 base.OnEvaluatorChanged(); 148 Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged); 149 ParameterizeEvaluator(); 150 ParameterizeSolutionCreator(); 151 UpdateMoveEvaluators(); 152 ParameterizeAnalyzers(); 153 if (Evaluator is ITSPCoordinatesPathEvaluator && Coordinates != null) 154 ClearDistanceMatrix(); 155 } 156 private void CoordinatesParameter_ValueChanged(object sender, EventArgs e) { 206 207 private void Coordinates_Reset(object sender, EventArgs e) { 208 DistanceMatrix = null; 209 } 210 211 private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) { 212 DistanceMatrix = null; 213 } 214 215 private void coordinatesParameter_ValueChanged(object sender, EventArgs e) { 157 216 if (Coordinates != null) { 158 217 Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged); 159 218 Coordinates.Reset += new EventHandler(Coordinates_Reset); 160 } 161 if (Evaluator is ITSPCoordinatesPathEvaluator) { 162 ParameterizeSolutionCreator(); 163 ClearDistanceMatrix(); 164 } 165 } 166 private void Coordinates_ItemChanged(object sender, EventArgs<int, int> e) { 167 if (Evaluator is ITSPCoordinatesPathEvaluator) { 168 ClearDistanceMatrix(); 169 } 170 } 171 private void Coordinates_Reset(object sender, EventArgs e) { 172 if (Evaluator is ITSPCoordinatesPathEvaluator) { 173 ParameterizeSolutionCreator(); 174 ClearDistanceMatrix(); 175 } 176 } 177 private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) { 178 ParameterizeEvaluator(); 179 ParameterizeAnalyzers(); 180 ParameterizeOperators(); 181 } 182 private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) { 183 ParameterizeAnalyzers(); 184 } 185 #endregion 186 187 #region Helpers 188 [StorableHook(HookType.AfterDeserialization)] 189 private void AfterDeserialization() { 190 // BackwardsCompatibility3.3 191 #region Backwards compatible code (remove with 3.4) 192 OptionalValueParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as OptionalValueParameter<DoubleMatrix>; 193 if (oldDistanceMatrixParameter != null) { 194 Parameters.Remove(oldDistanceMatrixParameter); 195 Parameters.Add(new OptionalValueParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities.")); 196 DistanceMatrixParameter.GetsCollected = oldDistanceMatrixParameter.GetsCollected; 197 DistanceMatrixParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false; 198 if (oldDistanceMatrixParameter.Value != null) { 199 DoubleMatrix oldDM = oldDistanceMatrixParameter.Value; 200 DistanceMatrix newDM = new DistanceMatrix(oldDM.Rows, oldDM.Columns, oldDM.ColumnNames, oldDM.RowNames); 201 newDM.SortableView = oldDM.SortableView; 202 for (int i = 0; i < newDM.Rows; i++) 203 for (int j = 0; j < newDM.Columns; j++) 204 newDM[i, j] = oldDM[i, j]; 205 DistanceMatrixParameter.Value = (DistanceMatrix)newDM.AsReadOnly(); 206 } 207 } 208 209 ValueParameter<DoubleMatrix> oldCoordinates = (Parameters["Coordinates"] as ValueParameter<DoubleMatrix>); 210 if (oldCoordinates != null) { 211 Parameters.Remove(oldCoordinates); 212 Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.", oldCoordinates.Value, oldCoordinates.GetsCollected)); 213 } 214 215 if (Operators.Count == 0) InitializeOperators(); 216 #endregion 217 RegisterEventHandlers(); 218 } 219 220 private void RegisterEventHandlers() { 221 CoordinatesParameter.ValueChanged += new EventHandler(CoordinatesParameter_ValueChanged); 222 if (Coordinates != null) { 223 Coordinates.ItemChanged += new EventHandler<EventArgs<int, int>>(Coordinates_ItemChanged); 224 Coordinates.Reset += new EventHandler(Coordinates_Reset); 225 } 226 SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged); 227 Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged); 219 DistanceMatrix = null; 220 } 228 221 } 229 222 … … 239 232 Operators.Add(new TSPAlleleFrequencyAnalyzer()); 240 233 Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>())); 234 Operators.AddRange(ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>()); 235 241 236 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 237 ParameterizeOperators(); 251 238 UpdateMoveEvaluators(); 252 239 } 253 240 private void UpdateMoveEvaluators() { 254 Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);255 foreach (var op in ApplicationManager.Manager.GetInstances<ITSPMoveEvaluator>())256 if (op.EvaluatorType == Evaluator.GetType()) {257 Operators.Add(op);258 }259 241 ParameterizeOperators(); 260 242 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 243 } 300 244 private void ParameterizeAnalyzers() { 301 245 if (BestTSPSolutionAnalyzer != null) { 302 246 BestTSPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; 303 BestTSPSolutionAnalyzer.CoordinatesParameter.ActualName = CoordinatesParameter.Name;304 BestTSPSolutionAnalyzer.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;247 BestTSPSolutionAnalyzer.CoordinatesParameter.ActualName = coordinatesParameter.Name; 248 BestTSPSolutionAnalyzer.PermutationParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName; 305 249 BestTSPSolutionAnalyzer.ResultsParameter.ActualName = "Results"; 306 250 BestTSPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name; 307 BestTSPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;308 BestTSPSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;251 BestTSPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = bestKnownSolutionParameter.Name; 252 BestTSPSolutionAnalyzer.MaximizationParameter.ActualName = ((ISingleObjectiveHeuristicOptimizationProblem)this).MaximizationParameter.Name; 309 253 } 310 254 311 255 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;256 TSPAlleleFrequencyAnalyzer.MaximizationParameter.ActualName = ((ISingleObjectiveHeuristicOptimizationProblem)this).MaximizationParameter.Name; 257 TSPAlleleFrequencyAnalyzer.CoordinatesParameter.ActualName = coordinatesParameter.Name; 258 TSPAlleleFrequencyAnalyzer.DistanceMatrixParameter.ActualName = distanceMatrixParameter.Name; 259 TSPAlleleFrequencyAnalyzer.SolutionParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName; 316 260 TSPAlleleFrequencyAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; 317 TSPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;261 TSPAlleleFrequencyAnalyzer.BestKnownSolutionParameter.ActualName = bestKnownSolutionParameter.Name; 318 262 TSPAlleleFrequencyAnalyzer.ResultsParameter.ActualName = "Results"; 319 263 } 320 264 } 321 265 private void ParameterizeOperators() { 322 foreach (IPermutationCrossover op in Operators.OfType<IPermutationCrossover>()) {323 op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;324 op.ParentsParameter.Hidden = true;325 op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;326 op.ChildParameter.Hidden = true;327 }328 foreach (IPermutationManipulator op in Operators.OfType<IPermutationManipulator>()) {329 op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;330 op.PermutationParameter.Hidden = true;331 }332 foreach (IPermutationMoveOperator op in Operators.OfType<IPermutationMoveOperator>()) {333 op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;334 op.PermutationParameter.Hidden = true;335 }336 266 foreach (ITSPPathMoveEvaluator op in Operators.OfType<ITSPPathMoveEvaluator>()) { 337 op.CoordinatesParameter.ActualName = CoordinatesParameter.Name; 267 op.DistanceFunctionParameter.ActualName = distanceFunctionParameter.Name; 268 op.DistanceFunctionParameter.Hidden = true; 269 op.CoordinatesParameter.ActualName = coordinatesParameter.Name; 338 270 op.CoordinatesParameter.Hidden = true; 339 op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;271 op.DistanceMatrixParameter.ActualName = distanceMatrixParameter.Name; 340 272 op.DistanceMatrixParameter.Hidden = true; 341 op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;273 op.UseDistanceMatrixParameter.ActualName = useDistanceMatrixParameter.Name; 342 274 op.UseDistanceMatrixParameter.Hidden = true; 343 275 op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName; 344 276 op.QualityParameter.Hidden = true; 345 op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;277 op.PermutationParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName; 346 278 op.PermutationParameter.Hidden = true; 347 279 } 348 foreach (IPermutationMultiNeighborhoodShakingOperator op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()) {349 op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;350 op.PermutationParameter.Hidden = true;351 }352 280 foreach (ISingleObjectiveImprovementOperator op in Operators.OfType<ISingleObjectiveImprovementOperator>()) { 353 op.SolutionParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;281 op.SolutionParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName; 354 282 op.SolutionParameter.Hidden = true; 355 283 } 356 284 foreach (ISingleObjectivePathRelinker op in Operators.OfType<ISingleObjectivePathRelinker>()) { 357 op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;285 op.ParentsParameter.ActualName = Encoding.SolutionCreator.PermutationParameter.ActualName; 358 286 op.ParentsParameter.Hidden = true; 359 287 } 360 288 foreach (ISolutionSimilarityCalculator op in Operators.OfType<ISolutionSimilarityCalculator>()) { 361 op.SolutionVariableName = SolutionCreator.PermutationParameter.ActualName;289 op.SolutionVariableName = Encoding.SolutionCreator.PermutationParameter.ActualName; 362 290 op.QualityVariableName = Evaluator.QualityParameter.ActualName; 363 291 } 364 292 } 365 293 366 private void ClearDistanceMatrix() { 367 DistanceMatrixParameter.Value = null; 294 public void UpdateDistanceMatrix() { 295 var df = DistanceFunction; 296 var c = Coordinates; 297 if (c == null) throw new InvalidOperationException("No coordinates are given to calculate distance matrix."); 298 DistanceMatrix = CalculateDistanceMatrix(df, c); 299 } 300 301 public static DistanceMatrix CalculateDistanceMatrix(TSPDistanceFunction distance, DoubleMatrix coordinates) { 302 var dm = new double[coordinates.Rows, coordinates.Rows]; 303 for (var i = 0; i < dm.GetLength(0); i++) { 304 for (var j = 0; j < dm.GetLength(1); j++) 305 dm[i, j] = CalculateDistance(distance, coordinates[i, 0], coordinates[i, 1], coordinates[j, 0], coordinates[j, 1]); 306 } 307 return new DistanceMatrix(dm, readOnly: true); 368 308 } 369 309 #endregion … … 381 321 Name = data.Name; 382 322 Description = data.Description; 383 384 bool clearCoordinates = false, clearDistanceMatrix = false; 323 385 324 if (data.Coordinates != null && data.Coordinates.GetLength(0) > 0) 386 325 Coordinates = new DoubleMatrix(data.Coordinates); 387 else clearCoordinates = true; 388 389 TSPEvaluator evaluator; 326 else Coordinates = null; 327 390 328 if (data.DistanceMeasure == DistanceMeasure.Att 391 329 || data.DistanceMeasure == DistanceMeasure.Manhattan 392 330 || data.DistanceMeasure == DistanceMeasure.Maximum) { 393 evaluator = new TSPDistanceMatrixEvaluator(); 394 UseDistanceMatrix = new BoolValue(true); 331 UseDistanceMatrix = true; 395 332 DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix()); 333 DistanceFunction = TSPDistanceFunction.DistanceMatrix; 396 334 } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) { 397 evaluator = new TSPDistanceMatrixEvaluator(); 398 UseDistanceMatrix = new BoolValue(true); 335 UseDistanceMatrix = true; 399 336 DistanceMatrix = new DistanceMatrix(data.Distances); 337 DistanceFunction = TSPDistanceFunction.DistanceMatrix; 400 338 } else { 401 clearDistanceMatrix = true; 402 UseDistanceMatrix = new BoolValue(data.Dimension <= DistanceMatrixSizeLimit); 339 UseDistanceMatrix = data.Dimension <= DistanceMatrixSizeLimit; 403 340 switch (data.DistanceMeasure) { 404 341 case DistanceMeasure.Euclidean: 405 evaluator = new TSPEuclideanPathEvaluator();342 DistanceFunction = TSPDistanceFunction.Euclidean; 406 343 break; 407 344 case DistanceMeasure.RoundedEuclidean: 408 evaluator = new TSPRoundedEuclideanPathEvaluator();345 DistanceFunction = TSPDistanceFunction.RoundedEuclidean; 409 346 break; 410 347 case DistanceMeasure.UpperEuclidean: 411 evaluator = new TSPUpperEuclideanPathEvaluator();348 DistanceFunction = TSPDistanceFunction.UpperEuclidean; 412 349 break; 413 350 case DistanceMeasure.Geo: 414 evaluator = new TSPGeoPathEvaluator();351 DistanceFunction = TSPDistanceFunction.Geo; 415 352 break; 416 353 default: 417 354 throw new InvalidDataException("An unknown distance measure is given in the instance!"); 418 355 } 419 } 420 evaluator.QualityParameter.ActualName = "TSPTourLength"; 421 Evaluator = evaluator; 422 423 // reset them after assigning the evaluator 424 if (clearCoordinates) Coordinates = null; 425 if (clearDistanceMatrix) DistanceMatrix = null; 426 356 if (UseDistanceMatrix) UpdateDistanceMatrix(); 357 else DistanceMatrix = null; 358 } 359 Evaluator.QualityParameter.ActualName = "TSPTourLength"; 360 427 361 BestKnownSolution = null; 428 BestKnownQuality = null;362 BestKnownQualityParameter.Value = null; 429 363 430 364 if (data.BestKnownTour != null) { … … 433 367 } catch (InvalidOperationException) { 434 368 if (data.BestKnownQuality.HasValue) 435 BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);369 BestKnownQuality = data.BestKnownQuality.Value; 436 370 } 437 371 } else if (data.BestKnownQuality.HasValue) { 438 BestKnownQuality = new DoubleValue(data.BestKnownQuality.Value);372 BestKnownQuality = data.BestKnownQuality.Value; 439 373 } 440 374 OnReset(); … … 444 378 var route = new Permutation(PermutationTypes.RelativeUndirected, tour); 445 379 BestKnownSolution = route; 446 447 double quality; 448 if (Evaluator is ITSPDistanceMatrixEvaluator) { 449 quality = TSPDistanceMatrixEvaluator.Apply(DistanceMatrix, route); 450 } else if (Evaluator is ITSPCoordinatesPathEvaluator) { 451 quality = TSPCoordinatesPathEvaluator.Apply((TSPCoordinatesPathEvaluator)Evaluator, Coordinates, route); 452 } else { 453 throw new InvalidOperationException("Cannot calculate solution quality, evaluator type is unknown."); 454 } 455 BestKnownQuality = new DoubleValue(quality); 380 BestKnownQuality = Evaluate(route); 381 } 382 383 public static double CalculateDistance(TSPDistanceFunction distanceFunction, double x1, double y1, double x2, double y2) { 384 switch (distanceFunction) { 385 case TSPDistanceFunction.Euclidean: 386 return CalculateEuclideanDistance(x1, y1, x2, y2); 387 case TSPDistanceFunction.RoundedEuclidean: 388 return CalculateRoundedEuclideanDistance(x1, y1, x2, y2); 389 case TSPDistanceFunction.UpperEuclidean: 390 return CalculateUpperEuclideanDistance(x1, y1, x2, y2); 391 case TSPDistanceFunction.Geo: 392 return CalculateGeoDistance(x1, y1, x2, y2); 393 default: throw new ArgumentException(string.Format("Distance calculation not available for {0}", distanceFunction)); 394 } 395 } 396 397 public static double CalculateEuclideanDistance(double x1, double y1, double x2, double y2) { 398 return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 399 } 400 401 public static double CalculateRoundedEuclideanDistance(double x1, double y1, double x2, double y2) { 402 return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); 403 } 404 405 public static double CalculateUpperEuclideanDistance(double x1, double y1, double x2, double y2) { 406 return Math.Ceiling(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); 407 } 408 409 public static double CalculateGeoDistance(double x1, double y1, double x2, double y2) { 410 double latitude1, longitude1, latitude2, longitude2; 411 double q1, q2, q3; 412 double length; 413 414 latitude1 = ConvertToRadian(x1); 415 longitude1 = ConvertToRadian(y1); 416 latitude2 = ConvertToRadian(x2); 417 longitude2 = ConvertToRadian(y2); 418 419 q1 = Math.Cos(longitude1 - longitude2); 420 q2 = Math.Cos(latitude1 - latitude2); 421 q3 = Math.Cos(latitude1 + latitude2); 422 423 length = (int)(RADIUS * Math.Acos(0.5 * ((1.0 + q1) * q2 - (1.0 - q1) * q3)) + 1.0); 424 return (length); 425 } 426 427 private static double ConvertToRadian(double x) { 428 return PI * (Math.Truncate(x) + 5.0 * (x - Math.Truncate(x)) / 3.0) / 180.0; 456 429 } 457 430 }
Note: See TracChangeset
for help on using the changeset viewer.