Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs @ 17320

Last change on this file since 17320 was 17320, checked in by mkommend, 5 years ago

#2521: Added cancellation token to evaluate function of problems.

File size: 9.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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.Collections.Generic;
24using System.Linq;
25using System.Threading;
26using HEAL.Attic;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Encodings.PermutationEncoding;
31using HeuristicLab.Parameters;
32using HeuristicLab.Problems.Instances;
33using HeuristicLab.Random;
34
35namespace HeuristicLab.Problems.PTSP {
36  [Item("Estimated Probabilistic TSP (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.")]
37  [Creatable(CreatableAttribute.Categories.CombinatorialProblems)]
38  [StorableType("d1b4149b-8ab9-4314-8d96-9ea04a4d5b8b")]
39  public sealed class EstimatedPTSP : ProbabilisticTSP {
40
41    #region Parameter Properties
42    [Storable] public IFixedValueParameter<IntValue> RealizationsSeedParameter { get; private set; }
43    [Storable] public IFixedValueParameter<IntValue> RealizationsParameter { get; private set; }
44    [Storable] private IValueParameter<ReadOnlyItemList<BoolArray>> RealizationDataParameter { get; set; }
45    #endregion
46
47    #region Properties
48
49    public int RealizationsSeed {
50      get { return RealizationsSeedParameter.Value.Value; }
51      set { RealizationsSeedParameter.Value.Value = value; }
52    }
53
54    public int Realizations {
55      get { return RealizationsParameter.Value.Value; }
56      set { RealizationsParameter.Value.Value = value; }
57    }
58   
59    private ReadOnlyItemList<BoolArray> RealizationData {
60      get { return RealizationDataParameter.Value; }
61      set { RealizationDataParameter.Value = value; }
62    }
63    #endregion
64
65    [StorableConstructor]
66    private EstimatedPTSP(StorableConstructorFlag _) : base(_) { }
67    private EstimatedPTSP(EstimatedPTSP original, Cloner cloner)
68      : base(original, cloner) {
69      RealizationsSeedParameter = cloner.Clone(original.RealizationsSeedParameter);
70      RealizationsParameter = cloner.Clone(original.RealizationsParameter);
71      RealizationDataParameter = cloner.Clone(original.RealizationDataParameter);
72      RegisterEventHandlers();
73    }
74    public EstimatedPTSP() {
75      Parameters.Add(RealizationsSeedParameter = new FixedValueParameter<IntValue>("RealizationsSeed", "The starting seed of the RNG from which realizations should be drawn.", new IntValue(1)));
76      Parameters.Add(RealizationsParameter = new FixedValueParameter<IntValue>("Realizations", "The number of realizations that should be made.", new IntValue(100)));
77      Parameters.Add(RealizationDataParameter = new ValueParameter<ReadOnlyItemList<BoolArray>>("RealizationData", "The actual realizations.") { Hidden = true, GetsCollected = false });
78
79      Operators.Add(new PTSPEstimatedInversionMoveEvaluator());
80      Operators.Add(new PTSPEstimatedInsertionMoveEvaluator());
81      Operators.Add(new PTSPEstimatedInversionLocalImprovement());
82      Operators.Add(new PTSPEstimatedInsertionLocalImprovement());
83      Operators.Add(new PTSPEstimatedTwoPointFiveLocalImprovement());
84
85      Operators.Add(new ExhaustiveTwoPointFiveMoveGenerator());
86      Operators.Add(new StochasticTwoPointFiveMultiMoveGenerator());
87      Operators.Add(new StochasticTwoPointFiveSingleMoveGenerator());
88      Operators.Add(new TwoPointFiveMoveMaker());
89      Operators.Add(new PTSPEstimatedTwoPointFiveMoveEvaluator());
90
91      Encoding.ConfigureOperators(Operators.OfType<IOperator>());
92      foreach (var twopointfiveMoveOperator in Operators.OfType<ITwoPointFiveMoveOperator>()) {
93        twopointfiveMoveOperator.TwoPointFiveMoveParameter.ActualName = "Permutation.TwoPointFiveMove";
94      }
95
96      UpdateRealizations();
97      RegisterEventHandlers();
98    }
99
100    public override IDeepCloneable Clone(Cloner cloner) {
101      return new EstimatedPTSP(this, cloner);
102    }
103
104    public override double Evaluate(Permutation tour, IRandom random, CancellationToken cancellationToken) {
105      return Evaluate(tour, ProbabilisticTSPData, RealizationData, cancellationToken);
106    }
107
108    [StorableHook(HookType.AfterDeserialization)]
109    private void AfterDeserialization() {
110      RegisterEventHandlers();
111    }
112
113    public static double Evaluate(Permutation tour, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations, CancellationToken cancellationToken) {
114      // Estimation-based evaluation, here without calculating variance for faster evaluation
115      var estimatedSum = 0.0;
116      var count = 0;
117      foreach (var r in realizations) {
118        int singleRealization = -1, firstNode = -1;
119        for (var j = 0; j < data.Cities; j++) {
120          if (r[tour[j]]) {
121            if (singleRealization != -1) {
122              estimatedSum += data.GetDistance(singleRealization, tour[j]);
123            } else {
124              firstNode = tour[j];
125            }
126            singleRealization = tour[j];
127          }
128        }
129        if (singleRealization != -1)
130          estimatedSum += data.GetDistance(singleRealization, firstNode);
131        count++;
132      }
133      return estimatedSum / count;
134    }
135
136    /// <summary>
137    /// An evaluate method that can be used if mean as well as variance should be calculated
138    /// </summary>
139    /// <param name="tour">The tour between all cities.</param>
140    /// <param name="data">The main parameters of the pTSP.</param>
141    /// <param name="realizations">How many realizations to achieve.</param>
142    /// <param name="seed">The starting seed of generating the realizations.</param>
143    /// <param name="variance">The estimated variance will be returned in addition to the mean.</param>
144    /// <returns>A vector with length two containing mean and variance.</returns>
145    public static double Evaluate(Permutation tour, IProbabilisticTSPData data, IEnumerable<BoolArray> realizations, out double variance) {
146      // Estimation-based evaluation
147      var estimatedSum = 0.0;
148      var partialSums = new List<double>();
149      var count = 0;
150      foreach (var r in realizations) {
151        var pSum = 0.0;
152        int singleRealization = -1, firstNode = -1;
153        for (var j = 0; j < data.Cities; j++) {
154          if (r[tour[j]]) {
155            if (singleRealization != -1) {
156              pSum += data.GetDistance(singleRealization, tour[j]);
157            } else {
158              firstNode = tour[j];
159            }
160            singleRealization = tour[j];
161          }
162        }
163        if (singleRealization != -1) {
164          pSum += data.GetDistance(singleRealization, firstNode);
165        }
166        estimatedSum += pSum;
167        partialSums.Add(pSum);
168        count++;
169      }
170      var mean = estimatedSum / count;
171      variance = 0.0;
172      for (var i = 0; i < count; i++) {
173        variance += Math.Pow((partialSums[i] - mean), 2);
174      }
175      variance = variance / count;
176      return mean;
177    }
178
179    private void RegisterEventHandlers() {
180      RealizationsParameter.Value.ValueChanged += RealizationsOnChanged;
181      RealizationsSeedParameter.Value.ValueChanged += RealizationsSeedOnChanged;
182    }
183
184    private void RealizationsSeedOnChanged(object sender, EventArgs e) {
185      UpdateRealizations();
186    }
187
188    private void RealizationsOnChanged(object sender, EventArgs e) {
189      if (Realizations <= 0) Realizations = 1;
190      else UpdateRealizations();
191    }
192
193    public override void Load(PTSPData data) {
194      base.Load(data);
195      UpdateRealizations();
196    }
197
198    private void UpdateRealizations() {
199      var data = new List<BoolArray>(Realizations);
200      var rng = new MersenneTwister((uint)RealizationsSeed);
201      if (Enumerable.Range(0, ProbabilisticTSPData.Cities).All(c => ProbabilisticTSPData.GetProbability(c) <= 0))
202        throw new InvalidOperationException("All probabilities are zero.");
203      while (data.Count < Realizations) {
204        var cities = 0;
205        var r = new bool[ProbabilisticTSPData.Cities];
206        for (var j = 0; j < ProbabilisticTSPData.Cities; j++) {
207          if (rng.NextDouble() < ProbabilisticTSPData.GetProbability(j)) {
208            r[j] = true;
209            cities++;
210          }
211        }
212        if (cities > 0) {
213          data.Add(new BoolArray(r, @readonly: true));
214        }
215      }
216      RealizationData = (new ItemList<BoolArray>(data)).AsReadOnly();
217    }
218  }
219}
Note: See TracBrowser for help on using the repository browser.