Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.SA/3.2/SA.cs @ 2497

Last change on this file since 2497 was 1530, checked in by gkronber, 16 years ago

Moved source files of plugins Hive ... Visualization.Test into version-specific sub-folders. #576

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