source: trunk/sources/HeuristicLab.ES/ES.cs @ 1222

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

Updated ES to uniformly distributed initialization of strategy vector #495
Fixed Plus/Comma display bug on load #491
Removed some unnecessary references
Added necessary reference to RealVector

File size: 27.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2009 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.Xml;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Operators;
28using HeuristicLab.Random;
29using HeuristicLab.Logging;
30using HeuristicLab.Selection;
31using HeuristicLab.RealVector;
32
33namespace HeuristicLab.ES {
34  /// <summary>
35  /// Class for the heuristic optimization technique "evolution strategy".
36  /// </summary>
37  public class ES : ItemBase, IEditable {
38    #region Create Operators
39    /// <summary>
40    /// Creates a new evolution strategy.
41    /// </summary>
42    /// <param name="engine">The engine of the ES to create.</param>
43    public static void Create(IEngine engine) {
44      engine.OperatorGraph.Clear();
45
46      CombinedOperator co = CreateES();
47      co.Name = "σSA-ES";
48      engine.OperatorGraph.AddOperator(co);
49      engine.OperatorGraph.InitialOperator = co;
50
51      engine.Reset();
52    }
53    private static CombinedOperator CreateES() {
54      CombinedOperator op = new CombinedOperator();
55      SequentialProcessor sp = new SequentialProcessor();
56      op.OperatorGraph.AddOperator(sp);
57      op.OperatorGraph.InitialOperator = sp;
58
59      CombinedOperator co1 = CreateVariableInjection();
60      co1.Name = "Variable Injection";
61      op.OperatorGraph.AddOperator(co1);
62      sp.AddSubOperator(co1);
63
64      // place holder for ProblemInjector
65      EmptyOperator eo1 = new EmptyOperator();
66      eo1.Name = "ProblemInjector";
67      op.OperatorGraph.AddOperator(eo1);
68      co1.AddSubOperator(eo1);
69
70      CombinedOperator co2 = CreatePopulationInitialization();
71      co2.Name = "Population Initialization";
72      op.OperatorGraph.AddOperator(co2);
73      sp.AddSubOperator(co2);
74
75      // place holder for SolutionGenerator
76      EmptyOperator eo2 = new EmptyOperator();
77      eo2.Name = "SolutionGenerator";
78      op.OperatorGraph.AddOperator(eo2);
79      co2.AddSubOperator(eo2);
80
81      // place holder for Evaluator
82      EmptyOperator eo3 = new EmptyOperator();
83      eo3.Name = "Evaluator";
84      op.OperatorGraph.AddOperator(eo3);
85      co2.AddSubOperator(eo3);
86
87      CombinedOperator co3 = CreateESMain();
88      co3.Name = "ES Main";
89      op.OperatorGraph.AddOperator(co3);
90      sp.AddSubOperator(co3);
91
92      // place holder for Mutator
93      EmptyOperator eo4 = new EmptyOperator();
94      eo4.Name = "Mutator";
95      op.OperatorGraph.AddOperator(eo4);
96      co3.AddSubOperator(eo4);
97
98      // place holder for Evaluator
99      co3.AddSubOperator(eo3);
100
101      // place holder for Recombinator
102      EmptyOperator eo5 = new EmptyOperator();
103      eo5.Name = "Recombinator";
104      op.OperatorGraph.AddOperator(eo5);
105      co3.AddSubOperator(eo5);
106
107      return op;
108    }
109    private static CombinedOperator CreateVariableInjection() {
110      CombinedOperator op = new CombinedOperator();
111      SequentialProcessor sp = new SequentialProcessor();
112      op.OperatorGraph.AddOperator(sp);
113      op.OperatorGraph.InitialOperator = sp;
114
115      RandomInjector ri = new RandomInjector();
116      op.OperatorGraph.AddOperator(ri);
117      sp.AddSubOperator(ri);
118
119      OperatorExtractor oe = new OperatorExtractor();
120      oe.Name = "ProblemInjector";
121      oe.GetVariableInfo("Operator").ActualName = "ProblemInjector";
122      op.OperatorGraph.AddOperator(oe);
123      sp.AddSubOperator(oe);
124
125      VariableInjector vi = new VariableInjector();
126      vi.AddVariable(new Variable("ESmu", new IntData(1)));
127      vi.AddVariable(new Variable("ESrho", new IntData(1)));
128      vi.AddVariable(new Variable("ESlambda", new IntData(1)));
129      vi.AddVariable(new Variable("EvaluatedSolutions", new IntData()));
130      vi.AddVariable(new Variable("PlusNotation", new BoolData(true)));
131      vi.AddVariable(new Variable("ProblemDimension", new IntData(1)));
132      vi.AddVariable(new Variable("ShakingFactorsMin", new DoubleData(0.1)));
133      vi.AddVariable(new Variable("ShakingFactorsMax", new DoubleData(5.0)));
134      vi.AddVariable(new Variable("Generations", new IntData()));
135      vi.AddVariable(new Variable("MaximumGenerations", new IntData(1000)));
136      vi.AddVariable(new Variable("GeneralLearningRate", new DoubleData(1.0 / Math.Sqrt(2))));
137      vi.AddVariable(new Variable("LearningRate", new DoubleData(1.0 / Math.Sqrt(2))));
138      op.OperatorGraph.AddOperator(vi);
139      sp.AddSubOperator(vi);
140
141      return op;
142    }
143    private static CombinedOperator CreatePopulationInitialization() {
144      CombinedOperator op = new CombinedOperator();
145      SequentialProcessor sp1 = new SequentialProcessor();
146      op.OperatorGraph.AddOperator(sp1);
147      op.OperatorGraph.InitialOperator = sp1;
148
149      SubScopesCreater ssc = new SubScopesCreater();
150      ssc.GetVariableInfo("SubScopes").ActualName = "ESmu";
151      op.OperatorGraph.AddOperator(ssc);
152      sp1.AddSubOperator(ssc);
153
154      UniformSequentialSubScopesProcessor ussp = new UniformSequentialSubScopesProcessor();
155      op.OperatorGraph.AddOperator(ussp);
156      sp1.AddSubOperator(ussp);
157
158      SequentialProcessor sp2 = new SequentialProcessor();
159      op.OperatorGraph.AddOperator(sp2);
160      ussp.AddSubOperator(sp2);
161
162      OperatorExtractor oe1 = new OperatorExtractor();
163      oe1.Name = "SolutionGenerator";
164      oe1.GetVariableInfo("Operator").ActualName = "SolutionGenerator";
165      op.OperatorGraph.AddOperator(oe1);
166      sp2.AddSubOperator(oe1);
167
168      OperatorExtractor oe2 = new OperatorExtractor();
169      oe2.Name = "Evaluator";
170      oe2.GetVariableInfo("Operator").ActualName = "Evaluator";
171      op.OperatorGraph.AddOperator(oe2);
172      sp2.AddSubOperator(oe2);
173
174      Counter c = new Counter();
175      c.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
176      op.OperatorGraph.AddOperator(c);
177      sp2.AddSubOperator(c);
178
179      UniformRandomRealVectorGenerator urrvg = new UniformRandomRealVectorGenerator();
180      urrvg.GetVariableInfo("Length").ActualName = "ProblemDimension";
181      urrvg.GetVariableInfo("Minimum").ActualName = "ShakingFactorsMin";
182      urrvg.GetVariableInfo("Maximum").ActualName = "ShakingFactorsMax";
183      urrvg.GetVariableInfo("RealVector").ActualName = "ShakingFactors";
184      op.OperatorGraph.AddOperator(urrvg);
185      sp2.AddSubOperator(urrvg);
186
187      Sorter s = new Sorter();
188      s.GetVariableInfo("Descending").ActualName = "Maximization";
189      s.GetVariableInfo("Value").ActualName = "Quality";
190      op.OperatorGraph.AddOperator(s);
191      sp1.AddSubOperator(s);
192
193      return op;
194    }
195    private static CombinedOperator CreateESMain() {
196      CombinedOperator op = new CombinedOperator();
197      SequentialProcessor sp = new SequentialProcessor();
198      op.OperatorGraph.AddOperator(sp);
199      op.OperatorGraph.InitialOperator = sp;
200
201      ESRandomSelector rs = new ESRandomSelector();
202      rs.Name = "Child Selector";
203      rs.GetVariableInfo("Lambda").ActualName = "ESlambda";
204      rs.GetVariableInfo("Rho").ActualName = "ESrho";
205      op.OperatorGraph.AddOperator(rs);
206      sp.AddSubOperator(rs);
207
208      SequentialSubScopesProcessor ssp = new SequentialSubScopesProcessor();
209      op.OperatorGraph.AddOperator(ssp);
210      sp.AddSubOperator(ssp);
211
212      EmptyOperator eo = new EmptyOperator();
213      op.OperatorGraph.AddOperator(eo);
214      ssp.AddSubOperator(eo);
215
216      CombinedOperator co1 = CreateCreateChildren();
217      co1.Name = "Create Children";
218      op.OperatorGraph.AddOperator(co1);
219      ssp.AddSubOperator(co1);
220
221      ConditionalBranch cb1 = new ConditionalBranch();
222      cb1.Name = "Plus or Comma Replacement";
223      cb1.GetVariableInfo("Condition").ActualName = "PlusNotation";
224      op.OperatorGraph.AddOperator(cb1);
225      sp.AddSubOperator(cb1);
226
227      MergingReducer mr = new MergingReducer();
228      mr.Name = "Plus Replacement";
229      op.OperatorGraph.AddOperator(mr);
230      cb1.AddSubOperator(mr);
231
232      RightReducer rr = new RightReducer();
233      rr.Name = "Comma Replacement";
234      op.OperatorGraph.AddOperator(rr);
235      cb1.AddSubOperator(rr);
236
237      CombinedOperator co2 = CreateReplacement();
238      co2.Name = "Parents Selection";
239      op.OperatorGraph.AddOperator(co2);
240      sp.AddSubOperator(co2);
241
242      QualityLogger ql = new QualityLogger();
243      op.OperatorGraph.AddOperator(ql);
244      sp.AddSubOperator(ql);
245
246      BestAverageWorstQualityCalculator bawqc = new BestAverageWorstQualityCalculator();
247      op.OperatorGraph.AddOperator(bawqc);
248      sp.AddSubOperator(bawqc);
249
250      DataCollector dc = new DataCollector();
251      ItemList<StringData> names = dc.GetVariable("VariableNames").GetValue<ItemList<StringData>>();
252      names.Add(new StringData("BestQuality"));
253      names.Add(new StringData("AverageQuality"));
254      names.Add(new StringData("WorstQuality"));
255      op.OperatorGraph.AddOperator(dc);
256      sp.AddSubOperator(dc);
257
258      LinechartInjector lci = new LinechartInjector();
259      lci.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
260      lci.GetVariable("NumberOfLines").GetValue<IntData>().Data = 3;
261      op.OperatorGraph.AddOperator(lci);
262      sp.AddSubOperator(lci);
263
264      Counter c = new Counter();
265      c.GetVariableInfo("Value").ActualName = "Generations";
266      op.OperatorGraph.AddOperator(c);
267      sp.AddSubOperator(c);
268
269      LessThanComparator ltc = new LessThanComparator();
270      ltc.GetVariableInfo("LeftSide").ActualName = "Generations";
271      ltc.GetVariableInfo("RightSide").ActualName = "MaximumGenerations";
272      ltc.GetVariableInfo("Result").ActualName = "GenerationsCondition";
273      op.OperatorGraph.AddOperator(ltc);
274      sp.AddSubOperator(ltc);
275
276      ConditionalBranch cb2 = new ConditionalBranch();
277      cb2.GetVariableInfo("Condition").ActualName = "GenerationsCondition";
278      op.OperatorGraph.AddOperator(cb2);
279      sp.AddSubOperator(cb2);
280
281      cb2.AddSubOperator(sp);
282
283      return op;
284    }
285    private static CombinedOperator CreateCreateChildren() {
286      CombinedOperator op = new CombinedOperator();
287      SequentialProcessor sp1 = new SequentialProcessor();
288      op.OperatorGraph.AddOperator(sp1);
289      op.OperatorGraph.InitialOperator = sp1;
290
291      OperatorExtractor oe1 = new OperatorExtractor();
292      oe1.Name = "Recombinator";
293      oe1.GetVariableInfo("Operator").ActualName = "Recombinator";
294      op.OperatorGraph.AddOperator(oe1);
295      sp1.AddSubOperator(oe1);
296
297      UniformSequentialSubScopesProcessor ussp = new UniformSequentialSubScopesProcessor();
298      op.OperatorGraph.AddOperator(ussp);
299      sp1.AddSubOperator(ussp);
300
301      SequentialProcessor sp2 = new SequentialProcessor();
302      op.OperatorGraph.AddOperator(sp2);
303      ussp.AddSubOperator(sp2);
304
305      OperatorExtractor oe2 = new OperatorExtractor();
306      oe2.Name = "Mutator";
307      oe2.GetVariableInfo("Operator").ActualName = "Mutator";
308      op.OperatorGraph.AddOperator(oe2);
309      sp2.AddSubOperator(oe2);
310
311      OperatorExtractor oe3 = new OperatorExtractor();
312      oe3.Name = "Evaluator";
313      oe3.GetVariableInfo("Operator").ActualName = "Evaluator";
314      op.OperatorGraph.AddOperator(oe3);
315      sp2.AddSubOperator(oe3);
316
317      Counter c = new Counter();
318      c.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
319      op.OperatorGraph.AddOperator(c);
320      sp2.AddSubOperator(c);
321
322      Sorter s = new Sorter();
323      s.GetVariableInfo("Value").ActualName = "Quality";
324      s.GetVariableInfo("Descending").ActualName = "Maximization";
325      op.OperatorGraph.AddOperator(s);
326      sp1.AddSubOperator(s);
327
328      return op;
329    }
330    private static CombinedOperator CreateReplacement() {
331      CombinedOperator op = new CombinedOperator();
332      SequentialProcessor sp1 = new SequentialProcessor();
333      op.OperatorGraph.AddOperator(sp1);
334      op.OperatorGraph.InitialOperator = sp1;
335
336      Sorter s = new Sorter();
337      s.GetVariableInfo("Descending").ActualName = "Maximization";
338      s.GetVariableInfo("Value").ActualName = "Quality";
339      op.OperatorGraph.AddOperator(s);
340      sp1.AddSubOperator(s);
341
342      LeftSelector ls = new LeftSelector();
343      ls.Name = "Parents Selector";
344      ls.GetVariableInfo("Selected").ActualName = "ESmu";
345      ls.GetVariable("CopySelected").Value = new BoolData(false);
346      op.OperatorGraph.AddOperator(ls);
347      sp1.AddSubOperator(ls);
348
349      RightReducer rr = new RightReducer();
350      rr.Name = "RightReducer";
351      op.OperatorGraph.AddOperator(rr);
352      sp1.AddSubOperator(rr);
353
354      return op;
355    }
356    #endregion
357
358    #region Properties
359    private IEngine myEngine;
360    /// <summary>
361    /// Gets the engine of the current instance.
362    /// </summary>
363    public IEngine Engine {
364      get { return myEngine; }
365    }
366    private BoolData mySetSeedRandomly;
367    /// <summary>
368    /// Gets or sets the boolean flag whether to set the seed randomly or not.
369    /// </summary>
370    public bool SetSeedRandomly {
371      get { return mySetSeedRandomly.Data; }
372      set { mySetSeedRandomly.Data = value; }
373    }
374    private IntData mySeed;
375    /// <summary>
376    /// Gets or sets the seed of the current instance.
377    /// </summary>
378    /// <remarks>Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>
379    /// in the setter.</remarks>
380    public int Seed {
381      get { return mySeed.Data; }
382      set {
383        mySeed.Data = value;
384        OnChanged();
385      }
386    }
387    private IntData myMu;
388    /// <summary>
389    /// Gets or sets the µ value of the current instance.
390    /// </summary>
391    /// <remarks>Sets also the λ and the ρ value if necessary. Using the comma notation it must hold that λ >= µ and generally µ >= ρ must hold as well. Calls <see cref="ItemBase.OnChanged"/> of
392    /// base class <see cref="ItemBase"/>.</remarks>
393    public int Mu {
394      get { return myMu.Data; }
395      set {
396        if (value > 0) {
397          myMu.Data = value;
398          if (!PlusNotation && value >= Lambda) myLambda.Data = value + 1;
399          if (value < Rho) myRho.Data = value;
400          OnChanged();
401        }
402      }
403    }
404    private IntData myRho;
405    /// <summary>
406    /// Gets or sets the ρ value of the current instance.
407    /// </summary>
408    /// <remarks>Sets also the µ value to be as large as the new ρ value if it was smaller before. Calls <see cref="ItemBase.OnChanged"/> of
409    /// base class <see cref="ItemBase"/>.</remarks>
410    public int Rho {
411      get { return myRho.Data; }
412      set {
413        if (value > 0) {
414          myRho.Data = value;
415          if (value > Mu) Mu = value;
416          OnChanged();
417        }
418      }
419    }
420    private IntData myLambda;
421    /// <summary>
422    /// Gets or sets the λ value of the current instance.
423    /// </summary>
424    /// <remarks>If the comma notation is used, it also changes the µ value to be as large as the new λ value if it was larger before. Note that in general for good optimization results it needs to be fairly larger than mu.
425    /// Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>.</remarks>
426    public int Lambda {
427      get { return myLambda.Data; }
428      set {
429        if (value > 0) {
430          if (PlusNotation) myLambda.Data = value;
431          else {
432            if (value >= 1 && value < Mu) {
433              myLambda.Data = value;
434              myMu.Data = value;
435            } else if (value > Mu) {
436              myLambda.Data = value;
437            }
438          }
439          OnChanged();
440        }
441      }
442    }
443    private BoolData myPlusNotation;
444    /// <summary>
445    /// Gets or sets the boolean flag whether the plus notation is used (true) or the comma notation (false).
446    /// </summary>
447    /// <remarks>If set to false (comma notation) it sets λ to be as large as µ if is lower. Note that in general for good optimization results it needs to be fairly larger than µ.
448    /// Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>.</remarks>
449    public bool PlusNotation {
450      get { return myPlusNotation.Data; }
451      set {
452        if (!value && myPlusNotation.Data) { // from plus to point
453          if (Lambda < Mu) {
454            myLambda.Data = Mu;
455          }
456        }
457        myPlusNotation.Data = value;
458        OnChanged();
459      }
460    }
461    private IntData myProblemDimension;
462    /// <summary>
463    /// Gets or sets the problem dimension which determines the length of the strategy vector.
464    /// </summary>
465    /// <remarks>Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>
466    /// in the setter.</remarks>
467    public int ProblemDimension {
468      get { return myProblemDimension.Data; }
469      set { myProblemDimension.Data = value; }
470    }
471    private DoubleData myShakingFactorsMin;
472    /// <summary>
473    /// Gets or sets the minimal value for each dimension of the strategy vector.
474    /// </summary>
475    /// <remarks>Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>
476    /// in the setter.</remarks>
477    public double ShakingFactorsMin {
478      get { return myShakingFactorsMin.Data; }
479      set {
480        myShakingFactorsMin.Data = value;
481        OnChanged();
482      }
483    }
484    private DoubleData myShakingFactorsMax;
485    /// <summary>
486    /// Gets or sets the maximal value for each dimension of the strategy vector.
487    /// </summary>
488    /// <remarks>Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>
489    /// in the setter.</remarks>
490    public double ShakingFactorsMax {
491      get { return myShakingFactorsMax.Data; }
492      set {
493        myShakingFactorsMax.Data = value;
494        OnChanged();
495      }
496    }
497    private DoubleData myGeneralLearningRate;
498    /// <summary>
499    /// Gets or sets the general learning rate (tau0).
500    /// </summary>
501    /// <remarks>Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>
502    /// in the setter.</remarks>
503    public double GeneralLearningRate {
504      get { return myGeneralLearningRate.Data; }
505      set {
506        if (value > 0.0 && value <= 1.0) {
507          myGeneralLearningRate.Data = value;
508          OnChanged();
509        }
510      }
511    }
512    private DoubleData myLearningRate;
513    /// <summary>
514    /// Gets or sets the learning rate (tau).
515    /// </summary>
516    /// <remarks>Calls <see cref="ItemBase.OnChanged"/> of base class <see cref="ItemBase"/>
517    /// in the setter.</remarks>
518    public double LearningRate {
519      get { return myLearningRate.Data; }
520      set {
521        if (value > 0.0 && value <= 1.0) {
522          myLearningRate.Data = value;
523          OnChanged();
524        }
525      }
526    }
527    private IntData myMaximumGenerations;
528    /// <summary>
529    /// Gets or sets the maximum number of generations.
530    /// </summary>
531    public int MaximumGenerations {
532      get { return myMaximumGenerations.Data; }
533      set { myMaximumGenerations.Data = value; }
534    }
535    private CombinedOperator myES;
536    private IOperator myESMain;
537    private IOperator myVariableInjection;
538    /// <summary>
539    /// Gets or sets the problem injection operator.
540    /// </summary>
541    public IOperator ProblemInjector {
542      get { return myVariableInjection.SubOperators[0]; }
543      set {
544        value.Name = "ProblemInjector";
545        myES.OperatorGraph.RemoveOperator(ProblemInjector.Guid);
546        myES.OperatorGraph.AddOperator(value);
547        myVariableInjection.AddSubOperator(value, 0);
548      }
549    }
550    private IOperator myPopulationInitialization;
551    /// <summary>
552    /// Gets or sets the solution generation operator.
553    /// </summary>
554    public IOperator SolutionGenerator {
555      get { return myPopulationInitialization.SubOperators[0]; }
556      set {
557        value.Name = "SolutionGenerator";
558        myES.OperatorGraph.RemoveOperator(SolutionGenerator.Guid);
559        myES.OperatorGraph.AddOperator(value);
560        myPopulationInitialization.AddSubOperator(value, 0);
561      }
562    }
563    /// <summary>
564    /// Gets or sets the evaluation operator.
565    /// </summary>
566    public IOperator Evaluator {
567      get { return myPopulationInitialization.SubOperators[1]; }
568      set {
569        value.Name = "Evaluator";
570        myES.OperatorGraph.RemoveOperator(Evaluator.Guid);
571        myES.OperatorGraph.AddOperator(value);
572        myPopulationInitialization.AddSubOperator(value, 1);
573        myESMain.AddSubOperator(value, 1);
574      }
575    }
576    /// <summary>
577    /// Gets or sets the mutation operator.
578    /// </summary>
579    public IOperator Mutator {
580      get { return myESMain.SubOperators[0]; }
581      set {
582        value.Name = "Mutator";
583        myES.OperatorGraph.RemoveOperator(Mutator.Guid);
584        myES.OperatorGraph.AddOperator(value);
585        myESMain.AddSubOperator(value, 0);
586      }
587    }
588    /// <summary>
589    /// Gets or sets the recombination operator.
590    /// </summary>
591    public IOperator Recombinator {
592      get { return myESMain.SubOperators[2]; }
593      set {
594        value.Name = "Recombinator";
595        myES.OperatorGraph.RemoveOperator(Recombinator.Guid);
596        myES.OperatorGraph.AddOperator(value);
597        myESMain.AddSubOperator(value, 2);
598      }
599    }
600    #endregion
601
602    /// <summary>
603    /// Initializes a new instance of <see cref="ES"/> having a <see cref="SequentialEngine"/> as engine.
604    /// </summary>
605    public ES() {
606      myEngine = new SequentialEngine.SequentialEngine();
607      Create(myEngine);
608      SetReferences();
609    }
610
611    /// <summary>
612    /// Creates a new instance of <see cref="ESEditor"/> to display the current instance.
613    /// </summary>
614    /// <returns>The created view as <see cref="ESEditor"/>.</returns>
615    public override IView CreateView() {
616      return new ESEditor(this);
617    }
618    /// <summary>
619    /// Creates a new instance of <see cref="ESEditor"/> to display the current instance.
620    /// </summary>
621    /// <returns>The created editor as <see cref="ESEditor"/>.</returns>
622    public virtual IEditor CreateEditor() {
623      return new ESEditor(this);
624    }
625
626    /// <summary>
627    /// Clones the current instance (deep clone).
628    /// </summary>
629    /// <remarks>Uses <see cref="Auxiliary.Clone"/> method of the <see cref="Auxiliary"/> class to
630    /// clone the engine.</remarks>
631    /// <param name="clonedObjects">A dictionary of all already cloned objects.
632    /// (Needed to avoid cycles.)</param>
633    /// <returns>The cloned object as <see cref="ES"/>.</returns>
634    public override object Clone(IDictionary<Guid, object> clonedObjects) {
635      ES clone = new ES();
636      clonedObjects.Add(Guid, clone);
637      clone.myEngine = (IEngine)Auxiliary.Clone(Engine, clonedObjects);
638      return clone;
639    }
640
641    #region SetReferences Method
642    private void SetReferences() {
643      // ES
644      CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
645      myES = co1;
646      // SequentialProcessor in ES
647      SequentialProcessor sp1 = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
648      // Variable Injection
649      CombinedOperator co2 = (CombinedOperator)sp1.SubOperators[0];
650      myVariableInjection = co2;
651      // SequentialProcessor in Variable Injection
652      SequentialProcessor sp2 = (SequentialProcessor)co2.OperatorGraph.InitialOperator;
653      // RandomInjector
654      RandomInjector ri = (RandomInjector)sp2.SubOperators[0];
655      mySetSeedRandomly = ri.GetVariable("SetSeedRandomly").GetValue<BoolData>();
656      mySeed = ri.GetVariable("Seed").GetValue<IntData>();
657      // VariableInjector
658      VariableInjector vi = (VariableInjector)sp2.SubOperators[2];
659      myMu = vi.GetVariable("ESmu").GetValue<IntData>();
660      myRho = vi.GetVariable("ESrho").GetValue<IntData>();
661      myLambda = vi.GetVariable("ESlambda").GetValue<IntData>();
662      myMaximumGenerations = vi.GetVariable("MaximumGenerations").GetValue<IntData>();
663      myPlusNotation = vi.GetVariable("PlusNotation").GetValue<BoolData>();
664      myProblemDimension = vi.GetVariable("ProblemDimension").GetValue<IntData>();
665      myShakingFactorsMin = vi.GetVariable("ShakingFactorsMin").GetValue<DoubleData>();
666      myShakingFactorsMax = vi.GetVariable("ShakingFactorsMax").GetValue<DoubleData>();
667      myGeneralLearningRate = vi.GetVariable("GeneralLearningRate").GetValue<DoubleData>();
668      myLearningRate = vi.GetVariable("LearningRate").GetValue<DoubleData>();
669      // Population Initialization
670      CombinedOperator co3 = (CombinedOperator)sp1.SubOperators[1];
671      myPopulationInitialization = co3;
672      // ES Main
673      CombinedOperator co4 = (CombinedOperator)sp1.SubOperators[2];
674      myESMain = co4;
675    }
676    #endregion
677
678    #region Persistence Methods
679    /// <summary>
680    /// Saves the current instance as <see cref="XmlNode"/> in the specified <paramref name="document"/>.
681    /// </summary>
682    /// <remarks>Calls <see cref="StorableBase.GetXmlNode"/> of base class <see cref="ItemBase"/>.
683    /// <br/>The engine of the current instance is saved as child node with tag name <c>Engine</c>.</remarks>
684    /// <param name="name">The (tag)name of the <see cref="XmlNode"/>.</param>
685    /// <param name="document">The <see cref="XmlDocument"/> where to save the data.</param>
686    /// <param name="persistedObjects">The dictionary of all already persisted objects.
687    /// (Needed to avoid cycles.)</param>
688    /// <returns>The saved <see cref="XmlNode"/>.</returns>
689    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
690      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
691      node.AppendChild(PersistenceManager.Persist("Engine", Engine, document, persistedObjects));
692      return node;
693    }
694    /// <summary>
695    /// Loads the persisted ES from the specified <paramref name="node"/>.
696    /// </summary>
697    /// <remarks>Calls <see cref="StorableBase.Populate"/> of base class <see cref="ItemBase"/>.<br/>
698    /// The engine must be saved as child node with tag name <c>Engine</c> (see
699    /// <see cref="GetXmlNode"/>).</remarks>
700    /// <param name="node">The <see cref="XmlNode"/> where the value is saved.</param>
701    /// <param name="restoredObjects">The dictionary of all already restored objects.
702    /// (Needed to avoid cycles.)</param>
703    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
704      base.Populate(node, restoredObjects);
705      myEngine = (IEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
706      SetReferences();
707    }
708    #endregion
709  }
710}
Note: See TracBrowser for help on using the repository browser.