Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.DiversityAnalysis/HeuristicLab.Problems.TravelingSalesman/3.3/Analyzers/TSPPopulationDiversityAnalyzer.cs @ 4420

Last change on this file since 4420 was 4420, checked in by swinkler, 14 years ago

Implemented population diversity analyzer for TSP. (#1188)

File size: 8.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Encodings.PermutationEncoding;
27using HeuristicLab.Operators;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31
32namespace HeuristicLab.Problems.TravelingSalesman {
33  /// <summary>
34  /// An operator for analyzing the diversity of a population of solutions for a Traveling Salesman Problems given in path representation using city coordinates.
35  /// </summary>
36  [Item("TSPPopulationDiversityAnalyzer", "An operator for analyzing the diversity of a population of solutions for a Traveling Salesman Problems given in path representation using city coordinates.")]
37  [StorableClass]
38  public sealed class TSPPopulationDiversityAnalyzer : SingleSuccessorOperator, IAnalyzer {
39
40    // TODO:
41    // - iterations sampling
42    // - decide whether old results shall be stored or disposed
43    // - view
44    // - check results for identical solutions
45
46    public ScopeTreeLookupParameter<Permutation> PermutationParameter {
47      get { return (ScopeTreeLookupParameter<Permutation>)Parameters["Permutation"]; }
48    }
49    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
50      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
51    }
52    public LookupParameter<ItemList<DoubleMatrix>> SimilaritiesParameter {
53      get { return (LookupParameter<ItemList<DoubleMatrix>>)Parameters["Similarities"]; }
54    }
55    public LookupParameter<ItemList<DoubleArray>> MaximumSimilaritiesParameter {
56      get { return (LookupParameter<ItemList<DoubleArray>>)Parameters["MaximumSimilarities"]; }
57    }
58    public LookupParameter<ItemList<DoubleValue>> AverageMaximumSimilaritiesParameter {
59      get { return (LookupParameter<ItemList<DoubleValue>>)Parameters["AverageMaximumSimilarities"]; }
60    }
61    public LookupParameter<ItemList<DoubleValue>> AverageSimilaritiesParameter {
62      get { return (LookupParameter<ItemList<DoubleValue>>)Parameters["AverageSimilarities"]; }
63    }
64
65    [NonSerialized]
66    private int[] rxData, ryData;
67    [NonSerialized]
68    private Permutation lastX, lastY;
69
70    public TSPPopulationDiversityAnalyzer()
71      : base() {
72      Parameters.Add(new ScopeTreeLookupParameter<Permutation>("Permutation", "The TSP solutions given in path representation from which the best solution should be analyzed."));
73      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the TSP solutions which should be analyzed."));
74      Parameters.Add(new LookupParameter<ItemList<DoubleMatrix>>("Similarities", "The similarities of the TSP solutions which should be analyzed."));
75      Parameters.Add(new LookupParameter<ItemList<DoubleArray>>("MaximumSimilarities", "The maximum similarities of the TSP solutions which should be analyzed."));
76      Parameters.Add(new LookupParameter<ItemList<DoubleValue>>("AverageMaximumSimilarities", "The average maximum similarities of the TSP solutions which should be analyzed."));
77      Parameters.Add(new LookupParameter<ItemList<DoubleValue>>("AverageSimilarities", "The average similarities of the TSP solutions which should be analyzed."));
78      rxData = null;
79      ryData = null;
80      lastX = null;
81      lastY = null;
82    }
83
84    public override IOperation Apply() {
85
86      ItemArray<Permutation> permutations = PermutationParameter.ActualValue;
87      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
88      Permutation[] permutationsArray = permutations.ToArray();
89      DoubleValue[] qualitiesArray = qualities.ToArray();
90      int cities = permutationsArray.Length;
91      #region sort permutations array
92      for (int i = 0; i < cities; i++) {
93        int minIndex = i;
94        for (int j = i + 1; j < cities; j++) {
95          if (qualitiesArray[j].Value < qualitiesArray[minIndex].Value)
96            minIndex = j;
97        }
98        if (minIndex != i) {
99          Permutation p = permutationsArray[i];
100          permutationsArray[i] = permutationsArray[minIndex];
101          permutationsArray[minIndex] = p;
102          DoubleValue d = qualitiesArray[i];
103          qualitiesArray[i] = qualitiesArray[minIndex];
104          qualitiesArray[minIndex] = d;
105        }
106      }
107      #endregion
108
109      DoubleMatrix similarities = new DoubleMatrix(cities, cities);
110      DoubleArray maxSimilarities = new DoubleArray(cities);
111      double avgSimilarity = 0;
112      int n = 0;
113      for (int i = 0; i < cities; i++) {
114        similarities[i, i] = 1;
115        // for (int j = (i + 1); j < cities; j++) {
116        for (int j = (i); j < cities; j++) {
117          double similarity = CalculateSimilarity(permutationsArray[i], permutationsArray[j]);
118          avgSimilarity += similarity;
119          n++;
120          similarities[i, j] = similarity;
121          similarities[j, i] = similarity;
122          if (maxSimilarities[i] < similarity)
123            maxSimilarities[i] = similarity;
124          if (maxSimilarities[j] < similarity)
125            maxSimilarities[j] = similarity;
126        }
127      }
128      DoubleValue averageMaximumSimilarity = new DoubleValue(maxSimilarities.Average());
129      DoubleValue averageSimilarity = new DoubleValue(avgSimilarity / n);
130
131      if (SimilaritiesParameter.ActualValue == null) {
132        SimilaritiesParameter.ActualValue = new ItemList<DoubleMatrix>();
133        MaximumSimilaritiesParameter.ActualValue = new ItemList<DoubleArray>();
134        AverageMaximumSimilaritiesParameter.ActualValue = new ItemList<DoubleValue>();
135        AverageSimilaritiesParameter.ActualValue = new ItemList<DoubleValue>();
136      }
137      SimilaritiesParameter.ActualValue.Add(similarities);
138      MaximumSimilaritiesParameter.ActualValue.Add(maxSimilarities);
139      AverageMaximumSimilaritiesParameter.ActualValue.Add(averageMaximumSimilarity);
140      AverageSimilaritiesParameter.ActualValue.Add(averageSimilarity);
141
142      return base.Apply();
143    }
144
145    private double CalculateSimilarity(Permutation x, Permutation y) {
146
147      int cities = x.Length;
148      if (rxData == null || rxData.Length != cities) {
149        rxData = new int[cities];
150        ryData = new int[cities];
151      }
152
153      if (x.Length != y.Length) throw new InvalidOperationException("ERROR in " + Name + ": Similarity can only be calculated between instances of an equal number of cities");
154      #region Performance savings when calling the function with at least one parameter identical to the last call
155      if (x == lastX) { // if Solution1 stayed the same
156        if (y != lastY) { // and Solution2 changed
157          for (int i = 0; i < y.Length; i++)
158            ryData[y[i]] = i;
159        }
160      } else {
161        if (y == lastX && x == lastY) { // if Solution1 and Solution2 were reversed the call before
162          int[] h = ryData;
163          ryData = rxData;
164          rxData = h;
165        } else if (y == lastX) { // or if just Solution1 is different now
166          ryData = rxData;
167          rxData = new int[x.Length];
168          for (int i = 0; i < x.Length; i++)
169            rxData[x[i]] = i;
170        } else if (x == lastY) { // or just Solution2 is different now
171          rxData = ryData;
172          ryData = new int[y.Length];
173          for (int i = 0; i < y.Length; i++)
174            ryData[y[i]] = i;
175        } else if (y != lastY) { // or none are the same
176          for (int i = 0; i < x.Length; i++) {
177            rxData[x[i]] = i;
178            ryData[y[i]] = i;
179          }
180        } else { // or just Solution2 is the same
181          for (int i = 0; i < x.Length; i++)
182            rxData[x[i]] = i;
183        }
184      }
185      lastX = x;
186      lastY = y;
187      #endregion
188      int similarEdges = 0;
189      for (int i = 1; i <= x.Length; i++) {
190        if (Math.Abs(ryData[x[(i < x.Length) ? (i) : (0)]] - ryData[x[i - 1]]) == 1
191          || Math.Abs(ryData[x[(i < x.Length) ? (i) : (0)]] - ryData[x[i - 1]]) == x.Length)
192          similarEdges++;
193      }
194      return (double)similarEdges / (double)x.Length;
195
196    }
197
198  }
199}
Note: See TracBrowser for help on using the repository browser.