Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive_Milestone3/sources/HeuristicLab.ES/3.2/ES.cs @ 6593

Last change on this file since 6593 was 2052, checked in by abeham, 16 years ago

Improved ES GUI according to #674

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