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

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

Modified the ES interface in the trunk to provide controls for the more advanced sigmaSA-ES (ticket #84)

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