source: branches/ALPS/HeuristicLab.Algorithms.ALPS/3.3/Alps.cs @ 12531

Last change on this file since 12531 was 12531, checked in by pfleck, 7 years ago

#2269 Added Termination Criteria to standard ALPS-GA.

File size: 20.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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 HeuristicLab.Analysis;
26using HeuristicLab.Collections;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Operators;
31using HeuristicLab.Optimization;
32using HeuristicLab.Optimization.Operators;
33using HeuristicLab.Parameters;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using HeuristicLab.Random;
36
37namespace HeuristicLab.Algorithms.ALPS {
38  [Item("ALPS", "Base class for all ALPS-based algorithms.")]
39  [StorableClass]
40  public abstract class Alps : HeuristicOptimizationEngineAlgorithm, IStorableContent {
41    public string Filename { get; set; }
42
43    #region Problem Properties
44    public override Type ProblemType {
45      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
46    }
47    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
48      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
49      set { base.Problem = value; }
50    }
51    #endregion
52
53    #region Parameter Properties
54    private IValueParameter<IntValue> SeedParameter {
55      get { return (IValueParameter<IntValue>)Parameters["Seed"]; }
56    }
57    private IValueParameter<BoolValue> SetSeedRandomlyParameter {
58      get { return (IValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
59    }
60    private IFixedValueParameter<MultiAnalyzer> AnalyzerParameter {
61      get { return (IFixedValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
62    }
63    private IFixedValueParameter<MultiAnalyzer> LayerAnalyzerParameter {
64      get { return (IFixedValueParameter<MultiAnalyzer>)Parameters["LayerAnalyzer"]; }
65    }
66    private IValueParameter<IntValue> NumberOfLayersParameter {
67      get { return (IValueParameter<IntValue>)Parameters["NumberOfLayers"]; }
68    }
69    private IValueParameter<EnumValue<AgingScheme>> AgingSchemeParameter {
70      get { return (IValueParameter<EnumValue<AgingScheme>>)Parameters["AgingScheme"]; }
71    }
72    private IValueParameter<IntValue> AgeGapParameter {
73      get { return (IValueParameter<IntValue>)Parameters["AgeGap"]; }
74    }
75    private IValueParameter<IntArray> AgeLimitsParameter {
76      get { return (IValueParameter<IntArray>)Parameters["AgeLimits"]; }
77    }
78    private IValueParameter<EnumValue<AgeInheritance>> AgeInheritanceParameter {
79      get { return (IValueParameter<EnumValue<AgeInheritance>>)Parameters["AgeInheritance"]; }
80    }
81    private IValueParameter<ReductionOperation> AgeInheritanceReductionParameter {
82      get { return (IValueParameter<ReductionOperation>)Parameters["AgeInheritanceReduction"]; }
83    }
84    private IValueParameter<IntValue> MatingPoolRangeParameter {
85      get { return (IValueParameter<IntValue>)Parameters["MatingPoolRange"]; }
86    }
87    private IValueParameter<PercentValue> MatingPoolSelectionPercentageParameter {
88      get { return (IValueLookupParameter<PercentValue>)Parameters["MatingPoolSelectionPercentage"]; }
89    }
90    private IValueParameter<MultiTerminator> TerminatorParameter {
91      get { return (IValueParameter<MultiTerminator>)Parameters["Terminator"]; }
92    }
93    #endregion
94
95    #region Properties
96    public IntValue Seed {
97      get { return SeedParameter.Value; }
98      set { SeedParameter.Value = value; }
99    }
100    public BoolValue SetSeedRandomly {
101      get { return SetSeedRandomlyParameter.Value; }
102      set { SetSeedRandomlyParameter.Value = value; }
103    }
104    public MultiAnalyzer Analyzer {
105      get { return AnalyzerParameter.Value; }
106    }
107    public MultiAnalyzer LayerAnalyzer {
108      get { return LayerAnalyzerParameter.Value; }
109    }
110    public IntValue NumberOfLayers {
111      get { return NumberOfLayersParameter.Value; }
112      set { NumberOfLayersParameter.Value = value; }
113    }
114    public EnumValue<AgingScheme> AgingScheme {
115      get { return AgingSchemeParameter.Value; }
116      set { AgingSchemeParameter.Value = value; }
117    }
118    public IntValue AgeGap {
119      get { return AgeGapParameter.Value; }
120      set { AgeGapParameter.Value = value; }
121    }
122    public IntArray AgeLimits {
123      get { return AgeLimitsParameter.Value; }
124      set { AgeLimitsParameter.Value = value; }
125    }
126    public EnumValue<AgeInheritance> AgeInheritance {
127      get { return AgeInheritanceParameter.Value; }
128      set { AgeInheritanceParameter.Value = value; }
129    }
130    private ReductionOperation AgeInheritanceReduction {
131      get { return AgeInheritanceReductionParameter.Value; }
132      set { AgeInheritanceReductionParameter.Value = value; }
133    }
134    public IntValue MatingPoolRange {
135      get { return MatingPoolRangeParameter.Value; }
136      set { MatingPoolRangeParameter.Value = value; }
137    }
138    public PercentValue MatingPoolSelectionPercentage {
139      get { return MatingPoolSelectionPercentageParameter.Value; }
140      set { MatingPoolSelectionPercentageParameter.Value = value; }
141    }
142    public MultiTerminator Terminators {
143      get { return TerminatorParameter.Value; }
144    }
145    #endregion
146
147    #region Helper Properties
148    protected RandomCreator GlobalRandomCreator {
149      get { return (RandomCreator)OperatorGraph.InitialOperator; }
150    }
151    protected SolutionsCreator SolutionsCreator {
152      get { return OperatorGraph.Iterate().OfType<SolutionsCreator>().First(); }
153    }
154    #endregion
155
156    #region Preconfigured Analyzers
157    [Storable]
158    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
159    [Storable]
160    private BestAverageWorstQualityAnalyzer layerQualityAnalyzer;
161    #endregion
162    #region Preconfigured Terminators
163    [Storable]
164    private ComparisonTerminator<IntValue> evaluationsTerminator;
165    [Storable]
166    private SingleObjectiveQualityTerminator qualityTerminator;
167    [Storable]
168    private ExecutionTimeTerminator executionTimeTerminator;
169    #endregion
170
171    [StorableConstructor]
172    protected Alps(bool deserializing)
173      : base(deserializing) { }
174    protected Alps(Alps original, Cloner cloner)
175      : base(original, cloner) {
176      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
177      layerQualityAnalyzer = cloner.Clone(original.layerQualityAnalyzer);
178      evaluationsTerminator = cloner.Clone(original.evaluationsTerminator);
179      qualityTerminator = cloner.Clone(original.qualityTerminator);
180      executionTimeTerminator = cloner.Clone(original.executionTimeTerminator);
181      Initialize();
182    }
183
184    protected Alps()
185      : base() {
186      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
187      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
188      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the islands.", new MultiAnalyzer()));
189      Parameters.Add(new FixedValueParameter<MultiAnalyzer>("LayerAnalyzer", "The operator used to analyze each layer.", new MultiAnalyzer()));
190      Parameters.Add(new ValueParameter<IntValue>("NumberOfLayers", "The number of layers.", new IntValue(10)));
191      Parameters.Add(new ValueParameter<EnumValue<AgingScheme>>("AgingScheme", "The aging scheme for setting the age-limits for the layers.", new EnumValue<AgingScheme>(ALPS.AgingScheme.Polynomial)));
192      Parameters.Add(new ValueParameter<IntValue>("AgeGap", "The frequency of reseeding the lowest layer and scaling factor for the age-limits for the layers", new IntValue(20)));
193      Parameters.Add(new ValueParameter<IntArray>("AgeLimits", new IntArray(new int[0])) { Hidden = true });
194      Parameters.Add(new ValueParameter<EnumValue<AgeInheritance>>("AgeInheritance", "The operator for determining the age of an offspring based the parents' age.", new EnumValue<AgeInheritance>(ALPS.AgeInheritance.Older)));
195      Parameters.Add(new ValueParameter<ReductionOperation>("AgeInheritanceReduction") { Hidden = true });
196      Parameters.Add(new ValueParameter<IntValue>("MatingPoolRange", "The range of layers used for creating a mating pool. (1 = current + previous layer)", new IntValue(1)) { Hidden = true });
197      Parameters.Add(new ValueParameter<PercentValue>("MatingPoolSelectionPercentage", "Percentage of the previous layers used for creating a mating pool.", new PercentValue(1.0, restrictToUnitInterval: true)) { Hidden = true });
198      Parameters.Add(new ValueParameter<MultiTerminator>("Terminator", "The termination criteria which sould be checked.", new MultiTerminator()));
199
200      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
201      layerQualityAnalyzer = new BestAverageWorstQualityAnalyzer();
202
203      ParameterizeAgeLimits();
204      ParameterizeAgeInheritanceReduction();
205
206      ParameterizeAnalyzers();
207      UpdateAnalyzers();
208
209      CreateTerminators();
210      ParameterizeTerminators();
211      UpdateTerminators();
212
213      Initialize();
214    }
215
216
217    #region Events
218    public override void Prepare() {
219      if (Problem != null)
220        base.Prepare();
221    }
222
223    protected override void OnProblemChanged() {
224      base.OnProblemChanged();
225      ParameterizeStochasticOperator(Problem.SolutionCreator);
226      ParameterizeStochasticOperatorForLayer(Problem.Evaluator);
227      foreach (var @operator in Problem.Operators.OfType<IOperator>())
228        ParameterizeStochasticOperator(@operator);
229      ParameterizeSolutionsCreator();
230      ParameterizeAnalyzers();
231      ParameterizeTerminators();
232      UpdateAnalyzers();
233      UpdateTerminators();
234      Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
235    }
236    protected override void RegisterProblemEvents() {
237      base.RegisterProblemEvents();
238      var maximizationParameter = (IValueParameter<BoolValue>)Problem.MaximizationParameter;
239      if (maximizationParameter != null) maximizationParameter.ValueChanged += new EventHandler(MaximizationParameter_ValueChanged);
240    }
241    protected override void DeregisterProblemEvents() {
242      var maximizationParameter = (IValueParameter<BoolValue>)Problem.MaximizationParameter;
243      if (maximizationParameter != null) maximizationParameter.ValueChanged -= new EventHandler(MaximizationParameter_ValueChanged);
244      base.DeregisterProblemEvents();
245    }
246
247    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
248      base.Problem_SolutionCreatorChanged(sender, e);
249      ParameterizeStochasticOperator(Problem.SolutionCreator);
250      ParameterizeSolutionsCreator();
251    }
252    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
253      base.Problem_EvaluatorChanged(sender, e);
254      ParameterizeStochasticOperatorForLayer(Problem.Evaluator);
255      ParameterizeSolutionsCreator();
256      ParameterizeAnalyzers();
257      Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
258    }
259
260    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
261      foreach (var @operator in Problem.Operators.OfType<IOperator>())
262        ParameterizeStochasticOperator(@operator);
263      UpdateAnalyzers();
264      UpdateTerminators();
265      base.Problem_OperatorsChanged(sender, e);
266    }
267    protected virtual void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
268      ParameterizeAnalyzers();
269    }
270    private void MaximizationParameter_ValueChanged(object sender, EventArgs e) {
271      ParameterizeTerminators();
272    }
273    private void QualityAnalyzer_CurrentBestQualityParameter_NameChanged(object sender, EventArgs e) {
274      ParameterizeTerminators();
275    }
276
277    private void AgeGapParameter_ValueChanged(object sender, EventArgs e) {
278      AgeGap.ValueChanged += AgeGap_ValueChanged;
279      ParameterizeAgeLimits();
280    }
281    private void AgeGap_ValueChanged(object sender, EventArgs e) {
282      ParameterizeAgeLimits();
283    }
284    private void AgingSchemeParameter_ValueChanged(object sender, EventArgs e) {
285      AgingScheme.ValueChanged += AgingScheme_ValueChanged;
286      ParameterizeAgeLimits();
287    }
288    private void AgingScheme_ValueChanged(object sender, EventArgs e) {
289      ParameterizeAgeLimits();
290    }
291    private void NumberOfLayersParameter_ValueChanged(object sender, EventArgs e) {
292      NumberOfLayers.ValueChanged += NumberOfLayers_ValueChanged;
293      ParameterizeAgeLimits();
294    }
295    private void NumberOfLayers_ValueChanged(object sender, EventArgs e) {
296      ParameterizeAgeLimits();
297    }
298    private void AgeInheritanceParameter_ValueChanged(object sender, EventArgs e) {
299      AgeInheritance.ValueChanged += AgeInheritance_ValueChanged;
300      ParameterizeAgeInheritanceReduction();
301    }
302    private void AgeInheritance_ValueChanged(object sender, EventArgs e) {
303      ParameterizeAgeInheritanceReduction();
304    }
305    private void AnalyzerOperators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IAnalyzer>> e) {
306      foreach (var analyzer in e.Items) {
307        foreach (var parameter in analyzer.Value.Parameters.OfType<IScopeTreeLookupParameter>()) {
308          parameter.Depth = 2;
309        }
310      }
311    }
312    private void LayerAnalyzerOperators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IAnalyzer>> e) {
313      foreach (var analyzer in e.Items) {
314        IParameter resultParameter;
315        if (analyzer.Value.Parameters.TryGetValue("Results", out resultParameter)) {
316          var lookupParameter = resultParameter as ILookupParameter;
317          if (lookupParameter != null)
318            lookupParameter.ActualName = "LayerResults";
319        }
320        foreach (var parameter in analyzer.Value.Parameters.OfType<IScopeTreeLookupParameter>()) {
321          parameter.Depth = 1;
322        }
323      }
324    }
325    #endregion
326
327    #region Parameterization
328    private void Initialize() {
329      if (Problem != null)
330        Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
331      AgeGapParameter.ValueChanged += AgeGapParameter_ValueChanged;
332      AgeGap.ValueChanged += AgeGap_ValueChanged;
333      AgingSchemeParameter.ValueChanged += AgingSchemeParameter_ValueChanged;
334      AgingScheme.ValueChanged += AgingScheme_ValueChanged;
335      NumberOfLayersParameter.ValueChanged += NumberOfLayersParameter_ValueChanged;
336      NumberOfLayers.ValueChanged += NumberOfLayers_ValueChanged;
337      AgeInheritanceParameter.ValueChanged += AgeInheritanceParameter_ValueChanged;
338      AgeInheritance.ValueChanged += AgeInheritance_ValueChanged;
339      Analyzer.Operators.ItemsAdded += AnalyzerOperators_ItemsAdded;
340      LayerAnalyzer.Operators.ItemsAdded += LayerAnalyzerOperators_ItemsAdded;
341      qualityAnalyzer.CurrentBestQualityParameter.NameChanged += new EventHandler(QualityAnalyzer_CurrentBestQualityParameter_NameChanged);
342    }
343    private void ParameterizeSolutionsCreator() {
344      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
345      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
346    }
347    private void ParameterizeAnalyzers() {
348      qualityAnalyzer.ResultsParameter.ActualName = "Results";
349      qualityAnalyzer.ResultsParameter.Hidden = true;
350      qualityAnalyzer.QualityParameter.Depth = 2;
351      layerQualityAnalyzer.ResultsParameter.ActualName = "Results";
352      layerQualityAnalyzer.ResultsParameter.Hidden = true;
353      layerQualityAnalyzer.QualityParameter.Depth = 1;
354      if (Problem != null) {
355        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
356        qualityAnalyzer.MaximizationParameter.Hidden = true;
357        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
358        qualityAnalyzer.QualityParameter.Hidden = true;
359        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
360        qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
361        layerQualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
362        layerQualityAnalyzer.MaximizationParameter.Hidden = true;
363        layerQualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
364        layerQualityAnalyzer.QualityParameter.Hidden = true;
365        layerQualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
366        layerQualityAnalyzer.BestKnownQualityParameter.Hidden = true;
367      }
368    }
369    private void ParameterizeTerminators() {
370      qualityTerminator.Parameterize(qualityAnalyzer.CurrentBestQualityParameter, Problem);
371    }
372    private void ParameterizeAgeInheritanceReduction() {
373      AgeInheritanceReduction.Value = GetAgeInheritanceReduction(AgeInheritance.Value);
374    }
375    protected abstract ReductionOperations GetAgeInheritanceReduction(AgeInheritance ageInheritance);
376    private void ParameterizeAgeLimits() {
377      var scheme = AgingScheme.Value;
378      int ageGap = AgeGap.Value;
379      int numberOfLayers = NumberOfLayers.Value;
380      AgeLimits = scheme.CalculateAgeLimits(ageGap, numberOfLayers);
381    }
382    protected virtual void ParameterizeStochasticOperator(IOperator @operator) {
383      var stochasticOperator = @operator as IStochasticOperator;
384      if (stochasticOperator != null) {
385        stochasticOperator.RandomParameter.ActualName = "GlobalRandom";
386        stochasticOperator.RandomParameter.Hidden = true;
387      }
388    }
389    protected virtual void ParameterizeStochasticOperatorForLayer(IOperator @operator) {
390      var stochasticOperator = @operator as IStochasticOperator;
391      if (stochasticOperator != null) {
392        stochasticOperator.RandomParameter.ActualName = "LocalRandom";
393        stochasticOperator.RandomParameter.Hidden = true;
394      }
395    }
396    #endregion
397
398    #region Updates
399    private void UpdateAnalyzers() {
400      Analyzer.Operators.Clear();
401      LayerAnalyzer.Operators.Clear();
402
403      Analyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
404      LayerAnalyzer.Operators.Add(layerQualityAnalyzer, layerQualityAnalyzer.EnabledByDefault);
405
406      if (Problem != null) {
407        foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>()) {
408          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
409        }
410      }
411    }
412    protected virtual void UpdateTerminators() {
413      var newTerminators = new Dictionary<ITerminator, bool> {
414        {evaluationsTerminator, Terminators.Operators.Contains(evaluationsTerminator) && Terminators.Operators.ItemChecked(evaluationsTerminator)},
415        {qualityTerminator, Terminators.Operators.Contains(qualityTerminator) && Terminators.Operators.ItemChecked(qualityTerminator) },
416        {executionTimeTerminator, Terminators.Operators.Contains(executionTimeTerminator) && Terminators.Operators.ItemChecked(executionTimeTerminator)}
417      };
418      if (Problem != null) {
419        foreach (var terminator in Problem.Operators.OfType<ITerminator>())
420          newTerminators.Add(terminator, !Terminators.Operators.Contains(terminator) || Terminators.Operators.ItemChecked(terminator));
421      }
422
423      Terminators.Operators.Clear();
424
425      foreach (var newTerminator in newTerminators)
426        Terminators.Operators.Add(newTerminator.Key, newTerminator.Value);
427    }
428    protected virtual void CreateTerminators() {
429      evaluationsTerminator = new ComparisonTerminator<IntValue>("EvaluatedSolutions", ComparisonType.Less, new IntValue(int.MaxValue)) { Name = "Evaluations" };
430      qualityTerminator = new SingleObjectiveQualityTerminator() { Name = "Quality" };
431      executionTimeTerminator = new ExecutionTimeTerminator(this, new TimeSpanValue(TimeSpan.FromMinutes(5)));
432    }
433    #endregion
434  }
435}
Note: See TracBrowser for help on using the repository browser.