Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CMAES/HeuristicLab.Algorithms.CMAEvolutionStrategy/3.3/CMAEvolutionStrategy.cs @ 9121

Last change on this file since 9121 was 9121, checked in by abeham, 11 years ago

#1961: Added wiring code, removed obsolete parameters, simplified mainloop slightly, changed sigmabounds to a matrix

  • Property svn:mime-type set to application/octet-stream
File size: 37.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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 HeuristicLab.Analysis;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Optimization.Operators;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Random;
32using System;
33using System.Linq;
34
35namespace HeuristicLab.Algorithms.CMAEvolutionStrategy {
36  [Item("CMA Evolution Strategy", "An evolution strategy based on covariance matrix adaptation.")]
37  [Creatable("Algorithms")]
38  [StorableClass]
39  public sealed class CMAEvolutionStrategy : HeuristicOptimizationEngineAlgorithm, IStorableContent {
40    public string Filename { get; set; }
41
42    #region Problem Properties
43    public override Type ProblemType {
44      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
45    }
46    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
47      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
48      set { base.Problem = value; }
49    }
50    #endregion
51
52    #region Parameter Properties
53    private IValueParameter<MultiAnalyzer> AnalyzerParameter {
54      get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
55    }
56    private IValueParameter<IntValue> SeedParameter {
57      get { return (IValueParameter<IntValue>)Parameters["Seed"]; }
58    }
59    private IValueParameter<BoolValue> SetSeedRandomlyParameter {
60      get { return (IValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
61    }
62    private IValueParameter<IntValue> PopulationSizeParameter {
63      get { return (IValueParameter<IntValue>)Parameters["PopulationSize"]; }
64    }
65    private IValueParameter<IntValue> MaximumGenerationsParameter {
66      get { return (IValueParameter<IntValue>)Parameters["MaximumGenerations"]; }
67    }
68    private IValueParameter<IntValue> MaximumEvaluatedSolutionsParameter {
69      get { return (IValueParameter<IntValue>)Parameters["MaximumEvaluatedSolutions"]; }
70    }
71    private IValueParameter<DoubleArray> InitialSigmaParameter {
72      get { return (IValueParameter<DoubleArray>)Parameters["InitialSigma"]; }
73    }
74    private IConstrainedValueParameter<ICMAESInitializer> CMAESInitializerParameter {
75      get { return (IConstrainedValueParameter<ICMAESInitializer>)Parameters["CMAESInitializer"]; }
76    }
77    private IConstrainedValueParameter<ICMAESManipulator> CMAESMutatorParameter {
78      get { return (IConstrainedValueParameter<ICMAESManipulator>)Parameters["CMAESMutator"]; }
79    }
80    private IConstrainedValueParameter<ICMAESRecombinator> CMAESRecombinatorParameter {
81      get { return (IConstrainedValueParameter<ICMAESRecombinator>)Parameters["CMAESRecombinator"]; }
82    }
83    private IConstrainedValueParameter<ICMAESUpdater> CMAESUpdaterParameter {
84      get { return (IConstrainedValueParameter<ICMAESUpdater>)Parameters["CMAESUpdater"]; }
85    }
86    #endregion
87
88    #region Properties
89    public IntValue Seed {
90      get { return SeedParameter.Value; }
91      set { SeedParameter.Value = value; }
92    }
93    public BoolValue SetSeedRandomly {
94      get { return SetSeedRandomlyParameter.Value; }
95      set { SetSeedRandomlyParameter.Value = value; }
96    }
97    public IntValue PopulationSize {
98      get { return PopulationSizeParameter.Value; }
99      set { PopulationSizeParameter.Value = value; }
100    }
101    public IntValue MaximumGenerations {
102      get { return MaximumGenerationsParameter.Value; }
103      set { MaximumGenerationsParameter.Value = value; }
104    }
105    public IntValue MaximumEvaluatedSolutions {
106      get { return MaximumEvaluatedSolutionsParameter.Value; }
107      set { MaximumEvaluatedSolutionsParameter.Value = value; }
108    }
109    public DoubleArray InitialSigma {
110      get { return InitialSigmaParameter.Value; }
111      set { InitialSigmaParameter.Value = value; }
112    }
113    public ICMAESManipulator CMAESMutator {
114      get { return CMAESMutatorParameter.Value; }
115      set { CMAESMutatorParameter.Value = value; }
116    }
117    public ICMAESRecombinator CMAESRecombinator {
118      get { return CMAESRecombinatorParameter.Value; }
119      set { CMAESRecombinatorParameter.Value = value; }
120    }
121    public MultiAnalyzer Analyzer {
122      get { return AnalyzerParameter.Value; }
123      set { AnalyzerParameter.Value = value; }
124    }
125    public ICMAESInitializer CMAESInitializer {
126      get { return CMAESInitializerParameter.Value; }
127      set { CMAESInitializerParameter.Value = value; }
128    }
129    public ICMAESUpdater CMAESUpdater {
130      get { return CMAESUpdaterParameter.Value; }
131      set { CMAESUpdaterParameter.Value = value; }
132    }
133
134    private RandomCreator RandomCreator {
135      get { return (RandomCreator)OperatorGraph.InitialOperator; }
136    }
137    private SolutionsCreator SolutionsCreator {
138      get { return (SolutionsCreator)RandomCreator.Successor; }
139    }
140    private CMAEvolutionStrategyMainLoop MainLoop {
141      get { return FindMainLoop(OperatorGraph.InitialOperator); }
142    }
143    [Storable]
144    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
145    #endregion
146
147    public CMAEvolutionStrategy()
148      : base() {
149      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
150      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
151      Parameters.Add(new ValueParameter<IntValue>("PopulationSize", "λ (lambda) - the size of the offspring population.", new IntValue(20)));
152      Parameters.Add(new ValueParameter<IntValue>("MaximumGenerations", "The maximum number of generations which should be processed.", new IntValue(1000)));
153      Parameters.Add(new ValueParameter<IntValue>("MaximumEvaluatedSolutions", "The maximum number of evaluated solutions that should be computed.", new IntValue(int.MaxValue)));
154      Parameters.Add(new ValueParameter<DoubleArray>("InitialSigma", "The initial sigma can be a single value or a value for each dimension. All values need to be > 0.", new DoubleArray(new[] { 0.5 })));
155      Parameters.Add(new ConstrainedValueParameter<ICMAESRecombinator>("CMAESRecombinator", "The operator used to calculate the new mean."));
156      Parameters.Add(new ConstrainedValueParameter<ICMAESManipulator>("CMAESMutator", "The operator used to manipulate a point."));
157      Parameters.Add(new ConstrainedValueParameter<ICMAESInitializer>("CMAESInitializer", "The operator that initializes the covariance matrix and strategy parameters."));
158      Parameters.Add(new ConstrainedValueParameter<ICMAESUpdater>("CMAESUpdater", "The operator that updates the covariance matrix and strategy parameters."));
159      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
160
161      var randomCreator = new RandomCreator();
162      var solutionsCreator = new SolutionsCreator();
163      var variableCreator = new VariableCreator();
164      var cmaesInitializer = new Placeholder();
165      var resultsCollector = new ResultsCollector();
166      var mainLoop = new CMAEvolutionStrategyMainLoop();
167
168      OperatorGraph.InitialOperator = randomCreator;
169
170      randomCreator.RandomParameter.ActualName = "Random";
171      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
172      randomCreator.SeedParameter.Value = null;
173      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
174      randomCreator.SetSeedRandomlyParameter.Value = null;
175      randomCreator.Successor = solutionsCreator;
176
177      solutionsCreator.NumberOfSolutions = new IntValue(1);
178      solutionsCreator.Successor = variableCreator;
179
180      variableCreator.Name = "Initialize Variables";
181      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(1)));
182      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Generations", new IntValue(0)));
183      variableCreator.Successor = cmaesInitializer;
184
185      cmaesInitializer.OperatorParameter.ActualName = CMAESInitializerParameter.Name;
186      cmaesInitializer.Successor = resultsCollector;
187
188      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("EvaluatedSolutions"));
189      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Generations"));
190      resultsCollector.ResultsParameter.ActualName = "Results";
191      resultsCollector.Successor = mainLoop;
192
193      mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
194      mainLoop.PopulationSizeParameter.ActualName = PopulationSizeParameter.Name;
195      mainLoop.MaximumGenerationsParameter.ActualName = MaximumGenerationsParameter.Name;
196      mainLoop.MaximumEvaluatedSolutionsParameter.ActualName = MaximumEvaluatedSolutionsParameter.Name;
197      mainLoop.MutatorParameter.ActualName = CMAESMutatorParameter.Name;
198      mainLoop.RecombinatorParameter.ActualName = CMAESRecombinatorParameter.Name;
199      mainLoop.CMAESUpdaterParameter.ActualName = CMAESUpdaterParameter.Name;
200      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
201      mainLoop.ResultsParameter.ActualName = "Results";
202      mainLoop.EvaluatedSolutionsParameter.ActualName = "EvaluatedSolutions";
203      mainLoop.GenerationsParameter.ActualName = "Generations";
204      mainLoop.MuParameter.ActualName = "Mu";
205
206      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
207
208      Initialize();
209      Parameterize();
210    }
211    [StorableConstructor]
212    private CMAEvolutionStrategy(bool deserializing) : base(deserializing) { }
213    [StorableHook(HookType.AfterDeserialization)]
214    private void AfterDeserialization() {
215      Initialize();
216    }
217
218    private CMAEvolutionStrategy(CMAEvolutionStrategy original, Cloner cloner)
219      : base(original, cloner) {
220      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
221      Initialize();
222    }
223    public override IDeepCloneable Clone(Cloner cloner) {
224      return new CMAEvolutionStrategy(this, cloner);
225    }
226
227    public override void Prepare() {
228      if (Problem != null) base.Prepare();
229    }
230
231    #region Events
232    protected override void OnProblemChanged() {
233      Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
234      UpdateOperators();
235      Parameterize();
236      base.OnProblemChanged();
237    }
238    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
239      Parameterize();
240      base.Problem_SolutionCreatorChanged(sender, e);
241    }
242    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
243      Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
244      Parameterize();
245      base.Problem_EvaluatorChanged(sender, e);
246    }
247    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
248      UpdateOperators();
249      Parameterize();
250      base.Problem_OperatorsChanged(sender, e);
251    }
252    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
253      Parameterize();
254    }
255    private bool cmaesInitializerSync;
256    private void CMAESInitializerParameter_ValueChanged(object sender, EventArgs e) {
257      if (cmaesInitializerSync) return;
258      UpdateOperators();
259      Parameterize();
260    }
261    #endregion
262
263    #region Helpers
264    private void Initialize() {
265      CMAESInitializerParameter.ValueChanged += CMAESInitializerParameter_ValueChanged;
266      if (Problem != null)
267        Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
268    }
269    private void UpdateOperators() {
270      cmaesInitializerSync = true;
271      try {
272        var oldInitializer = CMAESInitializer;
273        var oldMutator = CMAESMutator;
274        var oldRecombinator = CMAESRecombinator;
275        var oldUpdater = CMAESUpdater;
276        CMAESInitializerParameter.ValidValues.Clear();
277        CMAESMutatorParameter.ValidValues.Clear();
278        CMAESRecombinatorParameter.ValidValues.Clear();
279        CMAESUpdaterParameter.ValidValues.Clear();
280
281        if (Problem != null) {
282          foreach (var initializer in Problem.Operators.OfType<ICMAESInitializer>())
283            CMAESInitializerParameter.ValidValues.Add(initializer);
284          if (oldInitializer != null) {
285            var tmp = CMAESInitializerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldInitializer.GetType());
286            if (tmp != null) CMAESInitializer = tmp;
287          } else if (CMAESInitializerParameter.ValidValues.Count > 0)
288            CMAESInitializer = CMAESInitializerParameter.ValidValues.First();
289
290          if (CMAESInitializer != null) {
291            foreach (
292              var mutator in
293                Problem.Operators.OfType<ICMAESManipulator>().Where(x => x.CMAType == CMAESInitializer.CMAType))
294              CMAESMutatorParameter.ValidValues.Add(mutator);
295            if (oldMutator != null) {
296              var tmp = CMAESMutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
297              if (tmp != null) CMAESMutator = tmp;
298            } else if (CMAESMutatorParameter.ValidValues.Count > 0) CMAESMutator = CMAESMutatorParameter.ValidValues.First();
299
300            foreach (
301              var recombinator in
302                Problem.Operators.OfType<ICMAESRecombinator>().Where(x => x.CMAType == CMAESInitializer.CMAType))
303              CMAESRecombinatorParameter.ValidValues.Add(recombinator);
304            if (oldRecombinator != null) {
305              var tmp = CMAESRecombinatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldUpdater.GetType());
306              if (tmp != null) CMAESRecombinator = tmp;
307            } else if (CMAESRecombinatorParameter.ValidValues.Count > 0)
308              CMAESRecombinator = CMAESRecombinatorParameter.ValidValues.First();
309
310            foreach (
311              var updater in Problem.Operators.OfType<ICMAESUpdater>().Where(x => x.CMAType == CMAESInitializer.CMAType)
312              )
313              CMAESUpdaterParameter.ValidValues.Add(updater);
314            if (oldUpdater != null) {
315              var tmp = CMAESUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldUpdater.GetType());
316              if (tmp != null) CMAESUpdater = tmp;
317            } else if (CMAESUpdaterParameter.ValidValues.Count > 0) CMAESUpdater = CMAESUpdaterParameter.ValidValues.First();
318          }
319        }
320
321        Analyzer.Operators.Clear();
322        if (Problem != null) {
323          foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
324            foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
325              param.Depth = 1;
326            Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
327          }
328        }
329        Analyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
330      } finally { cmaesInitializerSync = false; }
331    }
332    private void Parameterize() {
333      if (Problem != null) {
334        SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
335        SolutionsCreator.EvaluatorParameter.Hidden = true;
336        SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
337        SolutionsCreator.SolutionCreatorParameter.Hidden = true;
338
339        MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
340        MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
341        MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
342        MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
343
344        foreach (var op in Problem.Operators.OfType<IStochasticOperator>()) {
345          op.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
346          op.RandomParameter.Hidden = true;
347        }
348
349        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
350        qualityAnalyzer.MaximizationParameter.Hidden = true;
351        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
352        qualityAnalyzer.QualityParameter.Depth = 1;
353        qualityAnalyzer.QualityParameter.Hidden = true;
354        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
355        qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
356
357        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
358          op.IterationsParameter.ActualName = "Generations";
359          op.IterationsParameter.Hidden = true;
360          op.MaximumIterationsParameter.ActualName = "MaximumGenerations";
361          op.MaximumIterationsParameter.Hidden = true;
362        }
363
364        foreach (var op in Problem.Operators.OfType<ICMAESInitializer>()) {
365          op.InitialSigmaParameter.Value = null;
366          op.InitialSigmaParameter.ActualName = InitialSigmaParameter.Name;
367          op.MuParameter.ActualName = "Mu";
368          op.PopulationSizeParameter.ActualName = PopulationSizeParameter.Name;
369        }
370      } else {
371        qualityAnalyzer.MaximizationParameter.Hidden = false;
372        qualityAnalyzer.QualityParameter.Hidden = false;
373        qualityAnalyzer.BestKnownQualityParameter.Hidden = false;
374      }
375
376      qualityAnalyzer.ResultsParameter.ActualName = "Results";
377      qualityAnalyzer.ResultsParameter.Hidden = true;
378    }
379
380    private CMAEvolutionStrategyMainLoop FindMainLoop(IOperator start) {
381      var mainLoop = start;
382      while (mainLoop != null && !(mainLoop is CMAEvolutionStrategyMainLoop))
383        mainLoop = ((SingleSuccessorOperator)mainLoop).Successor;
384      if (mainLoop == null) return null;
385      return (CMAEvolutionStrategyMainLoop)mainLoop;
386    }
387    #endregion
388  }
389}
Note: See TracBrowser for help on using the repository browser.