Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4502 was 4502, checked in by swinkler, 13 years ago

Worked on population diversity analyzer for TSP: Implemented storing of population diversity result details in a specialized data structure and the algorithm's results collection. (#1188)

File size: 9.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.Analysis;
25using HeuristicLab.Core;
26using HeuristicLab.Common;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.PermutationEncoding;
29using HeuristicLab.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using System.Data;
34
35namespace HeuristicLab.Problems.TravelingSalesman {
36  /// <summary>
37  /// An operator for analyzing the diversity of a population of solutions for a Traveling Salesman Problems given in path representation using city coordinates.
38  /// </summary>
39  [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.")]
40  [StorableClass]
41  public sealed class TSPPopulationDiversityAnalyzer : SingleSuccessorOperator, IAnalyzer {
42
43    // TODO:
44    // - iterations sampling
45    // - view
46    // - extract population diversity basic behavior into separate project
47
48    public const string PermutationKey = "Permutation";
49    public ScopeTreeLookupParameter<Permutation> PermutationParameter {
50      get { return (ScopeTreeLookupParameter<Permutation>)Parameters[PermutationKey]; }
51    }
52    public const string QualityKey = "Quality";
53    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
54      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[QualityKey]; }
55    }
56
57    public const string StoreCompleteHistoryKey = "StoreCompleteHistory";
58    public ValueParameter<BoolValue> StoreCompleteHistoryParameter {
59      get { return (ValueParameter<BoolValue>)Parameters[StoreCompleteHistoryKey]; }
60    }
61
62    public const string CurrentAverageSimilarityKey = "Current Average Population Similarity";
63    public const string AverageSimilarityProgressKey = "Average Population Similarity Progress";
64    public const string CurrentAverageMaximumSimilarityKey = "Current Average Maximum Population Similarity";
65    public const string AverageMaximumSimilarityProgressKey = "Average Maximum Population Similarity Progress";
66    public const string PopulationDiversityAnalysisResultsDetailsKey = "Population Diversity Analysis Results Details";
67
68    public const string ResultsKey = "Results";
69    public ValueLookupParameter<ResultCollection> ResultsParameter {
70      get { return (ValueLookupParameter<ResultCollection>)Parameters[ResultsKey]; }
71    }
72
73    public TSPPopulationDiversityAnalyzer()
74      : base() {
75      Parameters.Add(new ScopeTreeLookupParameter<Permutation>(PermutationKey, "The TSP solutions given in path representation from which the best solution should be analyzed."));
76      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityKey, "The qualities of the TSP solutions which should be analyzed."));
77      Parameters.Add(new ValueParameter<BoolValue>(StoreCompleteHistoryKey, "Flag that denotes whether the complete history of similarity values shall be stored.", new BoolValue(true)));
78      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The results collection in which the population diversity analysis results should be stored."));
79    }
80
81    public override IOperation Apply() {
82
83      ItemArray<Permutation> permutations = PermutationParameter.ActualValue;
84      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
85      Permutation[] permutationsArray = permutations.ToArray();
86      DoubleValue[] qualitiesArray = qualities.ToArray();
87      int cities = permutationsArray.Length;
88      ResultCollection results = ResultsParameter.ActualValue;
89
90      #region sort permutations array
91      for (int i = 0; i < cities; i++) {
92        int minIndex = i;
93        for (int j = i + 1; j < cities; j++) {
94          if (qualitiesArray[j].Value < qualitiesArray[minIndex].Value)
95            minIndex = j;
96        }
97        if (minIndex != i) {
98          Permutation p = permutationsArray[i];
99          permutationsArray[i] = permutationsArray[minIndex];
100          permutationsArray[minIndex] = p;
101          DoubleValue d = qualitiesArray[i];
102          qualitiesArray[i] = qualitiesArray[minIndex];
103          qualitiesArray[minIndex] = d;
104        }
105      }
106      #endregion
107
108      int[][] edges = new int[cities][];
109      for (int i = 0; i < cities; i++)
110        edges[i] = CalculateEdgesVector(permutationsArray[i]);
111
112      double[,] similarities = new double[cities, cities];
113      double[] maxSimilarities = new double[cities];
114      double avgSimilarity = 0;
115      int n = 0;
116      for (int i = 0; i < cities; i++) {
117        similarities[i, i] = 1;
118        for (int j = (i + 1); j < cities; j++) {
119          double similarity = CalculateSimilarity(edges[i], edges[j]);
120          avgSimilarity += similarity;
121          n++;
122          similarities[i, j] = similarity;
123          similarities[j, i] = similarity;
124          if (maxSimilarities[i] < similarity)
125            maxSimilarities[i] = similarity;
126          if (maxSimilarities[j] < similarity)
127            maxSimilarities[j] = similarity;
128        }
129      }
130      DoubleValue averageMaximumSimilarity = new DoubleValue(maxSimilarities.Average());
131      DoubleValue averageSimilarity = new DoubleValue(avgSimilarity / n);
132
133      #region Store average similarity values
134      if (results.ContainsKey(CurrentAverageSimilarityKey))
135        results[CurrentAverageSimilarityKey].Value = averageSimilarity;
136      else
137        results.Add(new Result(CurrentAverageSimilarityKey, averageSimilarity));
138
139      if (!results.ContainsKey(AverageSimilarityProgressKey))
140        results.Add(new Result(AverageSimilarityProgressKey, new Analysis.DataTable(AverageSimilarityProgressKey)));
141      Analysis.DataTable averageSimilarityProgressDataTable = (Analysis.DataTable)(results[AverageSimilarityProgressKey].Value);
142      if (averageSimilarityProgressDataTable.Rows.Count == 0)
143        averageSimilarityProgressDataTable.Rows.Add(new Analysis.DataRow(AverageSimilarityProgressKey));
144      averageSimilarityProgressDataTable.Rows[AverageSimilarityProgressKey].Values.Add(averageSimilarity.Value);
145      #endregion
146      #region Store average maximum similarity values
147      if (results.ContainsKey(CurrentAverageMaximumSimilarityKey))
148        results[CurrentAverageMaximumSimilarityKey].Value = averageMaximumSimilarity;
149      else
150        results.Add(new Result(CurrentAverageMaximumSimilarityKey, averageMaximumSimilarity));
151
152      if (!results.ContainsKey(AverageMaximumSimilarityProgressKey))
153        results.Add(new Result(AverageMaximumSimilarityProgressKey, new Analysis.DataTable(AverageMaximumSimilarityProgressKey)));
154      Analysis.DataTable averageMaximumSimilarityProgressDataTable = (Analysis.DataTable)(results[AverageMaximumSimilarityProgressKey].Value);
155      if (averageMaximumSimilarityProgressDataTable.Rows.Count == 0)
156        averageMaximumSimilarityProgressDataTable.Rows.Add(new Analysis.DataRow(AverageMaximumSimilarityProgressKey));
157      averageMaximumSimilarityProgressDataTable.Rows[AverageMaximumSimilarityProgressKey].Values.Add(averageMaximumSimilarity.Value);
158      #endregion
159      #region Store details
160      TSPPopulationDiversityAnalysisDetails details;
161      if (!results.ContainsKey(PopulationDiversityAnalysisResultsDetailsKey)) {
162        details = new TSPPopulationDiversityAnalysisDetails();
163        results.Add(new Result(PopulationDiversityAnalysisResultsDetailsKey, details));
164      } else {
165        details = (TSPPopulationDiversityAnalysisDetails)(results[PopulationDiversityAnalysisResultsDetailsKey].Value);
166      }
167      details.AverageSimilarities.Add(averageSimilarity.Value);
168      details.AverageMaximumSimilarities.Add(averageMaximumSimilarity.Value);
169      details.Similarities.Add(similarities);
170      details.MaximumSimilarities.Add(maxSimilarities);
171      if (!StoreCompleteHistoryParameter.Value.Value && details.Similarities.Count > 1) {
172        details.Similarities[details.Similarities.Count - 1] = null;
173        details.MaximumSimilarities[details.MaximumSimilarities.Count - 1] = null;
174      }
175      #endregion
176
177      return base.Apply();
178    }
179
180    private static int[] CalculateEdgesVector(Permutation permutation) {
181      int cities = permutation.Length;
182      int[] edgesVector = new int[cities];
183      for (int i = 0; i < (cities - 1); i++)
184        edgesVector[permutation[i]] = permutation[i + 1];
185      edgesVector[permutation[cities - 1]] = permutation[0];
186      return edgesVector;
187    }
188
189    private double CalculateSimilarity(int[] edgesA, int[] edgesB) {
190      if (edgesA.Length != edgesB.Length)
191        throw new InvalidOperationException("ERROR in " + Name + ": Similarity can only be calculated between instances of an equal number of cities");
192      int cities = edgesA.Length;
193      int similarEdges = 0;
194      for (int i = 0; i < edgesA.Length; i++) {
195        if (edgesA[i] == edgesB[i] || edgesA[edgesB[i]] == i)
196          similarEdges++;
197      }
198      return (double)(similarEdges) / cities;
199    }
200
201  }
202}
Note: See TracBrowser for help on using the repository browser.