Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11791 was 11791, checked in by mkommend, 9 years ago

#2282: Implemented stop button in PPP and adapted to new BasicAlgorithm.

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