Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs @ 5560

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

#852: Code refactoring. Created new interfaces and moved operators to respective projects as suggested in A. Beham's review. Work in progress.

File size: 19.4 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 : EngineAlgorithm, IStorableContent {
42
43    #region Problem Properties
44    public override Type ProblemType {
45      get { return typeof(ISingleObjectiveProblem); }
46    }
47    public new ISingleObjectiveProblem Problem {
48      get { return (ISingleObjectiveProblem)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 InertiaUpdater {
56      get { return InertiaUpdaterParameter.Value; }
57      set { InertiaUpdaterParameter.Value = value; }
58    }
59    #endregion
60
61    #region Parameter Properties
62    public IValueParameter<IntValue> SeedParameter {
63      get { return (IValueParameter<IntValue>)Parameters["Seed"]; }
64    }
65    public IValueParameter<BoolValue> SetSeedRandomlyParameter {
66      get { return (IValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
67    }
68    public IValueParameter<IntValue> SwarmSizeParameter {
69      get { return (IValueParameter<IntValue>)Parameters["SwarmSize"]; }
70    }
71    public IValueParameter<IntValue> MaxIterationsParameter {
72      get { return (IValueParameter<IntValue>)Parameters["MaxIterations"]; }
73    }
74    public IValueParameter<DoubleValue> InertiaParameter {
75      get { return (IValueParameter<DoubleValue>)Parameters["Inertia"]; }
76    }
77    public IValueParameter<DoubleValue> PersonalBestAttractionParameter {
78      get { return (IValueParameter<DoubleValue>)Parameters["PersonalBestAttraction"]; }
79    }
80    public IValueParameter<DoubleValue> NeighborsBestAttractionParameter {
81      get { return (IValueParameter<DoubleValue>)Parameters["NeighborsBestAttraction"]; }
82    }
83    public IValueParameter<MultiAnalyzer> AnalyzerParameter {
84      get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
85    }
86    public ConstrainedValueParameter<IParticleCreator> ParticleCreatorParameter {
87      get { return (ConstrainedValueParameter<IParticleCreator>)Parameters["ParticleCreator"]; }
88    }
89    public ConstrainedValueParameter<IParticleUpdater> ParticleUpdaterParameter {
90      get { return (ConstrainedValueParameter<IParticleUpdater>)Parameters["ParticleUpdater"]; }
91    }
92    public OptionalConstrainedValueParameter<ITopologyInitializer> TopologyInitializerParameter {
93      get { return (OptionalConstrainedValueParameter<ITopologyInitializer>)Parameters["TopologyInitializer"]; }
94    }
95    public OptionalConstrainedValueParameter<ITopologyUpdater> TopologyUpdaterParameter {
96      get { return (OptionalConstrainedValueParameter<ITopologyUpdater>)Parameters["TopologyUpdater"]; }
97    }
98    public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> InertiaUpdaterParameter {
99      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["InertiaUpdater"]; }
100    }
101    #endregion
102
103    #region Properties
104
105    public string Filename { get; set; }
106
107    [Storable]
108    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
109
110    [Storable]
111    private SolutionsCreator solutionsCreator;
112
113    [Storable]
114    private ParticleSwarmOptimizationMainLoop mainLoop;
115
116    public ITopologyInitializer TopologyInitializer {
117      get { return TopologyInitializerParameter.Value; }
118      set { TopologyInitializerParameter.Value = value; }
119    }
120
121    public ITopologyUpdater TopologyUpdater {
122      get { return TopologyUpdaterParameter.Value; }
123      set { TopologyUpdaterParameter.Value = value; }
124    }
125
126    public IParticleCreator ParticleCreator {
127      get { return ParticleCreatorParameter.Value; }
128      set { ParticleCreatorParameter.Value = value; }
129    }
130
131    public IParticleUpdater ParticleUpdater {
132      get { return ParticleUpdaterParameter.Value; }
133      set { ParticleUpdaterParameter.Value = value; }
134    }
135    #endregion
136
137    [StorableConstructor]
138    private ParticleSwarmOptimization(bool deserializing) : base(deserializing) { }
139    private ParticleSwarmOptimization(ParticleSwarmOptimization original, Cloner cloner)
140      : base(original, cloner) {
141      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
142      solutionsCreator = cloner.Clone(original.solutionsCreator);
143      mainLoop = cloner.Clone(original.mainLoop);
144      Initialize();
145    }
146    public ParticleSwarmOptimization()
147      : base() {
148      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
149      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
150      Parameters.Add(new ValueParameter<IntValue>("SwarmSize", "Size of the particle swarm.", new IntValue(10)));
151      Parameters.Add(new ValueParameter<IntValue>("MaxIterations", "Maximal number of iterations.", new IntValue(1000)));
152      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
153      Parameters.Add(new ValueParameter<DoubleValue>("Inertia", "Inertia weight on a particle's movement (omega).", new DoubleValue(-0.2)));
154      Parameters.Add(new ValueParameter<DoubleValue>("PersonalBestAttraction", "Weight for particle's pull towards its personal best soution (phi_p).", new DoubleValue(-0.01)));
155      Parameters.Add(new ValueParameter<DoubleValue>("NeighborsBestAttraction", "Weight for pull towards the neighborhood best solution or global best solution in case of a totally connected topology (phi_g).", new DoubleValue(3.7)));
156      Parameters.Add(new ConstrainedValueParameter<IParticleCreator>("ParticleCreator", "Operator creates a new particle."));
157      Parameters.Add(new ConstrainedValueParameter<IParticleUpdater>("ParticleUpdater", "Operator that updates a particle."));
158      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyInitializer>("TopologyInitializer", "Creates neighborhood description vectors."));
159      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyUpdater>("TopologyUpdater", "Updates the neighborhood description vectors."));
160      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("InertiaUpdater", "Updates the omega parameter."));
161
162      RandomCreator randomCreator = new RandomCreator();
163      VariableCreator variableCreator = new VariableCreator();
164      solutionsCreator = new SolutionsCreator();
165      Placeholder topologyInitializerPlaceholder = new Placeholder();
166      ResultsCollector resultsCollector = new ResultsCollector();
167      Placeholder analyzerPlaceholder = new Placeholder();
168      RealVectorSwarmUpdater swarmUpdater = new RealVectorSwarmUpdater();
169      mainLoop = new ParticleSwarmOptimizationMainLoop();
170
171      OperatorGraph.InitialOperator = randomCreator;
172
173      randomCreator.SetSeedRandomlyParameter.Value = null;
174      randomCreator.SeedParameter.Value = null;
175      randomCreator.Successor = variableCreator;
176
177      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("CurrentIteration", new IntValue(0)));
178      variableCreator.Successor = solutionsCreator;
179
180      solutionsCreator.NumberOfSolutionsParameter.ActualName = "SwarmSize";
181      ParameterizeSolutionsCreator();
182      solutionsCreator.Successor = topologyInitializerPlaceholder;
183
184      topologyInitializerPlaceholder.Name = "(TopologyInitializer)";
185      topologyInitializerPlaceholder.OperatorParameter.ActualName = "TopologyInitializer";
186      topologyInitializerPlaceholder.Successor = swarmUpdater;
187
188      swarmUpdater.Successor = resultsCollector;
189
190      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations", null, "CurrentIteration"));
191      //resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Current Inertia", null, "Inertia"));
192      //resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Solutions", null, "EvaluatedSolutions"));
193      resultsCollector.ResultsParameter.ActualName = "Results";
194      resultsCollector.Successor = mainLoop;
195
196      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
197      mainLoop.InertiaParameter.ActualName = InertiaParameter.Name;
198      mainLoop.MaxIterationsParameter.ActualName = MaxIterationsParameter.Name;
199      mainLoop.NeighborsBestAttractionParameter.ActualName = NeighborsBestAttractionParameter.Name;
200      mainLoop.InertiaUpdaterParameter.ActualName = InertiaUpdaterParameter.Name;
201      mainLoop.ParticleUpdaterParameter.ActualName = ParticleUpdaterParameter.Name;
202      mainLoop.PersonalBestAttractionParameter.ActualName = PersonalBestAttractionParameter.Name;
203      mainLoop.RandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
204      mainLoop.SwarmSizeParameter.ActualName = SwarmSizeParameter.Name;
205      mainLoop.TopologyUpdaterParameter.ActualName = TopologyUpdaterParameter.Name;
206      mainLoop.RandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
207      mainLoop.ResultsParameter.ActualName = "Results";
208      mainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
209     // mainLoop.EvaluatedMovesParameter.ActualName = "EvaluatedMoves";
210
211      InitializeAnalyzers();
212      ////InitVelocityBoundsUpdater();
213      InitializeParticleCreator();
214      ParameterizeSolutionsCreator();
215      UpdateAnalyzers();
216      UpdateInertiaUpdater();
217      InitInertiaUpdater();
218      UpdateTopologyInitializer();
219      Initialize();
220      ParameterizeMainLoop();
221    }
222
223    public override IDeepCloneable Clone(Cloner cloner) {
224      return new ParticleSwarmOptimization(this, cloner);
225    }
226
227    [StorableHook(HookType.AfterDeserialization)]
228    private void AfterDeserialization() {
229      Initialize();
230    }
231
232    public override void Prepare() {
233      if (Problem != null && ParticleCreator != null && ParticleUpdater != null) {
234        base.Prepare();
235        if (InertiaUpdater != null && InertiaUpdater.StartValueParameter.Value != null) {
236          this.InertiaParameter.ActualValue = new DoubleValue(InertiaUpdaterParameter.Value.StartValueParameter.Value.Value);
237        }
238        //if (VelocityBoundsUpdater != null && VelocityBoundsUpdater.StartValueParameter.Value != null && VelocityBoundsParameter.Value != null) {
239        //  DoubleMatrix matrix = VelocityBoundsParameter.Value;
240        //  for (int i = 0; i < matrix.Rows; i++) {
241        //    matrix[i, 0] = -VelocityBoundsUpdater.StartValueParameter.Value.Value;
242        //    matrix[i, 1] = VelocityBoundsUpdater.StartValueParameter.Value.Value;
243        //  }
244        //}
245      }
246    }
247
248    #region Events
249    protected override void OnProblemChanged() {
250      UpdateAnalyzers();
251      ParameterizeAnalyzers();
252      UpdateTopologyParameters();
253      InitializeParticleCreator();
254      ParameterizeSolutionsCreator();
255      base.OnProblemChanged();
256    }
257
258    void TopologyInitializerParameter_ValueChanged(object sender, EventArgs e) {
259      this.UpdateTopologyParameters();
260    }
261
262    //void VelocityBoundsUpdaterParameter_ValueChanged(object sender, EventArgs e) {
263    //  if (VelocityBoundsParameter.Value != null) {
264    //    foreach (IDiscreteDoubleMatrixModifier matrixOp in VelocityBoundsUpdaterParameter.Value.ScalingOperatorParameter.ValidValues) {
265    //      matrixOp.ValueParameter.ActualName = VelocityBoundsUpdater.ScaleParameter.Name;
266    //      matrixOp.StartValueParameter.Value = new DoubleValue(VelocityBoundsUpdater.ScaleParameter.ActualValue.Value);
267    //    }
268    //  }
269    //}
270    #endregion
271
272    #region Helpers
273    private void Initialize() {
274      TopologyInitializerParameter.ValueChanged += new EventHandler(TopologyInitializerParameter_ValueChanged);
275    }
276
277    private void InitializeParticleCreator() {
278      if (Problem != null) {
279        IParticleCreator oldParticleCreator = ParticleCreator;
280        ParticleCreatorParameter.ValidValues.Clear();
281        foreach (IParticleCreator Creator in Problem.Operators.OfType<IParticleCreator>().OrderBy(x => x.Name)) {
282          ParticleCreatorParameter.ValidValues.Add(Creator);
283        }
284        if (oldParticleCreator != null) {
285          IParticleCreator creator = ParticleCreatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleCreator.GetType());
286          if (creator != null) ParticleCreator = creator;
287        } 
288      }
289    }
290
291    private void InitializeAnalyzers() {
292      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
293      ParameterizeAnalyzers();
294    }
295
296    private void ParameterizeAnalyzers() {
297      if (Problem != null) {
298        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
299        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
300        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
301      }
302    }
303
304    private void UpdateAnalyzers() {
305      Analyzer.Operators.Clear();
306      if (Problem != null) {
307        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>())
308          Analyzer.Operators.Add(analyzer);
309      }
310      Analyzer.Operators.Add(qualityAnalyzer);
311    }
312
313    //private void InitVelocityBoundsUpdater() {
314    //  foreach (IDiscreteDoubleMatrixModifier matrixOp in ApplicationManager.Manager.GetInstances<IDiscreteDoubleMatrixModifier>()) {
315    //    VelocityBoundsUpdaterParameter.ValidValues.Add(matrixOp);
316    //    matrixOp.ValueParameter.ActualName = VelocityBoundsParameter.Name;
317    //    matrixOp.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
318    //    matrixOp.StartIndexParameter.Value = new IntValue(0);
319    //    matrixOp.IndexParameter.ActualName = "CurrentIteration";
320    //    matrixOp.EndValueParameter.Value = new DoubleValue(0);
321    //  }
322    //  VelocityBoundsUpdaterParameter.ValueChanged += new EventHandler(VelocityBoundsUpdaterParameter_ValueChanged);
323    //}
324
325    private void InitInertiaUpdater() {
326      foreach (IDiscreteDoubleValueModifier updater in InertiaUpdaterParameter.ValidValues) {
327        updater.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
328        updater.StartIndexParameter.Value = new IntValue(0);
329        updater.IndexParameter.ActualName = "CurrentIteration";
330        updater.ValueParameter.ActualName = InertiaParameter.Name;
331        updater.StartValueParameter.Value = new DoubleValue(1);
332        updater.EndValueParameter.Value = new DoubleValue(0);
333      }
334    }
335
336    private void UpdateInertiaUpdater() {
337      IDiscreteDoubleValueModifier oldInertiaUpdater = InertiaUpdater;
338      InertiaUpdaterParameter.ValidValues.Clear();
339      foreach (IDiscreteDoubleValueModifier updater in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
340        InertiaUpdaterParameter.ValidValues.Add(updater);
341      }
342      if (oldInertiaUpdater != null) {
343        IDiscreteDoubleValueModifier updater = InertiaUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldInertiaUpdater.GetType());
344        if (updater != null) InertiaUpdaterParameter.Value = updater;
345      }
346    }
347
348    private void UpdateTopologyInitializer() {
349      ITopologyInitializer oldTopologyInitializer = TopologyInitializer;
350      TopologyInitializerParameter.ValidValues.Clear();
351      foreach (ITopologyInitializer topologyInitializer in ApplicationManager.Manager.GetInstances<ITopologyInitializer>().OrderBy(x => x.Name)) {
352        TopologyInitializerParameter.ValidValues.Add(topologyInitializer);
353      }
354      if (oldTopologyInitializer != null && TopologyInitializerParameter.ValidValues.Any(x => x.GetType() == oldTopologyInitializer.GetType()))
355        TopologyInitializer = TopologyInitializerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldTopologyInitializer.GetType());
356      UpdateTopologyParameters();
357    }
358
359    private void UpdateTopologyParameters() {
360      ITopologyUpdater oldTopologyUpdater = TopologyUpdater;
361      IParticleUpdater oldParticleUpdater = ParticleUpdater;
362      ClearTopologyParameters();
363      if (Problem != null) {
364        if (TopologyInitializer != null) {
365          foreach (ITopologyUpdater topologyUpdater in ApplicationManager.Manager.GetInstances<ITopologyUpdater>())
366            TopologyUpdaterParameter.ValidValues.Add(topologyUpdater);
367          foreach (IParticleUpdater particleUpdater in Problem.Operators.OfType<ILocalParticleUpdater>().OrderBy(x => x.Name))
368            ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
369        } else {
370          foreach (IParticleUpdater particleUpdater in Problem.Operators.OfType<IGlobalParticleUpdater>().OrderBy(x => x.Name))
371            ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
372        }
373        if (oldTopologyUpdater != null) {
374          ITopologyUpdater newTopologyUpdater = TopologyUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
375          if (newTopologyUpdater != null) TopologyUpdater = newTopologyUpdater;
376        }
377        if (oldParticleUpdater != null) {
378          IParticleUpdater newParticleUpdater = ParticleUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
379          if (newParticleUpdater != null) ParticleUpdater = newParticleUpdater;
380        }
381      }
382    }
383
384    private void ClearTopologyParameters() {
385      TopologyUpdaterParameter.ValidValues.Clear();
386      ParticleUpdaterParameter.ValidValues.Clear();
387    }
388
389    private void ParameterizeSolutionsCreator() {
390      if (Problem != null) {
391        solutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
392        solutionsCreator.SolutionCreatorParameter.ActualName = ParticleCreatorParameter.Name;
393      }
394    }
395
396    private void ParameterizeMainLoop() {
397      mainLoop.MaxIterationsParameter.ActualName = MaxIterationsParameter.Name;
398    }
399    #endregion
400
401  }
402}
Note: See TracBrowser for help on using the repository browser.