Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 17533 was 17533, checked in by abeham, 4 years ago

#2521: Unified architecture

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