Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PSO/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs @ 5606

Last change on this file since 5606 was 5418, checked in by mkofler, 14 years ago

#852: Adapted PSO to perform move evaluation in parallel (using the parallel engine). See also #1333.

File size: 21.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
24using HeuristicLab.Analysis;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.RealVectorEncoding;
29using HeuristicLab.Operators;
30using HeuristicLab.Optimization;
31using HeuristicLab.Optimization.Operators;
32using HeuristicLab.Parameters;
33using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
34using HeuristicLab.PluginInfrastructure;
35using HeuristicLab.Random;
36using System.Collections.Generic;
37
38namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
39
40  [Item("Particle Swarm Optimization", "A particle swarm optimization algorithm based on the description in Pedersen, M.E.H. (2010). PhD thesis. University of Southampton.")]
41  [Creatable("Algorithms")]
42  [StorableClass]
43  public class ParticleSwarmOptimization : EngineAlgorithm, IStorableContent {
44
45    #region Problem Properties
46    public override Type ProblemType {
47      get { return typeof(ISingleObjectiveProblem); }
48    }
49    public new ISingleObjectiveProblem Problem {
50      get { return (ISingleObjectiveProblem)base.Problem; }
51      set { base.Problem = value; }
52    }
53    public MultiAnalyzer Analyzer {
54      get { return AnalyzerParameter.Value; }
55      set { AnalyzerParameter.Value = value; }
56    }
57    public IDiscreteDoubleValueModifier OmegaUpdater {
58      get { return OmegaUpdaterParameter.Value; }
59      set { OmegaUpdaterParameter.Value = value; }
60    }
61    public IDiscreteDoubleMatrixModifier VelocityBoundsUpdater {
62      get { return VelocityBoundsUpdaterParameter.Value; }
63      set { VelocityBoundsUpdaterParameter.Value = value; }
64    }
65    #endregion
66
67    #region Parameter Properties
68    public IValueParameter<IntValue> SeedParameter {
69      get { return (IValueParameter<IntValue>)Parameters["Seed"]; }
70    }
71    public IValueParameter<BoolValue> SetSeedRandomlyParameter {
72      get { return (IValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
73    }
74    public IValueParameter<IntValue> SwarmSizeParameter {
75      get { return (IValueParameter<IntValue>)Parameters["SwarmSize"]; }
76    }
77    public IValueParameter<IntValue> MaxIterationsParameter {
78      get { return (IValueParameter<IntValue>)Parameters["MaxIterations"]; }
79    }
80    public IValueParameter<DoubleValue> OmegaParameter {
81      get { return (IValueParameter<DoubleValue>)Parameters["Omega"]; }
82    }
83    public IValueParameter<DoubleValue> Phi_PParameter {
84      get { return (IValueParameter<DoubleValue>)Parameters["Phi_P"]; }
85    }
86    public IValueParameter<DoubleValue> Phi_GParameter {
87      get { return (IValueParameter<DoubleValue>)Parameters["Phi_G"]; }
88    }
89    public IValueParameter<MultiAnalyzer> AnalyzerParameter {
90      get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
91    }
92    public IValueLookupParameter<DoubleMatrix> VelocityBoundsParameter {
93      get { return (IValueLookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
94    }
95    public ConstrainedValueParameter<IParticleUpdater> ParticleUpdaterParameter {
96      get { return (ConstrainedValueParameter<IParticleUpdater>)Parameters["ParticleUpdater"]; }
97    }
98    public OptionalConstrainedValueParameter<ITopologyInitializer> TopologyInitializerParameter {
99      get { return (OptionalConstrainedValueParameter<ITopologyInitializer>)Parameters["TopologyInitializer"]; }
100    }
101    public OptionalConstrainedValueParameter<ITopologyUpdater> TopologyUpdaterParameter {
102      get { return (OptionalConstrainedValueParameter<ITopologyUpdater>)Parameters["TopologyUpdater"]; }
103    }
104    public OptionalConstrainedValueParameter<IDiscreteDoubleMatrixModifier> VelocityBoundsUpdaterParameter {
105      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleMatrixModifier>)Parameters["VelocityBoundsUpdater"]; }
106    }
107    public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> OmegaUpdaterParameter {
108      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["OmegaUpdater"]; }
109    }
110    #endregion
111
112    #region Properties
113
114    public string Filename { get; set; }
115
116    [Storable]
117    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
118
119    public ITopologyInitializer TopologyInitializer {
120      get { return TopologyInitializerParameter.Value; }
121      set { TopologyInitializerParameter.Value = value; }
122    }
123
124    public ITopologyUpdater TopologyUpdater {
125      get { return TopologyUpdaterParameter.Value; }
126      set { TopologyUpdaterParameter.Value = value; }
127    }
128
129    public IParticleUpdater ParticleUpdater {
130      get { return ParticleUpdaterParameter.Value; }
131      set { ParticleUpdaterParameter.Value = value; }
132    }
133
134    #endregion
135
136    [StorableConstructor]
137    protected ParticleSwarmOptimization(bool deserializing)
138      : base(deserializing) {
139    }
140    protected ParticleSwarmOptimization(ParticleSwarmOptimization original, Cloner cloner)
141      : base(original, cloner) {
142      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
143      Initialize();
144    }
145
146    [StorableHook(HookType.AfterDeserialization)]
147    private void AfterDeserialization() {
148      Initialize();
149    }
150
151    public ParticleSwarmOptimization()
152      : base() {
153      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
154      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
155      Parameters.Add(new ValueParameter<IntValue>("SwarmSize", "Size of the particle swarm.", new IntValue(10)));
156      Parameters.Add(new ValueParameter<IntValue>("MaxIterations", "Maximal number of iterations.", new IntValue(1000)));
157      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
158      Parameters.Add(new ValueParameter<DoubleValue>("Omega", "Weight for particle's velocity vector.", new DoubleValue(-0.2)));
159      Parameters.Add(new ValueParameter<DoubleValue>("Phi_P", "Weight for particle's personal best position.", new DoubleValue(-0.01)));
160      Parameters.Add(new ValueParameter<DoubleValue>("Phi_G", "Weight for global best position.", new DoubleValue(3.7)));
161      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("VelocityBounds", "Maximum Velocity in every dimension", new DoubleMatrix(new double[,] { { -1, 1 } })));
162      Parameters.Add(new ConstrainedValueParameter<IParticleUpdater>("ParticleUpdater", "Operator that calculates new position and velocity of a particle"));
163      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyInitializer>("TopologyInitializer", "Creates neighborhood description vectors"));
164      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyUpdater>("TopologyUpdater", "Updates the neighborhood description vectors"));
165      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("OmegaUpdater", "Updates the omega parameter"));
166      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleMatrixModifier>("VelocityBoundsUpdater", "Adjusts the velocity bounds."));
167      ParticleUpdaterParameter.ActualValue = ParticleUpdaterParameter.ValidValues.SingleOrDefault(v => v.GetType() == typeof(TotallyConnectedParticleUpdater));
168
169      RandomCreator randomCreator = new RandomCreator();
170      VariableCreator variableCreator = new VariableCreator();
171      SolutionsCreator solutionsCreator = new SolutionsCreator();
172      CombinedOperator particleCreator = new CombinedOperator();
173      Placeholder evaluatorPlaceholder = new Placeholder();
174      Assigner bestPersonalQualityAssigner = new Assigner();
175      BestPointInitializer bestPositionInitializer = new BestPointInitializer();
176      Placeholder topologyInitializerPlaceholder = new Placeholder();
177      NeighborUpdater neighborUpdater = new NeighborUpdater();
178      Placeholder analyzerPlaceholder = new Placeholder();
179      UniformSubScopesProcessor uniformSubScopeProcessor = new UniformSubScopesProcessor();
180      Placeholder particleUpdaterPlaceholder = new Placeholder();
181      Placeholder topologyUpdaterPlaceholder = new Placeholder();
182      UniformSubScopesProcessor uniformSubscopesProcessor2 = new UniformSubScopesProcessor();
183      UniformSubScopesProcessor evaluationProcessor = new UniformSubScopesProcessor();
184      NeighborUpdater neighborUpdater2 = new NeighborUpdater();
185      Placeholder evaluatorPlaceholder2 = new Placeholder();
186      SwarmUpdater swarmUpdater = new SwarmUpdater();
187      Placeholder analyzerPlaceholder2 = new Placeholder();
188      IntCounter currentIterationCounter = new IntCounter();
189      Comparator currentIterationComparator = new Comparator();
190      ConditionalBranch conditionalBranch = new ConditionalBranch();
191      Placeholder velocityBoundsUpdaterPlaceholder = new Placeholder();
192      Placeholder omegaUpdaterPlaceholder = new Placeholder();
193
194      OperatorGraph.InitialOperator = randomCreator;
195
196      randomCreator.SetSeedRandomlyParameter.Value = null;
197      randomCreator.SeedParameter.Value = null;
198      randomCreator.Successor = variableCreator;
199
200      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("CurrentIteration", new IntValue(0)));
201      variableCreator.Successor = solutionsCreator;
202
203      solutionsCreator.NumberOfSolutionsParameter.ActualName = "SwarmSize";
204      solutionsCreator.EvaluatorParameter.Value = evaluatorPlaceholder;
205      solutionsCreator.SolutionCreatorParameter.Value = particleCreator;
206      solutionsCreator.Successor = bestPositionInitializer;
207
208      InitializeParticleCreator(particleCreator);
209
210      evaluatorPlaceholder.Name = "(Evaluator)";
211      evaluatorPlaceholder.OperatorParameter.ActualName = "Evaluator";
212      evaluatorPlaceholder.Successor = bestPersonalQualityAssigner;
213
214      bestPersonalQualityAssigner.LeftSideParameter.ActualName = "PersonalBestQuality";
215      bestPersonalQualityAssigner.RightSideParameter.ActualName = "Quality";
216
217      bestPositionInitializer.Successor = topologyInitializerPlaceholder;
218
219      topologyInitializerPlaceholder.Name = "(TopologyInitializer)";
220      topologyInitializerPlaceholder.OperatorParameter.ActualName = "TopologyInitializer";
221      topologyInitializerPlaceholder.Successor = neighborUpdater;
222
223      neighborUpdater.Successor = analyzerPlaceholder;
224
225      analyzerPlaceholder.Name = "(Analyzer)";
226      analyzerPlaceholder.OperatorParameter.ActualName = "Analyzer";
227      analyzerPlaceholder.Successor = uniformSubScopeProcessor;
228
229      uniformSubScopeProcessor.Operator = particleUpdaterPlaceholder;
230      uniformSubScopeProcessor.Successor = evaluationProcessor;
231
232      particleUpdaterPlaceholder.Name = "(ParticleUpdater)";
233      particleUpdaterPlaceholder.OperatorParameter.ActualName = "ParticleUpdater";
234
235      evaluationProcessor.Parallel = new BoolValue(true);
236      evaluationProcessor.Operator = evaluatorPlaceholder2;
237      evaluationProcessor.Successor = topologyUpdaterPlaceholder;
238
239      evaluatorPlaceholder2.Name = "(Evaluator)";
240      evaluatorPlaceholder2.OperatorParameter.ActualName = "Evaluator";
241
242      topologyUpdaterPlaceholder.Name = "(TopologyUpdater)";
243      topologyUpdaterPlaceholder.OperatorParameter.ActualName = "TopologyUpdater";
244      topologyUpdaterPlaceholder.Successor = neighborUpdater2;
245
246      neighborUpdater2.Successor = uniformSubscopesProcessor2;
247
248      uniformSubscopesProcessor2.Operator = swarmUpdater;
249      uniformSubscopesProcessor2.Successor = analyzerPlaceholder2;
250
251      analyzerPlaceholder2.Name = "(Analyzer)";
252      analyzerPlaceholder2.OperatorParameter.ActualName = "Analyzer";
253      analyzerPlaceholder2.Successor = currentIterationCounter;
254
255      currentIterationCounter.Name = "CurrentIteration++";
256      currentIterationCounter.ValueParameter.ActualName = "CurrentIteration";
257      currentIterationCounter.Successor = omegaUpdaterPlaceholder;
258
259      omegaUpdaterPlaceholder.Name = "(Omega Updater)";
260      omegaUpdaterPlaceholder.OperatorParameter.ActualName = "OmegaUpdater";
261      omegaUpdaterPlaceholder.Successor = velocityBoundsUpdaterPlaceholder;
262
263      velocityBoundsUpdaterPlaceholder.Name = "(Velocity Bounds Updater)";
264      velocityBoundsUpdaterPlaceholder.OperatorParameter.ActualName = "VelocityBoundsUpdater";
265      velocityBoundsUpdaterPlaceholder.Successor = currentIterationComparator;
266
267      currentIterationComparator.LeftSideParameter.ActualName = "CurrentIteration";
268      currentIterationComparator.Comparison = new Comparison(ComparisonType.Less);
269      currentIterationComparator.RightSideParameter.ActualName = "MaxIterations";
270      currentIterationComparator.ResultParameter.ActualName = "ContinueIteration";
271      currentIterationComparator.Successor = conditionalBranch;
272
273      conditionalBranch.Name = "ContinueIteration?";
274      conditionalBranch.ConditionParameter.ActualName = "ContinueIteration";
275      conditionalBranch.TrueBranch = uniformSubScopeProcessor;
276
277      InitializeAnalyzers();
278      InitVelocityBoundsUpdater();
279      UpdateAnalyzers();
280      UpdateOmegaUpdater();
281      InitOmegaUpdater();
282      UpdateTopologyInitializer();
283      Initialize();
284    }
285
286    public override IDeepCloneable Clone(Cloner cloner) {
287      return new ParticleSwarmOptimization(this, cloner);
288    }
289
290    public override void Prepare() {
291      if (Problem != null) {
292        base.Prepare();
293        if (OmegaUpdater != null && OmegaUpdater.StartValueParameter.Value != null) {
294          this.OmegaParameter.ActualValue = new DoubleValue(OmegaUpdaterParameter.Value.StartValueParameter.Value.Value);
295        }
296        if (VelocityBoundsUpdater != null && VelocityBoundsUpdater.StartValueParameter.Value != null && VelocityBoundsParameter.Value != null) {
297          DoubleMatrix matrix = VelocityBoundsParameter.Value;
298          for (int i = 0; i < matrix.Rows; i++) {
299            matrix[i, 0] = -VelocityBoundsUpdater.StartValueParameter.Value.Value;
300            matrix[i, 1] = VelocityBoundsUpdater.StartValueParameter.Value.Value;
301          }
302        }
303      }
304    }
305
306    #region Events
307    protected override void OnProblemChanged() {
308      UpdateAnalyzers();
309      ParameterizeAnalyzers();
310      base.OnProblemChanged();
311    }
312
313    void TopologyInitializerParameter_ValueChanged(object sender, EventArgs e) {
314      this.UpdateTopologyParameters();
315    }
316
317    void VelocityBoundsUpdaterParameter_ValueChanged(object sender, EventArgs e) {
318      if (VelocityBoundsParameter.Value != null) {
319        foreach (IDiscreteDoubleMatrixModifier matrixOp in VelocityBoundsUpdaterParameter.Value.ScalingOperatorParameter.ValidValues) {
320          matrixOp.ValueParameter.ActualName = VelocityBoundsUpdater.ScaleParameter.Name;
321          matrixOp.StartValueParameter.Value = new DoubleValue(VelocityBoundsUpdater.ScaleParameter.ActualValue.Value);
322        }
323      }
324    }
325    #endregion
326
327    #region Helpers
328    private void Initialize() {
329      TopologyInitializerParameter.ValueChanged += new EventHandler(TopologyInitializerParameter_ValueChanged);
330    }
331
332    private static void InitializeParticleCreator(CombinedOperator particleCreator) {
333      Placeholder positionCreator = new Placeholder();
334      Assigner personalBestPositionAssigner = new Assigner();
335      UniformRandomRealVectorCreator velocityCreator = new UniformRandomRealVectorCreator();
336
337      particleCreator.Name = "Particle Creator";
338      particleCreator.OperatorGraph.InitialOperator = positionCreator;
339
340      positionCreator.Name = "(SolutionCreator)";
341      positionCreator.OperatorParameter.ActualName = "SolutionCreator";
342      positionCreator.Successor = personalBestPositionAssigner;
343
344      personalBestPositionAssigner.LeftSideParameter.ActualName = "PersonalBestPoint";
345      personalBestPositionAssigner.RightSideParameter.ActualName = "Point";
346      personalBestPositionAssigner.Successor = velocityCreator;
347
348      velocityCreator.LengthParameter.ActualName = "ProblemSize";
349      velocityCreator.BoundsParameter.ActualName = "VelocityBounds";
350      velocityCreator.RealVectorParameter.ActualName = "Velocity";
351    }
352
353    private void InitializeAnalyzers() {
354      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
355      ParameterizeAnalyzers();
356    }
357
358    private void ParameterizeAnalyzers() {
359      if (Problem != null) {
360        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
361        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
362        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
363      }
364    }
365
366    private void UpdateAnalyzers() {
367      Analyzer.Operators.Clear();
368      if (Problem != null) {
369        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>())
370          Analyzer.Operators.Add(analyzer);
371      }
372      Analyzer.Operators.Add(qualityAnalyzer);
373    }
374
375    private void InitVelocityBoundsUpdater() {
376      foreach (IDiscreteDoubleMatrixModifier matrixOp in ApplicationManager.Manager.GetInstances<IDiscreteDoubleMatrixModifier>()) {
377        VelocityBoundsUpdaterParameter.ValidValues.Add(matrixOp);
378        matrixOp.ValueParameter.ActualName = VelocityBoundsParameter.Name;
379        matrixOp.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
380        matrixOp.StartIndexParameter.Value = new IntValue(0);
381        matrixOp.IndexParameter.ActualName = "CurrentIteration";
382        matrixOp.EndValueParameter.Value = new DoubleValue(0);
383      }
384      VelocityBoundsUpdaterParameter.ValueChanged += new EventHandler(VelocityBoundsUpdaterParameter_ValueChanged);
385    }
386
387    private void InitOmegaUpdater() {
388      foreach (IDiscreteDoubleValueModifier updater in OmegaUpdaterParameter.ValidValues) {
389        updater.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
390        updater.StartIndexParameter.Value = new IntValue(0);
391        updater.IndexParameter.ActualName = "CurrentIteration";
392        updater.ValueParameter.ActualName = OmegaParameter.Name;
393        updater.StartValueParameter.Value = new DoubleValue(1);
394        updater.EndValueParameter.Value = new DoubleValue(0);
395      }
396    }
397
398    private void UpdateOmegaUpdater() {
399      IDiscreteDoubleValueModifier oldOmegaUpdater = OmegaUpdater;
400      OmegaUpdaterParameter.ValidValues.Clear();
401      foreach (IDiscreteDoubleValueModifier updater in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
402        OmegaUpdaterParameter.ValidValues.Add(updater);
403      }
404      if (oldOmegaUpdater != null) {
405        IDiscreteDoubleValueModifier updater = OmegaUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldOmegaUpdater.GetType());
406        if (updater != null) OmegaUpdaterParameter.Value = updater;
407      }
408    }
409
410    private void UpdateTopologyInitializer() {
411      ITopologyInitializer oldTopologyInitializer = TopologyInitializer;
412      TopologyInitializerParameter.ValidValues.Clear();
413      foreach (ITopologyInitializer topologyInitializer in ApplicationManager.Manager.GetInstances<ITopologyInitializer>().OrderBy(x => x.Name)) {
414        TopologyInitializerParameter.ValidValues.Add(topologyInitializer);
415      }
416      if (oldTopologyInitializer != null && TopologyInitializerParameter.ValidValues.Any(x => x.GetType() == oldTopologyInitializer.GetType()))
417        TopologyInitializer = TopologyInitializerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldTopologyInitializer.GetType());
418      UpdateTopologyParameters();
419    }
420
421    private void UpdateTopologyParameters() {
422      ITopologyUpdater oldTopologyUpdater = TopologyUpdater;
423      IParticleUpdater oldParticleUpdater = ParticleUpdater;
424      ClearTopologyParameters();
425      if (TopologyInitializer != null) {
426        foreach (ITopologyUpdater topologyUpdater in ApplicationManager.Manager.GetInstances<ITopologyUpdater>())
427          TopologyUpdaterParameter.ValidValues.Add(topologyUpdater);
428        foreach (IParticleUpdater particleUpdater in ApplicationManager.Manager.GetInstances<ILocalParticleUpdater>())
429          ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
430      } else {
431        foreach (IParticleUpdater particleUpdater in ApplicationManager.Manager.GetInstances<IGlobalParticleUpdater>())
432          ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
433      }
434      if (oldTopologyUpdater != null) {
435        ITopologyUpdater newTopologyUpdater = TopologyUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
436        if (newTopologyUpdater != null) TopologyUpdater = newTopologyUpdater;
437      }
438      if (oldParticleUpdater != null) {
439        IParticleUpdater newParticleUpdater = ParticleUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
440        if (newParticleUpdater != null) ParticleUpdater = newParticleUpdater;
441      }
442    }
443
444    private void ClearTopologyParameters() {
445      TopologyUpdaterParameter.ValidValues.Clear();
446      ParticleUpdaterParameter.ValidValues.Clear();
447    }
448    #endregion
449
450  }
451}
Note: See TracBrowser for help on using the repository browser.