Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/28/15 23:38:51 (9 years ago)
Author:
abeham
Message:

#2221:

  • Completely refactored PTSP branch
    • Added two sets of problem instances based on TSPLIB: homogeneous and heterogeneous
    • Implemented missing EvaluateByCoordinates for 1-shift moves
    • Made it clear that move evaluators are for estimated PTSP only
    • Changed parameter realization from a rather strange list of list of ints to a list of bool arrays
    • Reusing code of the 2-opt and 1-shift move evaluators in 2.5 move evaluator
    • Introducing distance calculators to properly handle the case when no distance matrix is given (previous code only worked with distance matrix and without only with euclidean distance in some settings)
    • Fixed several smaller code issues: protected, static, method parameters, copy & paste, interfaces, naming, parameters, serialization hooks, license headers, doc comments, data types
Location:
branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift
Files:
1 added
1 copied

Legend:

Unmodified
Added
Removed
  • branches/PTSP/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs

    r13408 r13412  
    2020#endregion
    2121
     22using System;
    2223using HeuristicLab.Common;
    2324using HeuristicLab.Core;
     
    2627using HeuristicLab.Parameters;
    2728using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    28 using System;
    2929
    3030namespace HeuristicLab.Problems.PTSP {
    31   [Item("PTSPEstimatedInsertionEvaluator", "Evaluates an insertion move (1-shift)")]
     31  [Item("PTSPEstimatedInsertionMoveEvaluator", "Evaluates an insertion move (1-shift)")]
    3232  [StorableClass]
    33   public class PTSPEstimatedInsertionEvaluator : PTSPMoveEvaluator, IPermutationTranslocationMoveOperator {
    34 
    35     public override Type EvaluatorType {
    36       get { return typeof(PTSPEstimatedInsertionEvaluator); }
    37     }
     33  public class PTSPEstimatedInsertionMoveEvaluator : EstimatedPTSPMoveEvaluator, IPermutationTranslocationMoveOperator {
     34
    3835    public ILookupParameter<TranslocationMove> TranslocationMoveParameter {
    3936      get { return (ILookupParameter<TranslocationMove>)Parameters["TranslocationMove"]; }
    4037    }
    4138
    42     public IValueParameter<ItemList<ItemList<IntValue>>> RealizationsParameter {
    43       get { return (IValueParameter<ItemList<ItemList<IntValue>>>)Parameters["Realizations"]; }
    44     }
    45 
    4639    [StorableConstructor]
    47     protected PTSPEstimatedInsertionEvaluator(bool deserializing) : base(deserializing) { }
    48     protected PTSPEstimatedInsertionEvaluator(PTSPEstimatedInsertionEvaluator original, Cloner cloner) : base(original, cloner) { }
    49     public PTSPEstimatedInsertionEvaluator()
     40    protected PTSPEstimatedInsertionMoveEvaluator(bool deserializing) : base(deserializing) { }
     41    protected PTSPEstimatedInsertionMoveEvaluator(PTSPEstimatedInsertionMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
     42    public PTSPEstimatedInsertionMoveEvaluator()
    5043      : base() {
    5144      Parameters.Add(new LookupParameter<TranslocationMove>("TranslocationMove", "The move to evaluate."));
     
    5346
    5447    public override IDeepCloneable Clone(Cloner cloner) {
    55       return new PTSPEstimatedInsertionEvaluator(this, cloner);
    56     }
    57 
    58     public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, PTSPEstimatedInsertionEvaluator evaluator) {
    59       int edge1source = permutation.GetCircular(move.Index1 - 1);
    60       int edge1target = permutation[move.Index1];
    61       int edge2source = permutation[move.Index2];
    62       int edge2target = permutation.GetCircular(move.Index2 + 1);
    63       if (move.Index2 - move.Index1 >= permutation.Length - 2) return 0;
    64       double moveQuality = 0;
    65       // remove two edges
    66       moveQuality -= evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
    67             coordinates[edge1target, 0], coordinates[edge1target, 1]);
    68       moveQuality -= evaluator.CalculateDistance(coordinates[edge2source, 0], coordinates[edge2source, 1],
    69         coordinates[edge2target, 0], coordinates[edge2target, 1]);
    70       // add two edges
    71       moveQuality += evaluator.CalculateDistance(coordinates[edge1source, 0], coordinates[edge1source, 1],
    72         coordinates[edge2source, 0], coordinates[edge2source, 1]);
    73       moveQuality += evaluator.CalculateDistance(coordinates[edge1target, 0], coordinates[edge1target, 1],
    74         coordinates[edge2target, 0], coordinates[edge2target, 1]);
    75       return moveQuality;
    76     }
    77 
    78     public static double EvaluateByDistanceMatrix(Permutation permutation, TranslocationMove move, DistanceMatrix distanceMatrix, ItemList<ItemList<IntValue>> realizations) {
    79       Permutation afterMove = new Permutation(PermutationTypes.RelativeUndirected,permutation);
     48      return new PTSPEstimatedInsertionMoveEvaluator(this, cloner);
     49    }
     50
     51    public static double EvaluateByCoordinates(Permutation permutation, TranslocationMove move, DoubleMatrix coordinates, DistanceCalculator distanceCalculator, ItemList<BoolArray> realizations) {
     52      var afterMove = new Permutation(PermutationTypes.RelativeUndirected, permutation);
    8053      TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
    8154      double moveQuality = 0;
    82       int[] edges = new int[12];
    83       int[] indices = new int[12];
     55      var edges = new int[12];
     56      var indices = new int[12];
    8457      edges[0] = permutation.GetCircular(move.Index1 - 1);
    85       indices[0] = decreaseCircularIndex(permutation.Length, move.Index1);
     58      indices[0] = DecreaseCircularIndex(permutation.Length, move.Index1);
    8659      edges[1] = permutation[move.Index1];
    8760      indices[1] = move.Index1;
     
    8962      indices[2] = move.Index1;
    9063      edges[3] = permutation.GetCircular(move.Index1 + 1);
    91       indices[3] = increaseCircularIndex(permutation.Length, move.Index1);
     64      indices[3] = IncreaseCircularIndex(permutation.Length, move.Index1);
    9265
    9366      edges[6] = afterMove.GetCircular(move.Index3 - 1);
    94       indices[6] = decreaseCircularIndex(afterMove.Length, move.Index3);
     67      indices[6] = DecreaseCircularIndex(afterMove.Length, move.Index3);
    9568      edges[7] = afterMove[move.Index3];
    9669      indices[7] = move.Index3;
     
    9871      indices[8] = move.Index3;
    9972      edges[9] = afterMove.GetCircular(move.Index3 + 1);
    100       indices[9] = increaseCircularIndex(afterMove.Length, move.Index3);
     73      indices[9] = IncreaseCircularIndex(afterMove.Length, move.Index3);
    10174
    10275      if (move.Index3 > move.Index1) {
     
    12093      }
    12194      int[] aPosteriori = new int[12];
    122       Permutation tempPermutation;
    123       foreach (ItemList<IntValue> realization in realizations) {
     95      foreach (var realization in realizations) {
    12496        for (int i = 0; i < edges.Length; i++) {
     97          Permutation tempPermutation;
    12598          if (i < 6) {
    12699            tempPermutation = permutation;
     
    128101            tempPermutation = afterMove;
    129102          }
    130           if (realization[edges[i]].Value == 1) {
     103          if (realization[edges[i]]) {
    131104            aPosteriori[i] = edges[i];
    132105          } else {
    133             int j=1;
    134             if (i%2==0) {
     106            int j = 1;
     107            if (i % 2 == 0) {
    135108              // find nearest predecessor in realization if source edge
    136               while (realization[tempPermutation.GetCircular(indices[i] - j)].Value == 0) {
     109              while (!realization[tempPermutation.GetCircular(indices[i] - j)]) {
    137110                j++;
    138111              }
     
    140113            } else {
    141114              // find nearest successor in realization if target edge
    142               while (realization[tempPermutation.GetCircular(indices[i] + j)].Value == 0) {
     115              while (!realization[tempPermutation.GetCircular(indices[i] + j)]) {
     116                j++;
     117              }
     118              aPosteriori[i] = tempPermutation.GetCircular(indices[i] + j);
     119            }
     120          }
     121        }
     122        if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3]) &&
     123          !(aPosteriori[0] == aPosteriori[4] && aPosteriori[1] == aPosteriori[5]) &&
     124          !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) {
     125          // compute cost difference between the two a posteriori solutions
     126
     127          moveQuality += distanceCalculator.Calculate(aPosteriori[6], aPosteriori[7], coordinates)
     128                       + distanceCalculator.Calculate(aPosteriori[8], aPosteriori[9], coordinates)
     129                       + distanceCalculator.Calculate(aPosteriori[10], aPosteriori[11], coordinates)
     130                       - distanceCalculator.Calculate(aPosteriori[0], aPosteriori[1], coordinates)
     131                       - distanceCalculator.Calculate(aPosteriori[2], aPosteriori[3], coordinates)
     132                       - distanceCalculator.Calculate(aPosteriori[4], aPosteriori[5], coordinates);
     133        }
     134        Array.Clear(aPosteriori, 0, aPosteriori.Length);
     135      }
     136      // return average of cost differences
     137      return moveQuality / realizations.Count;
     138    }
     139
     140    public static double EvaluateByDistanceMatrix(Permutation permutation, TranslocationMove move, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations) {
     141      var afterMove = new Permutation(PermutationTypes.RelativeUndirected, permutation);
     142      TranslocationManipulator.Apply(afterMove, move.Index1, move.Index1, move.Index3);
     143      double moveQuality = 0;
     144      var edges = new int[12];
     145      var indices = new int[12];
     146      edges[0] = permutation.GetCircular(move.Index1 - 1);
     147      indices[0] = DecreaseCircularIndex(permutation.Length, move.Index1);
     148      edges[1] = permutation[move.Index1];
     149      indices[1] = move.Index1;
     150      edges[2] = permutation[move.Index1];
     151      indices[2] = move.Index1;
     152      edges[3] = permutation.GetCircular(move.Index1 + 1);
     153      indices[3] = IncreaseCircularIndex(permutation.Length, move.Index1);
     154
     155      edges[6] = afterMove.GetCircular(move.Index3 - 1);
     156      indices[6] = DecreaseCircularIndex(afterMove.Length, move.Index3);
     157      edges[7] = afterMove[move.Index3];
     158      indices[7] = move.Index3;
     159      edges[8] = afterMove[move.Index3];
     160      indices[8] = move.Index3;
     161      edges[9] = afterMove.GetCircular(move.Index3 + 1);
     162      indices[9] = IncreaseCircularIndex(afterMove.Length, move.Index3);
     163
     164      if (move.Index3 > move.Index1) {
     165        edges[4] = permutation[move.Index3];
     166        indices[4] = move.Index3;
     167        edges[5] = permutation.GetCircular(move.Index3 + 1);
     168        indices[5] = indices[9];
     169        edges[10] = afterMove.GetCircular(move.Index1 - 1);
     170        indices[10] = indices[0];
     171        edges[11] = afterMove[move.Index1];
     172        indices[11] = move.Index1;
     173      } else {
     174        edges[4] = permutation.GetCircular(move.Index3 - 1);
     175        indices[4] = indices[6];
     176        edges[5] = permutation[move.Index3];
     177        indices[5] = move.Index3;
     178        edges[10] = afterMove[move.Index1];
     179        indices[10] = move.Index1;
     180        edges[11] = afterMove.GetCircular(move.Index1 + 1);
     181        indices[11] = indices[3];
     182      }
     183      int[] aPosteriori = new int[12];
     184      foreach (var realization in realizations) {
     185        for (int i = 0; i < edges.Length; i++) {
     186          Permutation tempPermutation;
     187          if (i < 6) {
     188            tempPermutation = permutation;
     189          } else {
     190            tempPermutation = afterMove;
     191          }
     192          if (realization[edges[i]]) {
     193            aPosteriori[i] = edges[i];
     194          } else {
     195            int j = 1;
     196            if (i % 2 == 0) {
     197              // find nearest predecessor in realization if source edge
     198              while (!realization[tempPermutation.GetCircular(indices[i] - j)]) {
     199                j++;
     200              }
     201              aPosteriori[i] = tempPermutation.GetCircular(indices[i] - j);
     202            } else {
     203              // find nearest successor in realization if target edge
     204              while (!realization[tempPermutation.GetCircular(indices[i] + j)]) {
    143205                j++;
    144206              }
     
    160222    }
    161223
    162     private static int decreaseCircularIndex(int length, int index) {
    163       int result = index - 1;
     224    private static int DecreaseCircularIndex(int length, int index) {
     225      var result = index - 1;
    164226      if (result == -1) {
    165227        result = length - 1;
     
    168230    }
    169231
    170     private static int increaseCircularIndex(int length, int index) {
    171       int result = index + 1;
     232    private static int IncreaseCircularIndex(int length, int index) {
     233      var result = index + 1;
    172234      if (result == length + 1) {
    173235        result = 0;
     
    176238    }
    177239
    178     protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates) {
    179       return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, this);
     240    protected override double EvaluateByCoordinates(Permutation permutation, DoubleMatrix coordinates, DistanceCalculator distanceCalculator) {
     241      return EvaluateByCoordinates(permutation, TranslocationMoveParameter.ActualValue, coordinates, distanceCalculator, RealizationsParameter.ActualValue);
    180242    }
    181243
    182244    protected override double EvaluateByDistanceMatrix(Permutation permutation, DistanceMatrix distanceMatrix) {
    183       return EvaluateByDistanceMatrix(permutation, TranslocationMoveParameter.ActualValue, distanceMatrix, RealizationsParameter.Value);
    184     }
    185 
    186     protected override double CalculateDistance(double x1, double y1, double x2, double y2) {
    187       return Math.Round(Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
     245      return EvaluateByDistanceMatrix(permutation, TranslocationMoveParameter.ActualValue, distanceMatrix, RealizationsParameter.ActualValue);
    188246    }
    189247  }
Note: See TracChangeset for help on using the changeset viewer.