Changeset 13470 for branches/PTSP/HeuristicLab.Problems.PTSP/3.3/PTSP.cs
- Timestamp:
- 12/15/15 16:38:08 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PTSP/HeuristicLab.Problems.PTSP/3.3/PTSP.cs
r13412 r13470 21 21 22 22 using System; 23 using System.Linq; 23 24 using HeuristicLab.Common; 24 25 using HeuristicLab.Core; … … 35 36 public abstract class ProbabilisticTravelingSalesmanProblem : SingleObjectiveBasicProblem<PermutationEncoding>, 36 37 IProblemInstanceConsumer<PTSPData> { 38 protected bool SuppressEvents { get; set; } 39 37 40 private static readonly int DistanceMatrixSizeLimit = 1000; 38 41 … … 92 95 [StorableConstructor] 93 96 protected ProbabilisticTravelingSalesmanProblem(bool deserializing) : base(deserializing) { } 94 protected ProbabilisticTravelingSalesmanProblem(ProbabilisticTravelingSalesmanProblem original, Cloner cloner) : base(original, cloner) { } 97 protected ProbabilisticTravelingSalesmanProblem(ProbabilisticTravelingSalesmanProblem original, Cloner cloner) 98 : base(original, cloner) { 99 RegisterEventHandlers(); 100 } 95 101 protected ProbabilisticTravelingSalesmanProblem() { 96 102 Parameters.Add(new OptionalValueParameter<DoubleMatrix>("Coordinates", "The x- and y-Coordinates of the cities.")); … … 101 107 Parameters.Add(new ValueParameter<DoubleArray>("Probabilities", "This list describes for each city the probability of appearing in a realized instance.")); 102 108 103 Coordinates = new DoubleMatrix(new double[,] {109 var coordinates = new DoubleMatrix(new double[,] { 104 110 { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 }, 105 111 { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 }, … … 107 113 { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 } 108 114 }); 109 110 Probabilities = new DoubleArray(new double[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }); 115 Coordinates = coordinates; 116 Encoding.Length = coordinates.Rows; 117 DistanceCalculator = new EuclideanDistance(); 118 DistanceMatrix = new DistanceMatrix(CalculateDistances()); 119 Probabilities = new DoubleArray(Enumerable.Range(0, coordinates.Rows).Select(x => 0.5).ToArray()); 120 121 RegisterEventHandlers(); 122 } 123 124 [StorableHook(HookType.AfterDeserialization)] 125 private void AfterDeserialization() { 126 RegisterEventHandlers(); 127 } 128 129 private void RegisterEventHandlers() { 130 CoordinatesParameter.ValueChanged += CoordinatesParameterOnValueChanged; 131 if (Coordinates != null) { 132 Coordinates.RowsChanged += CoordinatesOnChanged; 133 Coordinates.ItemChanged += CoordinatesOnChanged; 134 } 135 UseDistanceMatrixParameter.Value.ValueChanged += UseDistanceMatrixValueChanged; 136 DistanceCalculatorParameter.ValueChanged += DistanceCalculatorParameterOnValueChanged; 137 } 138 139 private void CoordinatesParameterOnValueChanged(object sender, EventArgs eventArgs) { 140 if (Coordinates != null) { 141 Coordinates.RowsChanged += CoordinatesOnChanged; 142 Coordinates.ItemChanged += CoordinatesOnChanged; 143 } 144 if (SuppressEvents) return; 145 UpdateInstance(); 146 } 147 148 private void CoordinatesOnChanged(object sender, EventArgs eventArgs) { 149 if (SuppressEvents) return; 150 UpdateInstance(); 151 } 152 153 private void UseDistanceMatrixValueChanged(object sender, EventArgs eventArgs) { 154 if (SuppressEvents) return; 155 UpdateInstance(); 156 } 157 158 private void DistanceCalculatorParameterOnValueChanged(object sender, EventArgs eventArgs) { 159 if (SuppressEvents) return; 160 UpdateInstance(); 111 161 } 112 162 … … 117 167 public abstract double Evaluate(Permutation tour, IRandom random); 118 168 169 public double[,] CalculateDistances() { 170 var coords = Coordinates; 171 var len = coords.Rows; 172 var dist = DistanceCalculator; 173 174 var matrix = new double[len, len]; 175 for (var i = 0; i < len - 1; i++) 176 for (var j = i + 1; j < len; j++) 177 matrix[i, j] = matrix[j, i] = dist.Calculate(i, j, coords); 178 179 return matrix; 180 } 181 119 182 public virtual void Load(PTSPData data) { 120 if (data.Coordinates == null && data.Distances == null) 121 throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!"); 122 if (data.Dimension > DistanceMatrixSizeLimit && (data.Coordinates == null || data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2)) 123 throw new System.IO.InvalidDataException("The given instance is too large for using a distance matrix and there is a problem with the coordinates."); 124 if (data.Coordinates != null && (data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2)) 125 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 respectively."); 126 127 switch (data.DistanceMeasure) { 128 case DistanceMeasure.Direct: 129 DistanceCalculator = null; 130 if (data.Dimension > DistanceMatrixSizeLimit && Coordinates != null) { 131 DistanceCalculator = new EuclideanDistance(); 132 UseDistanceMatrix = false; 133 } else UseDistanceMatrix = true; 134 break; 135 case DistanceMeasure.Att: DistanceCalculator = new AttDistance(); break; 136 case DistanceMeasure.Euclidean: DistanceCalculator = new EuclideanDistance(); break; 137 case DistanceMeasure.Geo: DistanceCalculator = new GeoDistance(); break; 138 case DistanceMeasure.Manhattan: DistanceCalculator = new ManhattanDistance(); break; 139 case DistanceMeasure.Maximum: DistanceCalculator = new MaximumDistance(); break; 140 case DistanceMeasure.RoundedEuclidean: DistanceCalculator = new RoundedEuclideanDistance(); break; 141 case DistanceMeasure.UpperEuclidean: DistanceCalculator = new UpperEuclideanDistance(); break; 142 default: throw new ArgumentException("Distance measure is unknown"); 143 } 144 145 Name = data.Name; 146 Description = data.Description; 147 148 Probabilities = new DoubleArray(data.Probabilities); 149 BestKnownSolution = data.BestKnownTour != null ? new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour) : null; 150 Coordinates = data.Coordinates != null && data.Coordinates.GetLength(0) > 0 ? new DoubleMatrix(data.Coordinates) : null; 151 DistanceMatrix = new DistanceMatrix(data.GetDistanceMatrix()); 152 153 Encoding.Length = data.Dimension; 154 183 try { 184 SuppressEvents = true; 185 if (data.Coordinates == null && data.Distances == null) 186 throw new System.IO.InvalidDataException("The given instance specifies neither coordinates nor distances!"); 187 if (data.Dimension > DistanceMatrixSizeLimit && (data.Coordinates == null || data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2)) 188 throw new System.IO.InvalidDataException("The given instance is too large for using a distance matrix and there is a problem with the coordinates."); 189 if (data.Coordinates != null && (data.Coordinates.GetLength(0) != data.Dimension || data.Coordinates.GetLength(1) != 2)) 190 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 respectively."); 191 192 switch (data.DistanceMeasure) { 193 case DistanceMeasure.Direct: 194 DistanceCalculator = null; 195 if (data.Dimension > DistanceMatrixSizeLimit && Coordinates != null) { 196 DistanceCalculator = new EuclideanDistance(); 197 UseDistanceMatrix = false; 198 } else UseDistanceMatrix = true; 199 break; 200 case DistanceMeasure.Att: DistanceCalculator = new AttDistance(); break; 201 case DistanceMeasure.Euclidean: DistanceCalculator = new EuclideanDistance(); break; 202 case DistanceMeasure.Geo: DistanceCalculator = new GeoDistance(); break; 203 case DistanceMeasure.Manhattan: DistanceCalculator = new ManhattanDistance(); break; 204 case DistanceMeasure.Maximum: DistanceCalculator = new MaximumDistance(); break; 205 case DistanceMeasure.RoundedEuclidean: DistanceCalculator = new RoundedEuclideanDistance(); break; 206 case DistanceMeasure.UpperEuclidean: DistanceCalculator = new UpperEuclideanDistance(); break; 207 default: throw new ArgumentException("Distance measure is unknown"); 208 } 209 210 Name = data.Name; 211 Description = data.Description; 212 213 Probabilities = new DoubleArray(data.Probabilities); 214 BestKnownSolution = data.BestKnownTour != null ? new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour) : null; 215 Coordinates = data.Coordinates != null && data.Coordinates.GetLength(0) > 0 ? new DoubleMatrix(data.Coordinates) : null; 216 DistanceMatrix = data.Dimension <= DistanceMatrixSizeLimit && UseDistanceMatrix ? new DistanceMatrix(data.GetDistanceMatrix()) : null; 217 218 Encoding.Length = data.Dimension; 219 } finally { SuppressEvents = false; } 155 220 OnReset(); 221 } 222 223 private void UpdateInstance() { 224 var len = GetProblemDimension(); 225 if (Coordinates != null && Coordinates.Rows <= DistanceMatrixSizeLimit 226 && DistanceCalculator != null && UseDistanceMatrix) 227 DistanceMatrix = new DistanceMatrix(CalculateDistances()); 228 if (!UseDistanceMatrix) DistanceMatrix = null; 229 Encoding.Length = len; 230 231 OnReset(); 232 } 233 234 private int GetProblemDimension() { 235 if (Coordinates == null && DistanceMatrix == null) throw new InvalidOperationException("Both coordinates and distance matrix are null, please specify at least one of them."); 236 return Coordinates != null ? Coordinates.Rows : DistanceMatrix.Rows; 156 237 } 157 238 }
Note: See TracChangeset
for help on using the changeset viewer.