Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Parameter-less Population Pyramid/HeuristicLab.Algorithms.ParameterlessPopulationPyramid/3.3/ParameterlessPopulationPyramid.cs @ 11733

Last change on this file since 11733 was 11681, checked in by bgoldman, 10 years ago

#2282 Added plots for the number of solutions being stored and the total number of levels in the pyramid.

File size: 9.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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.Text;
26using System.Threading.Tasks;
27using HeuristicLab.Analysis;
28using HeuristicLab.Common;
29using HeuristicLab.Core;
30using HeuristicLab.Data;
31using HeuristicLab.Encodings.BinaryVectorEncoding;
32using HeuristicLab.Optimization;
33using HeuristicLab.Parameters;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using HeuristicLab.Random;
36
37namespace HeuristicLab.Algorithms.ParameterlessPopulationPyramid {
38  [Item("Parameter-less Population Pyramid", "Binary value optimization algorithm which requires no configuration.")]
39  [StorableClass]
40  [Creatable("Parameterless Population Pyramid")]
41
42  public class ParameterlessPopulationPyramid : AlgorithmBase {
43    private readonly IRandom random = new MersenneTwister();
44    private List<Population> pyramid;
45    private EvaluationTracker tracker;
46
47    // Tracks all solutions in Pyramid for quick membership checks
48    private HashSet<bool[]> seen = new HashSet<bool[]>(new EnumerableBoolEqualityComparer());
49
50    #region ParameterNames
51    private const string MaximumIterationsParameterName = "Maximum Iterations";
52    private const string MaximumEvaluationsParameterName = "Maximum Evaluations";
53    private const string SeedParameterName = "Seed";
54    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
55    #endregion
56
57    #region ParameterProperties
58    public IFixedValueParameter<IntValue> MaximumIterationsParameter {
59      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumIterationsParameterName]; }
60    }
61    public IFixedValueParameter<IntValue> MaximumEvaluationsParameter {
62      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluationsParameterName]; }
63    }
64    public IFixedValueParameter<IntValue> SeedParameter {
65      get { return (IFixedValueParameter<IntValue>)Parameters[SeedParameterName]; }
66    }
67    public FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
68      get { return (FixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
69    }
70    #endregion
71
72    #region Properties
73    public int MaximumIterations {
74      get { return MaximumIterationsParameter.Value.Value; }
75      set { MaximumIterationsParameter.Value.Value = value; }
76    }
77
78    public int MaximumEvaluations {
79      get { return MaximumEvaluationsParameter.Value.Value; }
80      set { MaximumEvaluationsParameter.Value.Value = value; }
81    }
82
83    public int Seed {
84      get { return SeedParameter.Value.Value; }
85      set { SeedParameter.Value.Value = value; }
86    }
87
88    public bool SetSeedRandomly {
89      get { return SetSeedRandomlyParameter.Value.Value; }
90      set { SetSeedRandomlyParameter.Value.Value = value; }
91    }
92    #endregion
93
94    #region ResultsProperties
95    private double ResultsBestQuality {
96      get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
97      set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }
98    }
99
100    private BinaryVector ResultsBestSolution {
101      get { return (BinaryVector)Results["Best Solution"].Value; }
102      set { Results["Best Solution"].Value = value; }
103    }
104
105    private int ResultsBestFoundOnEvaluation {
106      get { return ((IntValue)Results["Evaluation Best Solution Was Found"].Value).Value; }
107      set { ((IntValue)Results["Evaluation Best Solution Was Found"].Value).Value = value; }
108    }
109
110    private int ResultsEvaluations {
111      get { return ((IntValue)Results["Evaluations"].Value).Value; }
112      set { ((IntValue)Results["Evaluations"].Value).Value = value; }
113    }
114    private int ResultsIterations {
115      get { return ((IntValue)Results["Iterations"].Value).Value; }
116      set { ((IntValue)Results["Iterations"].Value).Value = value; }
117    }
118
119    private DataTable ResultsQualities {
120      get { return ((DataTable)Results["Qualities"].Value); }
121    }
122    private DataRow ResultsQualitiesBest {
123      get { return ResultsQualities.Rows["Best Quality"]; }
124    }
125
126    private DataRow ResultsQualitiesIteration {
127      get { return ResultsQualities.Rows["Iteration Quality"]; }
128    }
129
130
131    private DataRow ResultsLevels {
132      get { return ((DataTable)Results["Pyramid Levels"].Value).Rows["Levels"]; }
133    }
134
135    private DataRow ResultsSolutions {
136      get { return ((DataTable)Results["Stored Solutions"].Value).Rows["Solutions"]; }
137    }
138    #endregion
139
140    [StorableConstructor]
141    protected ParameterlessPopulationPyramid(bool deserializing) : base(deserializing) { }
142
143    protected ParameterlessPopulationPyramid(ParameterlessPopulationPyramid original, Cloner cloner)
144      : base(original, cloner) {
145    }
146
147    public override IDeepCloneable Clone(Cloner cloner) {
148      return new ParameterlessPopulationPyramid(this, cloner);
149    }
150
151    public ParameterlessPopulationPyramid() {
152      Parameters.Add(new FixedValueParameter<IntValue>(MaximumIterationsParameterName, "", new IntValue(Int32.MaxValue)));
153      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(10000)));
154      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
155      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
156    }
157
158    private void AddIfUnique(bool[] solution, int level) {
159      // Don't add things you have seen
160      if (seen.Contains(solution)) return;
161      if (level == pyramid.Count) {
162        pyramid.Add(new Population(tracker.Length, random));
163      }
164      var copied = (bool[])solution.Clone();
165      pyramid[level].Add(copied);
166      seen.Add(copied);
167    }
168
169    // In the GECCO paper, Figure 1
170    private double iterate() {
171      // Create a random solution
172      bool[] solution = new bool[tracker.Length];
173      for (int i = 0; i < solution.Length; i++) {
174        solution[i] = random.Next(2) == 1;
175      }
176      double fitness = tracker.Evaluate(solution);
177      fitness = HillClimber.ImproveToLocalOptimum(tracker, solution, fitness, random);
178      AddIfUnique(solution, 0);
179
180      for (int level = 0; level < pyramid.Count; level++) {
181        var current = pyramid[level];
182        double newFitness = LinkageCrossover.ImproveUsingTree(current.Tree, current.Solutions, solution, fitness, tracker, random);
183        // add it to the next level if its a strict fitness improvement
184        if (tracker.IsBetter(newFitness, fitness)) {
185          fitness = newFitness;
186          AddIfUnique(solution, level + 1);
187        }
188      }
189      return fitness;
190    }
191
192    protected override void Run() {
193      // Set up the algorithm
194      if (SetSeedRandomly) Seed = new System.Random().Next();
195      pyramid = new List<Population>();
196      seen.Clear();
197      random.Reset(Seed);
198      tracker = new EvaluationTracker(Problem, MaximumEvaluations);
199
200      // Set up the results display
201      Results.Add(new Result("Iterations", new IntValue(0)));
202      Results.Add(new Result("Evaluations", new IntValue(0)));
203      Results.Add(new Result("Best Solution", new BinaryVector(tracker.BestSolution)));
204      Results.Add(new Result("Best Quality", new DoubleValue(tracker.BestQuality)));
205      Results.Add(new Result("Evaluation Best Solution Was Found", new IntValue(tracker.BestFoundOnEvaluation)));
206      var table = new DataTable("Qualities");
207      table.Rows.Add(new DataRow("Best Quality"));
208      var iterationRows = new DataRow("Iteration Quality");
209      iterationRows.VisualProperties.LineStyle = DataRowVisualProperties.DataRowLineStyle.Dot;
210      table.Rows.Add(iterationRows);
211      Results.Add(new Result("Qualities", table));
212
213      table = new DataTable("Pyramid Levels");
214      table.Rows.Add(new DataRow("Levels"));
215      Results.Add(new Result("Pyramid Levels", table));
216
217      table = new DataTable("Stored Solutions");
218      table.Rows.Add(new DataRow("Solutions"));
219      Results.Add(new Result("Stored Solutions", table));
220
221      // Loop until iteration limit reached or canceled.
222      for (ResultsIterations = 0; ResultsIterations < MaximumIterations; ResultsIterations++) {
223        double fitness = double.NaN;
224
225        try {
226          fitness = iterate();
227        }
228        catch (OperationCanceledException) {
229          throw;
230        }
231        finally {
232          ResultsEvaluations = tracker.Evaluations;
233          ResultsBestSolution = new BinaryVector(tracker.BestSolution);
234          ResultsBestQuality = tracker.BestQuality;
235          ResultsBestFoundOnEvaluation = tracker.BestFoundOnEvaluation;
236          ResultsQualitiesBest.Values.Add(tracker.BestQuality);
237          ResultsQualitiesIteration.Values.Add(fitness);
238          ResultsLevels.Values.Add(pyramid.Count);
239          ResultsSolutions.Values.Add(seen.Count);
240        }
241      }
242    }
243  }
244}
Note: See TracBrowser for help on using the repository browser.