Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis Refactoring/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs @ 5644

Last change on this file since 5644 was 5644, checked in by gkronber, 13 years ago

#1418 introduced HeuristicOptimizationEngineAlgorithm

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