Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/28/15 23:38:51 (8 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
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PTSP/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs

    r12799 r13412  
    1 using System.Text;
    2 using System.Threading.Tasks;
    3 using HeuristicLab.Optimization;
    4 using HeuristicLab.PluginInfrastructure;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2015 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
     22using System;
     23using System.Linq;
     24using HeuristicLab.Common;
    525using HeuristicLab.Core;
     26using HeuristicLab.Data;
     27using HeuristicLab.Encodings.PermutationEncoding;
     28using HeuristicLab.Parameters;
    629using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    730using HeuristicLab.Problems.Instances;
    8 using HeuristicLab.Encodings.PermutationEncoding;
    9 using HeuristicLab.Common;
    10 using HeuristicLab.Parameters;
    11 using HeuristicLab.Data;
    1231using HeuristicLab.Random;
    13 using System;
    14 using System.Linq;
    1532
    1633namespace HeuristicLab.Problems.PTSP {
    17   [Item("Estimated Probabilistic Traveling Salesman Problem", "Represents an estimated Probabilistic Traveling Salesman Problem.")]
    18   [Creatable("Problems")]
     34  [Item("Estimated Probabilistic Traveling Salesman Problem (PTSP)", "Represents a probabilistic traveling salesman problem where the expected tour length is estimated by averaging over the length of tours on a number of, so called, realizations.")]
     35  [Creatable(CreatableAttribute.Categories.CombinatorialProblems)]
    1936  [StorableClass]
    20   public sealed class EstimatedProbabilisticTravelingSalesmanProblem : ProbabilisticTravelingSalesmanProblem, IStorableContent,
    21   IProblemInstanceConsumer<PTSPData> {
    22 
     37  public sealed class EstimatedProbabilisticTravelingSalesmanProblem : ProbabilisticTravelingSalesmanProblem {
    2338
    2439    #region Parameter Properties
    25     public ValueParameter<ItemList<ItemList<IntValue>>> RealizationsParameter {
    26       get { return (ValueParameter<ItemList<ItemList<IntValue>>>)Parameters["Realizations"]; }
    27     }
    28     public ValueParameter<IntValue> RealizationsSizeParameter {
    29       get { return (ValueParameter<IntValue>)Parameters["RealizationsSize"]; }
    30     }
    31 
     40    public IValueParameter<ItemList<BoolArray>> RealizationsParameter {
     41      get { return (IValueParameter<ItemList<BoolArray>>)Parameters["Realizations"]; }
     42    }
     43    public IFixedValueParameter<IntValue> RealizationsSizeParameter {
     44      get { return (IFixedValueParameter<IntValue>)Parameters["RealizationsSize"]; }
     45    }
    3246    #endregion
    3347
    3448    #region Properties
    35     public ItemList<ItemList<IntValue>> Realizations {
     49    public ItemList<BoolArray> Realizations {
    3650      get { return RealizationsParameter.Value; }
    3751      set { RealizationsParameter.Value = value; }
    3852    }
    3953
    40     public IntValue RealizationsSize {
    41       get { return RealizationsSizeParameter.Value; }
    42       set { RealizationsSizeParameter.Value = value; }
     54    public int RealizationsSize {
     55      get { return RealizationsSizeParameter.Value.Value; }
     56      set { RealizationsSizeParameter.Value.Value = value; }
    4357    }
    4458    #endregion
     
    5165    }
    5266    public EstimatedProbabilisticTravelingSalesmanProblem() {
    53       Parameters.Add(new ValueParameter<IntValue>("RealizationsSize", "Size of the sample for the estimation-based evaluation"));
    54       Parameters.Add(new ValueParameter<ItemList<ItemList<IntValue>>>("Realizations", "The concrete..."));
    55 
    56       Operators.RemoveAll(x => x is ISingleObjectiveMoveEvaluator);
    57       Operators.RemoveAll(x => x is IMoveGenerator);
    58       Operators.RemoveAll(x => x is IMoveMaker);
     67      Parameters.Add(new FixedValueParameter<IntValue>("RealizationsSize", "Size of the sample for the estimation-based evaluation", new IntValue(100)));
     68      Parameters.Add(new ValueParameter<ItemList<BoolArray>>("Realizations", "The list of samples drawn from all possible stochastic instances.", new ItemList<BoolArray>()));
    5969
    6070      Operators.Add(new BestPTSPSolutionAnalyzer());
    6171
    62       Operators.Add(new PTSPEstimatedInversionEvaluator());
    63       Operators.Add(new PTSPEstimatedInsertionEvaluator());
     72      Operators.Add(new PTSPEstimatedInversionMoveEvaluator());
     73      Operators.Add(new PTSPEstimatedInsertionMoveEvaluator());
    6474      Operators.Add(new PTSPExhaustiveInversionLocalImprovement());
    6575      Operators.Add(new PTSPExhaustiveInsertionLocalImprovement());
    6676
    67       Operators.Add(new Exhaustive25MoveGenerator());
    68       Operators.Add(new Stochastic25MultiMoveGenerator());
    69       Operators.Add(new Stochastic25SingleMoveGenerator());
     77      Operators.Add(new ExhaustiveTwoPointFiveMoveGenerator());
     78      Operators.Add(new StochasticTwoPointFiveMultiMoveGenerator());
     79      Operators.Add(new StochasticTwoPointFiveSingleMoveGenerator());
    7080      Operators.Add(new TwoPointFiveMoveMaker());
    71       Operators.Add(new PTSP25MoveEvaluator());
     81      Operators.Add(new PTSPTwoPointFiveMoveEvaluator());
    7282
    7383      Encoding.ConfigureOperators(Operators.OfType<IOperator>());
    74       foreach (var twopointfiveMoveOperator in Operators.OfType<I25MoveOperator>()) {
     84      foreach (var twopointfiveMoveOperator in Operators.OfType<ITwoPointFiveMoveOperator>()) {
    7585        twopointfiveMoveOperator.TwoPointFiveMoveParameter.ActualName = "Permutation.TwoPointFiveMove";
    7686      }
    77       RealizationsSize = new IntValue(100);
     87
    7888      RegisterEventHandlers();
    7989    }
     
    8393    }
    8494
    85     public override double Evaluate(Individual individual, IRandom random) {
    86       Permutation p = individual.Permutation();
     95    [StorableHook(HookType.AfterDeserialization)]
     96    private void AfterDeserialization() {
     97      RegisterEventHandlers();
     98    }
     99
     100    private void RegisterEventHandlers() {
     101      RealizationsSizeParameter.Value.ValueChanged += RealizationsSizeParameter_ValueChanged;
     102    }
     103
     104    private void RealizationsSizeParameter_ValueChanged(object sender, EventArgs e) {
     105      UpdateRealizations();
     106    }
     107
     108    public override double Evaluate(Permutation tour, IRandom random) {
    87109      // Estimation-based evaluation
    88       MersenneTwister r = new MersenneTwister();
    89       double estimatedSum = 0;
    90       for (int i = 0; i < Realizations.Count; i++) {
     110      var estimatedSum = 0.0;
     111      for (var i = 0; i < Realizations.Count; i++) {
    91112        int singleRealization = -1, firstNode = -1;
    92         for (int j = 0; j < Realizations[i].Count; j++) {
    93           if (Realizations[i][p[j]].Value == 1) {
     113        for (var j = 0; j < Realizations[i].Length; j++) {
     114          if (Realizations[i][tour[j]]) {
    94115            if (singleRealization != -1) {
    95               estimatedSum += DistanceMatrix[singleRealization, p[j]];
     116              estimatedSum += GetDistance(singleRealization, tour[j]);
    96117            } else {
    97               firstNode = p[j];
     118              firstNode = tour[j];
    98119            }
    99             singleRealization = p[j];
     120            singleRealization = tour[j];
    100121          }
    101122        }
    102123        if (singleRealization != -1) {
    103           estimatedSum += DistanceMatrix[singleRealization, firstNode];
    104         }
    105       }
    106       return estimatedSum / RealizationsSize.Value;
    107     }
    108 
    109     public double[] EvaluateWithParams(DistanceMatrix distances, DoubleArray probabilities, ItemList<ItemList<IntValue>> realizations, Permutation individual ) {
     124          estimatedSum += GetDistance(singleRealization, firstNode);
     125        }
     126      }
     127      return estimatedSum / RealizationsSize;
     128    }
     129
     130    /// <summary>
     131    /// An evaluate method that can be used if mean as well as variance should be calculated
     132    /// </summary>
     133    /// <param name="tour">The tour between all cities.</param>
     134    /// <param name="distanceMatrix">The distances between the cities.</param>
     135    /// <param name="realizations">A sample of realizations of the stochastic instance</param>
     136    /// <returns>A vector with length two containing mean and variance.</returns>
     137    public static double[] Evaluate(Permutation tour, DistanceMatrix distanceMatrix, ItemList<BoolArray> realizations) {
    110138      // Estimation-based evaluation
    111       MersenneTwister r = new MersenneTwister();
    112       double estimatedSum = 0;
    113       double[] partialSums = new double[realizations.Count];
    114       for (int i = 0; i < realizations.Count; i++) {
     139      var estimatedSum = 0.0;
     140      var partialSums = new double[realizations.Count];
     141      for (var i = 0; i < realizations.Count; i++) {
    115142        partialSums[i] = 0;
    116143        int singleRealization = -1, firstNode = -1;
    117         for (int j = 0; j < realizations[i].Count; j++) {
    118           if (realizations[i][individual[j]].Value == 1) {
     144        for (var j = 0; j < realizations[i].Length; j++) {
     145          if (realizations[i][tour[j]]) {
    119146            if (singleRealization != -1) {
    120               partialSums[i] += distances[singleRealization, individual[j]];
     147              partialSums[i] += distanceMatrix[singleRealization, tour[j]];
    121148            } else {
    122               firstNode = individual[j];
     149              firstNode = tour[j];
    123150            }
    124             singleRealization = individual[j];
     151            singleRealization = tour[j];
    125152          }
    126153        }
    127154        if (singleRealization != -1) {
    128           partialSums[i] += distances[singleRealization, firstNode];
     155          partialSums[i] += distanceMatrix[singleRealization, firstNode];
    129156        }
    130157        estimatedSum += partialSums[i];
    131158      }
    132       double mean = estimatedSum / realizations.Count;
    133       double variance = 0;
    134       for (int i = 0; i < realizations.Count; i++) {
     159      var mean = estimatedSum / realizations.Count;
     160      var variance = 0.0;
     161      for (var i = 0; i < realizations.Count; i++) {
    135162        variance += Math.Pow((partialSums[i] - mean), 2);
    136163      }
    137164      variance = variance / realizations.Count;
    138       return new double[] {mean,variance};
    139     }
    140 
    141    
    142 
    143     private void RegisterEventHandlers() {
    144       //RealizationsSizeParameter.ValueChanged += new EventHandler(RealizationsSizeParameter_ValueChanged);
    145       RealizationsSize.ValueChanged += new EventHandler(RealizationsSizeParameter_ValueChanged);
    146       //RealizationsSizeParameter.Value.ValueChanged += new EventHandler(RealizationsSizeParameter_ValueChanged);
    147     }
    148 
    149     private void RealizationsSizeParameter_ValueChanged(object sender, EventArgs e) {
    150       UpdateRealizations();
     165      return new[] { mean, variance };
     166    }
     167
     168    public double GetDistance(int from, int to) {
     169      if (UseDistanceMatrix) return DistanceMatrix[from, to];
     170      return DistanceCalculator.Calculate(from, to, Coordinates);
    151171    }
    152172
    153173    private void UpdateRealizations() {
    154       MersenneTwister r = new MersenneTwister();
    155       int countOnes = 0;
    156       Realizations = new ItemList<ItemList<IntValue>>(RealizationsSize.Value);
    157       for (int i = 0; i < RealizationsSize.Value; i++) {
    158         ItemList<IntValue> newRealization = new ItemList<IntValue>();
    159         while (countOnes < 4) { //only generate realizations with at least 4 cities visited
     174      var realizations = new ItemList<BoolArray>(RealizationsSize);
     175      var rand = new MersenneTwister();
     176      for (var i = 0; i < RealizationsSize; i++) {
     177        var newRealization = new BoolArray(Probabilities.Length);
     178        var countOnes = 0;
     179        while (countOnes < 4) { // only generate realizations with at least 4 cities visited
    160180          countOnes = 0;
    161           newRealization.Clear();
    162           for (int j = 0; j < DistanceMatrix.Rows; j++) {
    163             if (ProbabilityMatrix[j] > r.NextDouble()) {
    164               newRealization.Add(new IntValue(1));
    165               countOnes++;
    166             } else {
    167               newRealization.Add(new IntValue(0));
    168             }
     181          for (var j = 0; j < Probabilities.Length; j++) {
     182            newRealization[j] = Probabilities[j] < rand.NextDouble();
     183            if (newRealization[j]) countOnes++;
    169184          }
    170185        }
    171         countOnes = 0;
    172186        Realizations.Add(newRealization);
    173187      }
     188      Realizations = realizations;
    174189    }
    175190
     
    178193      UpdateRealizations();
    179194
    180       foreach (var op in Operators.OfType<PTSPMoveEvaluator>()) {
    181         op.RealizationsParameter.Value = Realizations;
    182       }
    183       foreach (var op in Operators.OfType<PTSPExhaustiveInversionLocalImprovement>()) {
    184         op.RealizationsParameter.Value = Realizations;
    185       }
    186       foreach (var op in Operators.OfType<PTSP25MoveEvaluator>()) {
    187         op.RealizationsParameter.Value = Realizations;
    188       }
    189 
     195      foreach (var op in Operators.OfType<IEstimatedPTSPOperator>()) {
     196        op.RealizationsParameter.ActualName = RealizationsParameter.Name;
     197      }
    190198    }
    191199  }
Note: See TracChangeset for help on using the changeset viewer.