Changeset 13412 for branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPTwoPointFiveMoveEvaluator.cs
- Timestamp:
- 11/28/15 23:38:51 (8 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/TwoPointFiveOpt/PTSPTwoPointFiveMoveEvaluator.cs
r13408 r13412 20 20 #endregion 21 21 22 using System;23 22 using HeuristicLab.Common; 24 23 using HeuristicLab.Core; … … 27 26 using HeuristicLab.Parameters; 28 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 29 using HeuristicLab.Optimization;30 using HeuristicLab.Operators;31 28 32 29 namespace HeuristicLab.Problems.PTSP { 33 /// <summary> 34 /// A base class for operators which evaluate TSP solutions. 35 /// </summary> 36 [Item("PTSP25MoveEvaluator", "Operator that evaluates 2.5-p-opt moves of PTSP")] 30 [Item("PTSP 2.5-MoveEvaluator", "Operator that evaluates 2.5-p-opt moves of PTSP")] 37 31 [StorableClass] 38 public class PTSP25MoveEvaluator : SingleSuccessorOperator, I25MoveOperator, ISingleObjectiveMoveEvaluator { 39 public ILookupParameter<Permutation> PermutationParameter { 40 get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; } 41 } 42 public ILookupParameter<DoubleMatrix> CoordinatesParameter { 43 get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; } 44 } 45 public ILookupParameter<DistanceMatrix> DistanceMatrixParameter { 46 get { return (ILookupParameter<DistanceMatrix>)Parameters["DistanceMatrix"]; } 47 } 48 public ILookupParameter<BoolValue> UseDistanceMatrixParameter { 49 get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; } 50 } 51 public IValueParameter<ItemList<ItemList<IntValue>>> RealizationsParameter { 52 get { return (IValueParameter<ItemList<ItemList<IntValue>>>)Parameters["Realizations"]; } 53 } 32 public class PTSPTwoPointFiveMoveEvaluator : EstimatedPTSPMoveEvaluator, ITwoPointFiveMoveOperator { 33 54 34 public ILookupParameter<TwoPointFiveMove> TwoPointFiveMoveParameter { 55 35 get { return (ILookupParameter<TwoPointFiveMove>)Parameters["TwoPointFiveMove"]; } 56 36 } 57 public ILookupParameter<DoubleValue> QualityParameter {58 get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }59 }60 public ILookupParameter<DoubleValue> MoveQualityParameter {61 get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }62 }63 37 64 38 [StorableConstructor] 65 protected PTSP 25MoveEvaluator(bool deserializing) : base(deserializing) { }66 protected PTSP 25MoveEvaluator(PTSP25MoveEvaluator original, Cloner cloner) : base(original, cloner) { }67 public PTSP 25MoveEvaluator()39 protected PTSPTwoPointFiveMoveEvaluator(bool deserializing) : base(deserializing) { } 40 protected PTSPTwoPointFiveMoveEvaluator(PTSPTwoPointFiveMoveEvaluator original, Cloner cloner) : base(original, cloner) { } 41 public PTSPTwoPointFiveMoveEvaluator() 68 42 : base() { 69 Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));70 Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The city's coordinates."));71 Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));72 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."));73 Parameters.Add(new ValueParameter<ItemList<ItemList<IntValue>>>("Realizations", "The concrete..."));74 43 Parameters.Add(new LookupParameter<TwoPointFiveMove>("TwoPointFiveMove", "The move to evaluate.")); 75 Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of a TSP solution."));76 Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a TSP solution."));77 44 } 78 45 79 46 public override IDeepCloneable Clone(Cloner cloner) { 80 return new PTSP 25MoveEvaluator(this, cloner);47 return new PTSPTwoPointFiveMoveEvaluator(this, cloner); 81 48 } 82 49 83 [StorableHook(HookType.AfterDeserialization)] 84 private void AfterDeserialization() { 85 // BackwardsCompatibility3.3 86 #region Backwards compatible code (remove with 3.4) 87 LookupParameter<DoubleMatrix> oldDistanceMatrixParameter = Parameters["DistanceMatrix"] as LookupParameter<DoubleMatrix>; 88 if (oldDistanceMatrixParameter != null) { 89 Parameters.Remove(oldDistanceMatrixParameter); 90 Parameters.Add(new LookupParameter<DistanceMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities.")); 91 DistanceMatrixParameter.ActualName = oldDistanceMatrixParameter.ActualName; 92 } 93 #endregion 50 protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator) { 51 var move = TwoPointFiveMoveParameter.ActualValue; 52 var realizations = RealizationsParameter.ActualValue; 53 return EvaluateByCoordinates(permutation, coordinates, distanceCalculator, move, realizations); 94 54 } 95 55 96 public override IOperation Apply() { 97 Permutation permutation = PermutationParameter.ActualValue; 98 DoubleMatrix coordinates = CoordinatesParameter.ActualValue; 99 double relativeQualityDifference = 0; 100 if (UseDistanceMatrixParameter.ActualValue.Value) { 101 DistanceMatrix distanceMatrix = DistanceMatrixParameter.ActualValue; 102 if (distanceMatrix == null) { 103 if (coordinates == null) throw new InvalidOperationException("Neither a distance matrix nor coordinates were given."); 104 distanceMatrix = CalculateDistanceMatrix(coordinates); 105 DistanceMatrixParameter.ActualValue = distanceMatrix; 106 } 107 relativeQualityDifference = EvaluateByDistanceMatrix(permutation, distanceMatrix); 108 } 109 DoubleValue moveQuality = MoveQualityParameter.ActualValue; 110 if (moveQuality == null) MoveQualityParameter.ActualValue = new DoubleValue(QualityParameter.ActualValue.Value + relativeQualityDifference); 111 else moveQuality.Value = QualityParameter.ActualValue.Value + relativeQualityDifference; 112 return base.Apply(); 56 public static double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator, TwoPointFiveMove move, ItemList<BoolArray> realizations) { 57 if (move.IsInvert) { 58 return PTSPEstimatedInversionMoveEvaluator.EvaluateByCoordinates(permutation, 59 new InversionMove(move.Index1, move.Index2, move.Permutation), 60 coordinates, distanceCalculator, realizations); 61 } else { 62 return PTSPEstimatedInsertionMoveEvaluator.EvaluateByCoordinates(permutation, 63 new TranslocationMove(move.Index1, move.Index1, move.Index2), 64 coordinates, distanceCalculator, realizations); 65 } 113 66 } 114 67 115 protected double CalculateDistance(double x1, double y1, double x2, double y2) { 116 return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); 68 protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) { 69 var move = TwoPointFiveMoveParameter.ActualValue; 70 var realizations = RealizationsParameter.ActualValue; 71 return EvaluateByDistanceMatrix(permutation, distanceMatrix, move, realizations); 117 72 } 118 73 119 private static int decreaseCircularIndex(int length, int index) { 120 int result = index - 1; 121 if (result == -1) { 122 result = length - 1; 74 public static double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix, TwoPointFiveMove move, ItemList<BoolArray> realizations) { 75 if (move.IsInvert) { 76 return PTSPEstimatedInversionMoveEvaluator.EvaluateByDistanceMatrix(permutation, 77 new InversionMove(move.Index1, move.Index2, move.Permutation), 78 distanceMatrix, realizations); 79 } else { 80 return PTSPEstimatedInsertionMoveEvaluator.EvaluateByDistanceMatrix(permutation, 81 new TranslocationMove(move.Index1, move.Index1, move.Index2), 82 distanceMatrix, realizations); 123 83 } 124 return result;125 }126 127 private static int increaseCircularIndex(int length, int index) {128 int result = index + 1;129 if (result == length + 1) {130 result = 0;131 }132 return result;133 }134 135 136 public static double EvaluateInversionByDistanceMatrix(Permutation permutation, TwoPointFiveMove move, DistanceMatrix distanceMatrix, ItemList<ItemList<IntValue>> realizations) {137 double moveQuality = 0;138 int[] edges = new int[4];139 int[] indices = new int[4];140 edges[0] = permutation.GetCircular(move.Index1 - 1);141 indices[0] = decreaseCircularIndex(permutation.Length, move.Index1);142 edges[1] = permutation[move.Index1];143 indices[1] = move.Index1;144 edges[2] = permutation[move.Index2];145 indices[2] = move.Index2;146 edges[3] = permutation.GetCircular(move.Index2 + 1);147 indices[3] = increaseCircularIndex(permutation.Length, move.Index2);148 int[] aPosteriori = new int[4];149 foreach (ItemList<IntValue> realization in realizations) {150 for (int i = 0; i < edges.Length; i++) {151 if (realization[edges[i]].Value == 1) {152 aPosteriori[i] = edges[i];153 } else {154 int j = 1;155 if (i % 2 == 0) {156 // find nearest predecessor in realization if source edge157 while (realization[permutation.GetCircular(indices[i] - j)].Value == 0) {158 j++;159 }160 aPosteriori[i] = permutation.GetCircular(indices[i] - j);161 } else {162 // find nearest successor in realization if target edge163 while (realization[permutation.GetCircular(indices[i] + j)].Value == 0) {164 j++;165 }166 aPosteriori[i] = permutation.GetCircular(indices[i] + j);167 }168 }169 }170 // compute cost difference between the two a posteriori solutions171 if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3])) {172 moveQuality = moveQuality + distanceMatrix[aPosteriori[0], aPosteriori[2]] + distanceMatrix[aPosteriori[1], aPosteriori[3]] - distanceMatrix[aPosteriori[0], aPosteriori[1]] - distanceMatrix[aPosteriori[2], aPosteriori[3]];173 }174 Array.Clear(aPosteriori, 0, aPosteriori.Length);175 }176 // return average of cost differences177 return moveQuality / realizations.Count;178 }179 public static double EvaluateInsertionByDistanceMatrix(Permutation permutation, TwoPointFiveMove move, DistanceMatrix distanceMatrix, ItemList<ItemList<IntValue>> realizations) {180 Permutation afterMove = new Permutation(PermutationTypes.RelativeUndirected, permutation);181 TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index2);182 double moveQuality = 0;183 int[] edges = new int[12];184 int[] indices = new int[12];185 edges[0] = permutation.GetCircular(move.Index1 - 1);186 indices[0] = decreaseCircularIndex(permutation.Length, move.Index1);187 edges[1] = permutation[move.Index1];188 indices[1] = move.Index1;189 edges[2] = permutation[move.Index1];190 indices[2] = move.Index1;191 edges[3] = permutation.GetCircular(move.Index1 + 1);192 indices[3] = increaseCircularIndex(permutation.Length, move.Index1);193 194 edges[6] = afterMove.GetCircular(move.Index2 - 1);195 indices[6] = decreaseCircularIndex(afterMove.Length, move.Index2);196 edges[7] = afterMove[move.Index2];197 indices[7] = move.Index2;198 edges[8] = afterMove[move.Index2];199 indices[8] = move.Index2;200 edges[9] = afterMove.GetCircular(move.Index2 + 1);201 indices[9] = increaseCircularIndex(afterMove.Length, move.Index2);202 203 if (move.Index2 > move.Index1) {204 edges[4] = permutation[move.Index2];205 indices[4] = move.Index2;206 edges[5] = permutation.GetCircular(move.Index2 + 1);207 indices[5] = indices[9];208 edges[10] = afterMove.GetCircular(move.Index1 - 1);209 indices[10] = indices[0];210 edges[11] = afterMove[move.Index1];211 indices[11] = move.Index1;212 } else {213 edges[4] = permutation.GetCircular(move.Index2 - 1);214 indices[4] = indices[6];215 edges[5] = permutation[move.Index2];216 indices[5] = move.Index2;217 edges[10] = afterMove[move.Index1];218 indices[10] = move.Index1;219 edges[11] = afterMove.GetCircular(move.Index1 + 1);220 indices[11] = indices[3];221 }222 int[] aPosteriori = new int[12];223 Permutation tempPermutation;224 foreach (ItemList<IntValue> realization in realizations) {225 for (int i = 0; i < edges.Length; i++) {226 if (i < 6) {227 tempPermutation = permutation;228 } else {229 tempPermutation = afterMove;230 }231 if (realization[edges[i]].Value == 1) {232 aPosteriori[i] = edges[i];233 } else {234 int j = 1;235 if (i % 2 == 0) {236 // find nearest predecessor in realization if source edge237 while (realization[tempPermutation.GetCircular(indices[i] - j)].Value == 0) {238 j++;239 }240 aPosteriori[i] = tempPermutation.GetCircular(indices[i] - j);241 } else {242 // find nearest successor in realization if target edge243 while (realization[tempPermutation.GetCircular(indices[i] + j)].Value == 0) {244 j++;245 }246 aPosteriori[i] = tempPermutation.GetCircular(indices[i] + j);247 }248 }249 }250 if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3]) &&251 !(aPosteriori[0] == aPosteriori[4] && aPosteriori[1] == aPosteriori[5]) &&252 !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) {253 // compute cost difference between the two a posteriori solutions254 moveQuality = moveQuality + distanceMatrix[aPosteriori[6], aPosteriori[7]] + distanceMatrix[aPosteriori[8], aPosteriori[9]] + distanceMatrix[aPosteriori[10], aPosteriori[11]];255 moveQuality = moveQuality - distanceMatrix[aPosteriori[0], aPosteriori[1]] - distanceMatrix[aPosteriori[2], aPosteriori[3]] - distanceMatrix[aPosteriori[4], aPosteriori[5]];256 }257 Array.Clear(aPosteriori, 0, aPosteriori.Length);258 }259 // return average of cost differences260 return moveQuality / realizations.Count;261 }262 protected double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {263 TwoPointFiveMove currentMove = TwoPointFiveMoveParameter.ActualValue;264 if (currentMove.IsInvert) {265 return EvaluateInversionByDistanceMatrix(permutation, currentMove, distanceMatrix, RealizationsParameter.Value);266 } else {267 return EvaluateInsertionByDistanceMatrix(permutation, currentMove, distanceMatrix, RealizationsParameter.Value);268 }269 }270 271 private DistanceMatrix CalculateDistanceMatrix(DoubleMatrix c) {272 DistanceMatrix distanceMatrix = new DistanceMatrix(c.Rows, c.Rows);273 for (int i = 0; i < distanceMatrix.Rows; i++) {274 for (int j = 0; j < distanceMatrix.Columns; j++)275 distanceMatrix[i, j] = CalculateDistance(c[i, 0], c[i, 1], c[j, 0], c[j, 1]);276 }277 return (DistanceMatrix)distanceMatrix.AsReadOnly();278 84 } 279 85 }
Note: See TracChangeset
for help on using the changeset viewer.