Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.SGA/SGA.cs @ 1225

Last change on this file since 1225 was 1225, checked in by abeham, 15 years ago

Adapted SGA plugin to use new crossover model, added reference to HeuristicLab.Evolutionary (ticket #496)

File size: 22.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Evolutionary;
29using HeuristicLab.SequentialEngine;
30using HeuristicLab.Operators;
31using HeuristicLab.Random;
32using HeuristicLab.Logging;
33using HeuristicLab.Selection;
34
35namespace HeuristicLab.SGA {
36  /// <summary>
37  /// Class for the heuristic optimization technique "simple genetic algorithm".
38  /// </summary>
39  public class SGA : ItemBase, IEditable {
40    #region Create Operators
41    /// <summary>
42    /// Creates operators for the current instance.
43    /// </summary>
44    /// <param name="engine">The engine where to add the operators.</param>
45    public static void Create(IEngine engine) {
46      engine.OperatorGraph.Clear();
47
48      CombinedOperator co = CreateSGA();
49      co.Name = "SGA";
50      engine.OperatorGraph.AddOperator(co);
51      engine.OperatorGraph.InitialOperator = co;
52
53      engine.Reset();
54    }
55    private static CombinedOperator CreateSGA() {
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 = "ProblemInjector";
69      op.OperatorGraph.AddOperator(eo1);
70      co1.AddSubOperator(eo1);
71
72      CombinedOperator co2 = CreatePopulationInitialization();
73      co2.Name = "Population Initialization";
74      op.OperatorGraph.AddOperator(co2);
75      sp.AddSubOperator(co2);
76
77      // place holder for SolutionGenerator
78      EmptyOperator eo2 = new EmptyOperator();
79      eo2.Name = "SolutionGenerator";
80      op.OperatorGraph.AddOperator(eo2);
81      co2.AddSubOperator(eo2);
82
83      // place holder for Evaluator
84      EmptyOperator eo3 = new EmptyOperator();
85      eo3.Name = "Evaluator";
86      op.OperatorGraph.AddOperator(eo3);
87      co2.AddSubOperator(eo3);
88
89      CombinedOperator co3 = CreateSGAMain();
90      co3.Name = "SGA Main";
91      op.OperatorGraph.AddOperator(co3);
92      sp.AddSubOperator(co3);
93
94      // place holder for Selector
95      EmptyOperator eo4 = new EmptyOperator();
96      eo4.Name = "Selector";
97      op.OperatorGraph.AddOperator(eo4);
98      co3.AddSubOperator(eo4);
99
100      // place holder for Crossover
101      EmptyOperator eo5 = new EmptyOperator();
102      eo5.Name = "Crossover";
103      op.OperatorGraph.AddOperator(eo5);
104      co3.AddSubOperator(eo5);
105
106      // place holder for Mutator
107      EmptyOperator eo6 = new EmptyOperator();
108      eo6.Name = "Mutator";
109      op.OperatorGraph.AddOperator(eo6);
110      co3.AddSubOperator(eo6);
111
112      // place holder for Evaluator
113      co3.AddSubOperator(eo3);
114
115      return op;
116    }
117    private static CombinedOperator CreateVariableInjection() {
118      CombinedOperator op = new CombinedOperator();
119      SequentialProcessor sp = new SequentialProcessor();
120      op.OperatorGraph.AddOperator(sp);
121      op.OperatorGraph.InitialOperator = sp;
122
123      RandomInjector ri = new RandomInjector();
124      op.OperatorGraph.AddOperator(ri);
125      sp.AddSubOperator(ri);
126
127      OperatorExtractor oe = new OperatorExtractor();
128      oe.Name = "ProblemInjector";
129      oe.GetVariableInfo("Operator").ActualName = "ProblemInjector";
130      op.OperatorGraph.AddOperator(oe);
131      sp.AddSubOperator(oe);
132
133      VariableInjector vi = new VariableInjector();
134      vi.AddVariable(new Variable("PopulationSize", new IntData(100)));
135      vi.AddVariable(new Variable("EvaluatedSolutions", new IntData()));
136      vi.AddVariable(new Variable("Parents", new IntData(200)));
137      vi.AddVariable(new Variable("MutationRate", new DoubleData(0.05)));
138      vi.AddVariable(new Variable("Elites", new IntData(1)));
139      vi.AddVariable(new Variable("Generations", new IntData()));
140      vi.AddVariable(new Variable("MaximumGenerations", new IntData(1000)));
141      op.OperatorGraph.AddOperator(vi);
142      sp.AddSubOperator(vi);
143
144      return op;
145    }
146    private static CombinedOperator CreatePopulationInitialization() {
147      CombinedOperator op = new CombinedOperator();
148      SequentialProcessor sp1 = new SequentialProcessor();
149      op.OperatorGraph.AddOperator(sp1);
150      op.OperatorGraph.InitialOperator = sp1;
151
152      SubScopesCreater ssc = new SubScopesCreater();
153      ssc.GetVariableInfo("SubScopes").ActualName = "PopulationSize";
154      op.OperatorGraph.AddOperator(ssc);
155      sp1.AddSubOperator(ssc);
156
157      UniformSequentialSubScopesProcessor ussp = new UniformSequentialSubScopesProcessor();
158      op.OperatorGraph.AddOperator(ussp);
159      sp1.AddSubOperator(ussp);
160
161      SequentialProcessor sp2 = new SequentialProcessor();
162      op.OperatorGraph.AddOperator(sp2);
163      ussp.AddSubOperator(sp2);
164
165      OperatorExtractor oe1 = new OperatorExtractor();
166      oe1.Name = "SolutionGenerator";
167      oe1.GetVariableInfo("Operator").ActualName = "SolutionGenerator";
168      op.OperatorGraph.AddOperator(oe1);
169      sp2.AddSubOperator(oe1);
170
171      OperatorExtractor oe2 = new OperatorExtractor();
172      oe2.Name = "Evaluator";
173      oe2.GetVariableInfo("Operator").ActualName = "Evaluator";
174      op.OperatorGraph.AddOperator(oe2);
175      sp2.AddSubOperator(oe2);
176
177      Counter c = new Counter();
178      c.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
179      op.OperatorGraph.AddOperator(c);
180      sp2.AddSubOperator(c);
181
182      Sorter s = new Sorter();
183      s.GetVariableInfo("Descending").ActualName = "Maximization";
184      s.GetVariableInfo("Value").ActualName = "Quality";
185      op.OperatorGraph.AddOperator(s);
186      sp1.AddSubOperator(s);
187
188      return op;
189    }
190    private static CombinedOperator CreateSGAMain() {
191      CombinedOperator op = new CombinedOperator();
192      SequentialProcessor sp = new SequentialProcessor();
193      op.OperatorGraph.AddOperator(sp);
194      op.OperatorGraph.InitialOperator = sp;
195
196      OperatorExtractor oe = new OperatorExtractor();
197      oe.Name = "Selector";
198      oe.GetVariableInfo("Operator").ActualName = "Selector";
199      op.OperatorGraph.AddOperator(oe);
200      sp.AddSubOperator(oe);
201
202      SequentialSubScopesProcessor ssp = new SequentialSubScopesProcessor();
203      op.OperatorGraph.AddOperator(ssp);
204      sp.AddSubOperator(ssp);
205
206      EmptyOperator eo = new EmptyOperator();
207      op.OperatorGraph.AddOperator(eo);
208      ssp.AddSubOperator(eo);
209
210      CombinedOperator co1 = CreateCreateChildren();
211      co1.Name = "Create Children";
212      op.OperatorGraph.AddOperator(co1);
213      ssp.AddSubOperator(co1);
214
215      CombinedOperator co2 = CreateReplacement();
216      co2.Name = "Replacement";
217      op.OperatorGraph.AddOperator(co2);
218      sp.AddSubOperator(co2);
219
220      QualityLogger ql = new QualityLogger();
221      op.OperatorGraph.AddOperator(ql);
222      sp.AddSubOperator(ql);
223
224      BestAverageWorstQualityCalculator bawqc = new BestAverageWorstQualityCalculator();
225      op.OperatorGraph.AddOperator(bawqc);
226      sp.AddSubOperator(bawqc);
227
228      DataCollector dc = new DataCollector();
229      ItemList<StringData> names = dc.GetVariable("VariableNames").GetValue<ItemList<StringData>>();
230      names.Add(new StringData("BestQuality"));
231      names.Add(new StringData("AverageQuality"));
232      names.Add(new StringData("WorstQuality"));
233      op.OperatorGraph.AddOperator(dc);
234      sp.AddSubOperator(dc);
235
236      LinechartInjector lci = new LinechartInjector();
237      lci.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
238      lci.GetVariable("NumberOfLines").GetValue<IntData>().Data = 3;
239      op.OperatorGraph.AddOperator(lci);
240      sp.AddSubOperator(lci);
241
242      Counter c = new Counter();
243      c.GetVariableInfo("Value").ActualName = "Generations";
244      op.OperatorGraph.AddOperator(c);
245      sp.AddSubOperator(c);
246
247      LessThanComparator ltc = new LessThanComparator();
248      ltc.GetVariableInfo("LeftSide").ActualName = "Generations";
249      ltc.GetVariableInfo("RightSide").ActualName = "MaximumGenerations";
250      ltc.GetVariableInfo("Result").ActualName = "GenerationsCondition";
251      op.OperatorGraph.AddOperator(ltc);
252      sp.AddSubOperator(ltc);
253
254      ConditionalBranch cb = new ConditionalBranch();
255      cb.GetVariableInfo("Condition").ActualName = "GenerationsCondition";
256      op.OperatorGraph.AddOperator(cb);
257      sp.AddSubOperator(cb);
258
259      cb.AddSubOperator(sp);
260
261      return op;
262    }
263    private static CombinedOperator CreateCreateChildren() {
264      CombinedOperator op = new CombinedOperator();
265      SequentialProcessor sp1 = new SequentialProcessor();
266      op.OperatorGraph.AddOperator(sp1);
267      op.OperatorGraph.InitialOperator = sp1;
268
269      ChildrenInitializer ci = new ChildrenInitializer();
270      op.OperatorGraph.AddOperator(ci);
271      sp1.AddSubOperator(ci);
272
273      UniformSequentialSubScopesProcessor ussp = new UniformSequentialSubScopesProcessor();
274      op.OperatorGraph.AddOperator(ussp);
275      sp1.AddSubOperator(ussp);
276
277      SequentialProcessor sp2 = new SequentialProcessor();
278      op.OperatorGraph.AddOperator(sp2);
279      ussp.AddSubOperator(sp2);
280
281      OperatorExtractor oe1 = new OperatorExtractor();
282      oe1.Name = "Crossover";
283      oe1.GetVariableInfo("Operator").ActualName = "Crossover";
284      op.OperatorGraph.AddOperator(oe1);
285      sp2.AddSubOperator(oe1);
286
287      StochasticBranch hb = new StochasticBranch();
288      hb.GetVariableInfo("Probability").ActualName = "MutationRate";
289      op.OperatorGraph.AddOperator(hb);
290      sp2.AddSubOperator(hb);
291
292      OperatorExtractor oe2 = new OperatorExtractor();
293      oe2.Name = "Mutator";
294      oe2.GetVariableInfo("Operator").ActualName = "Mutator";
295      op.OperatorGraph.AddOperator(oe2);
296      hb.AddSubOperator(oe2);
297
298      OperatorExtractor oe3 = new OperatorExtractor();
299      oe3.Name = "Evaluator";
300      oe3.GetVariableInfo("Operator").ActualName = "Evaluator";
301      op.OperatorGraph.AddOperator(oe3);
302      sp2.AddSubOperator(oe3);
303
304      SubScopesRemover sr = new SubScopesRemover();
305      sr.GetVariableInfo("SubScopeIndex").Local = true;
306      op.OperatorGraph.AddOperator(sr);
307      sp2.AddSubOperator(sr);
308
309      Counter c = new Counter();
310      c.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
311      op.OperatorGraph.AddOperator(c);
312      sp2.AddSubOperator(c);
313
314      Sorter s = new Sorter();
315      s.GetVariableInfo("Descending").ActualName = "Maximization";
316      s.GetVariableInfo("Value").ActualName = "Quality";
317      op.OperatorGraph.AddOperator(s);
318      sp1.AddSubOperator(s);
319
320      return op;
321    }
322    private static CombinedOperator CreateReplacement() {
323      CombinedOperator op = new CombinedOperator();
324      SequentialProcessor sp1 = new SequentialProcessor();
325      op.OperatorGraph.AddOperator(sp1);
326      op.OperatorGraph.InitialOperator = sp1;
327
328      SequentialSubScopesProcessor ssp = new SequentialSubScopesProcessor();
329      op.OperatorGraph.AddOperator(ssp);
330      sp1.AddSubOperator(ssp);
331
332      SequentialProcessor sp2 = new SequentialProcessor();
333      op.OperatorGraph.AddOperator(sp2);
334      ssp.AddSubOperator(sp2);
335
336      LeftSelector ls = new LeftSelector();
337      ls.GetVariableInfo("Selected").ActualName = "Elites";
338      op.OperatorGraph.AddOperator(ls);
339      sp2.AddSubOperator(ls);
340
341      RightReducer rr = new RightReducer();
342      op.OperatorGraph.AddOperator(rr);
343      sp2.AddSubOperator(rr);
344
345      SequentialProcessor sp3 = new SequentialProcessor();
346      op.OperatorGraph.AddOperator(sp3);
347      ssp.AddSubOperator(sp3);
348
349      RightSelector rs = new RightSelector();
350      rs.GetVariableInfo("Selected").ActualName = "Elites";
351      op.OperatorGraph.AddOperator(rs);
352      sp3.AddSubOperator(rs);
353
354      LeftReducer lr = new LeftReducer();
355      op.OperatorGraph.AddOperator(lr);
356      sp3.AddSubOperator(lr);
357
358      MergingReducer mr = new MergingReducer();
359      op.OperatorGraph.AddOperator(mr);
360      sp1.AddSubOperator(mr);
361
362      Sorter s = new Sorter();
363      s.GetVariableInfo("Descending").ActualName = "Maximization";
364      s.GetVariableInfo("Value").ActualName = "Quality";
365      op.OperatorGraph.AddOperator(s);
366      sp1.AddSubOperator(s);
367
368      return op;
369    }
370    #endregion
371
372    #region Properties
373    private IEngine myEngine;
374    /// <summary>
375    /// Gets the engine of the current instance.
376    /// </summary>
377    public IEngine Engine {
378      get { return myEngine; }
379    }
380    private BoolData mySetSeedRandomly;
381    /// <summary>
382    /// Gets or sets the flag whether to set the seed randomly or not.
383    /// </summary>
384    public bool SetSeedRandomly {
385      get { return mySetSeedRandomly.Data; }
386      set { mySetSeedRandomly.Data = value; }
387    }
388    private IntData mySeed;
389    /// <summary>
390    /// Gets or sets the value of the seed of the current instance.
391    /// </summary>
392    public int Seed {
393      get { return mySeed.Data; }
394      set { mySeed.Data = value; }
395    }
396    private IntData myPopulationSize;
397    private IntData myParents;
398    /// <summary>
399    /// Gets or sets the population size of the current instance.
400    /// </summary>
401    /// <remarks>The number of parents is set to two times the population size.</remarks>
402    public int PopulationSize {
403      get { return myPopulationSize.Data; }
404      set {
405        myPopulationSize.Data = value;
406        myParents.Data = value * 2;
407      }
408    }
409    private IntData myMaximumGenerations;
410    /// <summary>
411    /// Gets or sets the number of maximum generations.
412    /// </summary>
413    public int MaximumGenerations {
414      get { return myMaximumGenerations.Data; }
415      set { myMaximumGenerations.Data = value; }
416    }
417    private DoubleData myMutationRate;
418    /// <summary>
419    /// Gets or sets the mutation rate of the current instance.
420    /// </summary>
421    public double MutationRate {
422      get { return myMutationRate.Data; }
423      set { myMutationRate.Data = value; }
424    }
425    private IntData myElites;
426    /// <summary>
427    /// Gets or sets the elites of the current instance.
428    /// </summary>
429    public int Elites {
430      get { return myElites.Data; }
431      set { myElites.Data = value; }
432    }
433    private CombinedOperator mySGA;
434    private IOperator myVariableInjection;
435    /// <summary>
436    /// Gets or sets the problem injector of the current instance.
437    /// </summary>
438    public IOperator ProblemInjector {
439      get { return myVariableInjection.SubOperators[0]; }
440      set {
441        value.Name = "ProblemInjector";
442        mySGA.OperatorGraph.RemoveOperator(ProblemInjector.Guid);
443        mySGA.OperatorGraph.AddOperator(value);
444        myVariableInjection.AddSubOperator(value, 0);
445      }
446    }
447    private IOperator myPopulationInitialization;
448    /// <summary>
449    /// Gets or sets the solution generator of the current instance.
450    /// </summary>
451    public IOperator SolutionGenerator {
452      get { return myPopulationInitialization.SubOperators[0]; }
453      set {
454        value.Name = "SolutionGenerator";
455        mySGA.OperatorGraph.RemoveOperator(SolutionGenerator.Guid);
456        mySGA.OperatorGraph.AddOperator(value);
457        myPopulationInitialization.AddSubOperator(value, 0);
458      }
459    }
460    /// <summary>
461    /// Gets or sets the evaluator of the current instance.
462    /// </summary>
463    public IOperator Evaluator {
464      get { return myPopulationInitialization.SubOperators[1]; }
465      set {
466        value.Name = "Evaluator";
467        mySGA.OperatorGraph.RemoveOperator(Evaluator.Guid);
468        mySGA.OperatorGraph.AddOperator(value);
469        myPopulationInitialization.AddSubOperator(value, 1);
470        mySGAMain.AddSubOperator(value, 3);
471      }
472    }
473    private IOperator mySGAMain;
474    /// <summary>
475    /// Gets or sets the selection operator of the current instance.
476    /// </summary>
477    public IOperator Selector {
478      get { return mySGAMain.SubOperators[0]; }
479      set {
480        value.Name = "Selector";
481        mySGA.OperatorGraph.RemoveOperator(Selector.Guid);
482        mySGA.OperatorGraph.AddOperator(value);
483        mySGAMain.AddSubOperator(value, 0);
484      }
485    }
486    /// <summary>
487    /// Gets or sets the crossover operator of the current instance.
488    /// </summary>
489    public IOperator Crossover {
490      get { return mySGAMain.SubOperators[1]; }
491      set {
492        value.Name = "Crossover";
493        mySGA.OperatorGraph.RemoveOperator(Crossover.Guid);
494        mySGA.OperatorGraph.AddOperator(value);
495        mySGAMain.AddSubOperator(value, 1);
496      }
497    }
498    /// <summary>
499    /// Gets or sets the mutation operator of the current instance.
500    /// </summary>
501    public IOperator Mutator {
502      get { return mySGAMain.SubOperators[2]; }
503      set {
504        value.Name = "Mutator";
505        mySGA.OperatorGraph.RemoveOperator(Mutator.Guid);
506        mySGA.OperatorGraph.AddOperator(value);
507        mySGAMain.AddSubOperator(value, 2);
508      }
509    }
510    #endregion
511
512    /// <summary>
513    /// Initializes a new instance of <see cref="SGA"/>.
514    /// </summary>
515    public SGA() {
516      myEngine = new SequentialEngine.SequentialEngine();
517      Create(myEngine);
518      SetReferences();
519    }
520
521    /// <summary>
522    /// Creates a new instance of the <see cref="SGAEditor"/> class.
523    /// </summary>
524    /// <returns>The created instance of the <see cref="SGAEditor"/>.</returns>
525    public override IView CreateView() {
526      return new SGAEditor(this);
527    }
528    /// <summary>
529    /// Creates a new instance of the <see cref="SGAEditor"/> class.
530    /// </summary>
531    /// <returns>The created instance of the <see cref="SGAEditor"/>.</returns>
532    public virtual IEditor CreateEditor() {
533      return new SGAEditor(this);
534    }
535
536    /// <summary>
537    /// Clones the current instance (deep clone).
538    /// </summary>
539    /// <remarks>Deep clone through <see cref="Auxiliary.Clone"/> method of helper class
540    /// <see cref="Auxiliary"/>.</remarks>
541    /// <param name="clonedObjects">Dictionary of all already cloned objects. (Needed to avoid cycles.)</param>
542    /// <returns>The cloned object as <see cref="SGA"/>.</returns>
543    public override object Clone(IDictionary<Guid, object> clonedObjects) {
544      SGA clone = new SGA();
545      clonedObjects.Add(Guid, clone);
546      clone.myEngine = (IEngine)Auxiliary.Clone(Engine, clonedObjects);
547      return clone;
548    }
549
550    #region SetReferences Method
551    private void SetReferences() {
552      // SGA
553      CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
554      mySGA = co1;
555      // SequentialProcessor in SGA
556      SequentialProcessor sp1 = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
557      // Variable Injection
558      CombinedOperator co2 = (CombinedOperator)sp1.SubOperators[0];
559      myVariableInjection = co2;
560      // SequentialProcessor in Variable Injection
561      SequentialProcessor sp2 = (SequentialProcessor)co2.OperatorGraph.InitialOperator;
562      // RandomInjector
563      RandomInjector ri = (RandomInjector)sp2.SubOperators[0];
564      mySetSeedRandomly = ri.GetVariable("SetSeedRandomly").GetValue<BoolData>();
565      mySeed = ri.GetVariable("Seed").GetValue<IntData>();
566      // VariableInjector
567      VariableInjector vi = (VariableInjector)sp2.SubOperators[2];
568      myPopulationSize = vi.GetVariable("PopulationSize").GetValue<IntData>();
569      myParents = vi.GetVariable("Parents").GetValue<IntData>();
570      myMaximumGenerations = vi.GetVariable("MaximumGenerations").GetValue<IntData>();
571      myMutationRate = vi.GetVariable("MutationRate").GetValue<DoubleData>();
572      myElites = vi.GetVariable("Elites").GetValue<IntData>();
573      // Population Initialization
574      CombinedOperator co3 = (CombinedOperator)sp1.SubOperators[1];
575      myPopulationInitialization = co3;
576      // SGA Main
577      CombinedOperator co4 = (CombinedOperator)sp1.SubOperators[2];
578      mySGAMain = co4;
579    }
580    #endregion
581
582    #region Persistence Methods
583    /// <summary>
584    /// Saves the current instance as <see cref="XmlNode"/> in the specified <paramref name="document"/>.
585    /// </summary>
586    /// <remarks>The engine of the current instance is saved as a child node with the tag name
587    /// <c>Engine</c>.</remarks>
588    /// <param name="name">The (tag)name of the <see cref="XmlNode"/>.</param>
589    /// <param name="document">The <see cref="XmlDocument"/> where the data is saved.</param>
590    /// <param name="persistedObjects">A dictionary of all already persisted objects. (Needed to avoid cycles.)</param>
591    /// <returns>The saved <see cref="XmlNode"/>.</returns>
592    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid,IStorable> persistedObjects) {
593      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
594      node.AppendChild(PersistenceManager.Persist("Engine", Engine, document, persistedObjects));
595      return node;
596    }
597    /// <summary>
598    /// Loads the persisted instance from the specified <paramref name="node"/>.
599    /// </summary>
600    /// <remarks>The elements of the current instance must be saved in a special way, see
601    /// <see cref="GetXmlNode"/>.</remarks>
602    /// <param name="node">The <see cref="XmlNode"/> where the instance is saved.</param>
603    /// <param name="restoredObjects">The dictionary of all already restored objects. (Needed to avoid cycles.)</param>
604    public override void Populate(XmlNode node, IDictionary<Guid,IStorable> restoredObjects) {
605      base.Populate(node, restoredObjects);
606      myEngine = (IEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
607      SetReferences();
608    }
609    #endregion
610  }
611}
Note: See TracBrowser for help on using the repository browser.