Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 5645 was 5645, checked in by epitzer, 12 years ago

Set CurrentInertia inside operator graph and make sure all operators use it
Set default end value to epsilon instead of zero (#852)

File size: 18.2 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.Operators;
29using HeuristicLab.Optimization;
30using HeuristicLab.Optimization.Operators;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33using HeuristicLab.PluginInfrastructure;
34using HeuristicLab.Random;
35
36namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
37  [Item("Particle Swarm Optimization", "A particle swarm optimization algorithm based on the description in Pedersen, M.E.H. (2010). PhD thesis. University of Southampton.")]
38  [Creatable("Algorithms")]
39  [StorableClass]
40  public sealed class ParticleSwarmOptimization : EngineAlgorithm, IStorableContent {
41
42    #region Problem Properties
43    public override Type ProblemType {
44      get { return typeof(ISingleObjectiveProblem); }
45    }
46    public new ISingleObjectiveProblem Problem {
47      get { return (ISingleObjectiveProblem)base.Problem; }
48      set { base.Problem = value; }
49    }
50    public MultiAnalyzer Analyzer {
51      get { return AnalyzerParameter.Value; }
52      set { AnalyzerParameter.Value = value; }
53    }
54    public IDiscreteDoubleValueModifier InertiaUpdater {
55      get { return InertiaUpdaterParameter.Value; }
56      set { InertiaUpdaterParameter.Value = value; }
57    }
58    #endregion
59
60    #region Parameter Properties
61    public IValueParameter<IntValue> SeedParameter {
62      get { return (IValueParameter<IntValue>)Parameters["Seed"]; }
63    }
64    public IValueParameter<BoolValue> SetSeedRandomlyParameter {
65      get { return (IValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
66    }
67    public IValueParameter<IntValue> SwarmSizeParameter {
68      get { return (IValueParameter<IntValue>)Parameters["SwarmSize"]; }
69    }
70    public IValueParameter<IntValue> MaxIterationsParameter {
71      get { return (IValueParameter<IntValue>)Parameters["MaxIterations"]; }
72    }
73    public IValueParameter<DoubleValue> InertiaParameter {
74      get { return (IValueParameter<DoubleValue>)Parameters["Inertia"]; }
75    }
76    public IValueParameter<DoubleValue> PersonalBestAttractionParameter {
77      get { return (IValueParameter<DoubleValue>)Parameters["PersonalBestAttraction"]; }
78    }
79    public IValueParameter<DoubleValue> NeighborBestAttractionParameter {
80      get { return (IValueParameter<DoubleValue>)Parameters["NeighborBestAttraction"]; }
81    }
82    public IValueParameter<MultiAnalyzer> AnalyzerParameter {
83      get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
84    }
85    public ConstrainedValueParameter<IParticleCreator> ParticleCreatorParameter {
86      get { return (ConstrainedValueParameter<IParticleCreator>)Parameters["ParticleCreator"]; }
87    }
88    public ConstrainedValueParameter<IParticleUpdater> ParticleUpdaterParameter {
89      get { return (ConstrainedValueParameter<IParticleUpdater>)Parameters["ParticleUpdater"]; }
90    }
91    public OptionalConstrainedValueParameter<ITopologyInitializer> TopologyInitializerParameter {
92      get { return (OptionalConstrainedValueParameter<ITopologyInitializer>)Parameters["TopologyInitializer"]; }
93    }
94    public OptionalConstrainedValueParameter<ITopologyUpdater> TopologyUpdaterParameter {
95      get { return (OptionalConstrainedValueParameter<ITopologyUpdater>)Parameters["TopologyUpdater"]; }
96    }
97    public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> InertiaUpdaterParameter {
98      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["InertiaUpdater"]; }
99    }
100    public ConstrainedValueParameter<ISwarmUpdater> SwarmUpdaterParameter {
101      get { return (ConstrainedValueParameter<ISwarmUpdater>)Parameters["SwarmUpdater"]; }
102
103    }
104    #endregion
105
106    #region Properties
107
108    public string Filename { get; set; }
109
110    [Storable]
111    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
112
113    [Storable]
114    private SolutionsCreator solutionsCreator;
115
116    [Storable]
117    private ParticleSwarmOptimizationMainLoop mainLoop;
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 IParticleCreator ParticleCreator {
130      get { return ParticleCreatorParameter.Value; }
131      set { ParticleCreatorParameter.Value = value; }
132    }
133
134    public IParticleUpdater ParticleUpdater {
135      get { return ParticleUpdaterParameter.Value; }
136      set { ParticleUpdaterParameter.Value = value; }
137    }
138    #endregion
139
140    [StorableConstructor]
141    private ParticleSwarmOptimization(bool deserializing) : base(deserializing) { }
142    private ParticleSwarmOptimization(ParticleSwarmOptimization original, Cloner cloner)
143      : base(original, cloner) {
144      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
145      solutionsCreator = cloner.Clone(original.solutionsCreator);
146      mainLoop = cloner.Clone(original.mainLoop);
147      Initialize();
148    }
149    public ParticleSwarmOptimization()
150      : base() {
151      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
152      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
153      Parameters.Add(new ValueParameter<IntValue>("SwarmSize", "Size of the particle swarm.", new IntValue(10)));
154      Parameters.Add(new ValueParameter<IntValue>("MaxIterations", "Maximal number of iterations.", new IntValue(1000)));
155      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
156      Parameters.Add(new ValueParameter<DoubleValue>("Inertia", "Inertia weight on a particle's movement (omega).", new DoubleValue(-0.2)));
157      Parameters.Add(new ValueParameter<DoubleValue>("PersonalBestAttraction", "Weight for particle's pull towards its personal best soution (phi_p).", new DoubleValue(-0.01)));
158      Parameters.Add(new ValueParameter<DoubleValue>("NeighborBestAttraction", "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)));
159      Parameters.Add(new ConstrainedValueParameter<IParticleCreator>("ParticleCreator", "Operator creates a new particle."));
160      Parameters.Add(new ConstrainedValueParameter<IParticleUpdater>("ParticleUpdater", "Operator that updates a particle."));
161      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyInitializer>("TopologyInitializer", "Creates neighborhood description vectors."));
162      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyUpdater>("TopologyUpdater", "Updates the neighborhood description vectors."));
163      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("InertiaUpdater", "Updates the omega parameter."));
164      Parameters.Add(new ConstrainedValueParameter<ISwarmUpdater>("SwarmUpdater", "Encoding-specific parameter which is provided by the problem. May provide additional encoding-specific parameters, such as velocity bounds for real valued problems"));
165
166      RandomCreator randomCreator = new RandomCreator();
167      VariableCreator variableCreator = new VariableCreator();
168      Assigner assigner = new Assigner();
169      solutionsCreator = new SolutionsCreator();
170      SubScopesCounter subScopesCounter = new SubScopesCounter();
171      Placeholder topologyInitializerPlaceholder = new Placeholder();
172      Placeholder analyzerPlaceholder = new Placeholder();
173      mainLoop = new ParticleSwarmOptimizationMainLoop();
174
175      OperatorGraph.InitialOperator = randomCreator;
176
177      randomCreator.SetSeedRandomlyParameter.Value = null;
178      randomCreator.SeedParameter.Value = null;
179      randomCreator.Successor = variableCreator;
180
181      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("CurrentIteration", new IntValue(0)));
182      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("CurrentVelocityBounds", new DoubleValue(0)));
183      variableCreator.Successor = assigner;
184
185      assigner.Name = "CurrentInertia := Inertia";
186      assigner.LeftSideParameter.ActualName = "CurrentInertia";
187      assigner.RightSideParameter.ActualName = "Inertia";
188      assigner.Successor = solutionsCreator;
189
190      solutionsCreator.NumberOfSolutionsParameter.ActualName = "SwarmSize";
191      ParameterizeSolutionsCreator();
192      solutionsCreator.Successor = subScopesCounter;
193
194      subScopesCounter.Name = "Initialize EvaluatedSolutions";
195      subScopesCounter.ValueParameter.ActualName = "EvaluatedSolutions";
196      subScopesCounter.Successor = topologyInitializerPlaceholder;
197
198      topologyInitializerPlaceholder.Name = "(TopologyInitializer)";
199      topologyInitializerPlaceholder.OperatorParameter.ActualName = "TopologyInitializer";
200      topologyInitializerPlaceholder.Successor = mainLoop;
201
202      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
203      mainLoop.InertiaParameter.ActualName = "CurrentInertia";
204      mainLoop.MaxIterationsParameter.ActualName = MaxIterationsParameter.Name;
205      mainLoop.NeighborBestAttractionParameter.ActualName = NeighborBestAttractionParameter.Name;
206      mainLoop.InertiaUpdaterParameter.ActualName = InertiaUpdaterParameter.Name;
207      mainLoop.ParticleUpdaterParameter.ActualName = ParticleUpdaterParameter.Name;
208      mainLoop.PersonalBestAttractionParameter.ActualName = PersonalBestAttractionParameter.Name;
209      mainLoop.RandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
210      mainLoop.SwarmSizeParameter.ActualName = SwarmSizeParameter.Name;
211      mainLoop.TopologyUpdaterParameter.ActualName = TopologyUpdaterParameter.Name;
212      mainLoop.RandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
213      mainLoop.ResultsParameter.ActualName = "Results";
214
215      InitializeAnalyzers();
216      InitializeParticleCreator();
217      InitializeSwarmUpdater();
218      ParameterizeSolutionsCreator();
219      UpdateAnalyzers();
220      UpdateInertiaUpdater();
221      InitInertiaUpdater();
222      UpdateTopologyInitializer();
223      Initialize();
224      ParameterizeMainLoop();
225    }
226
227    public override IDeepCloneable Clone(Cloner cloner) {
228      return new ParticleSwarmOptimization(this, cloner);
229    }
230
231    [StorableHook(HookType.AfterDeserialization)]
232    private void AfterDeserialization() {
233      Initialize();
234    }
235
236    public override void Prepare() {
237      if (Problem != null && ParticleCreator != null && ParticleUpdater != null) {
238        base.Prepare();
239      }
240    }
241
242    #region Events
243    protected override void OnProblemChanged() {
244      UpdateAnalyzers();
245      ParameterizeAnalyzers();
246      UpdateTopologyParameters();
247      InitializeParticleCreator();
248      InitializeSwarmUpdater();
249      ParameterizeSolutionsCreator();
250      base.OnProblemChanged();
251    }
252
253    void TopologyInitializerParameter_ValueChanged(object sender, EventArgs e) {
254      this.UpdateTopologyParameters();
255    }
256    #endregion
257
258    #region Helpers
259    private void Initialize() {
260      TopologyInitializerParameter.ValueChanged += new EventHandler(TopologyInitializerParameter_ValueChanged);
261    }
262
263    private void InitializeParticleCreator() {
264      if (Problem != null) {
265        IParticleCreator oldParticleCreator = ParticleCreator;
266        ParticleCreatorParameter.ValidValues.Clear();
267        foreach (IParticleCreator Creator in Problem.Operators.OfType<IParticleCreator>().OrderBy(x => x.Name)) {
268          ParticleCreatorParameter.ValidValues.Add(Creator);
269        }
270        if (oldParticleCreator != null) {
271          IParticleCreator creator = ParticleCreatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleCreator.GetType());
272          if (creator != null) ParticleCreator = creator;
273        }
274      }
275    }
276
277    private void InitializeAnalyzers() {
278      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
279      qualityAnalyzer.ResultsParameter.ActualName = "Results";
280      ParameterizeAnalyzers();
281    }
282
283    private void ParameterizeAnalyzers() {
284      if (Problem != null) {
285        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
286        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
287        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
288      }
289    }
290
291    private void UpdateAnalyzers() {
292      Analyzer.Operators.Clear();
293      if (Problem != null) {
294        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>())
295          Analyzer.Operators.Add(analyzer);
296      }
297      Analyzer.Operators.Add(qualityAnalyzer);
298    }
299
300    private void InitInertiaUpdater() {
301      foreach (IDiscreteDoubleValueModifier updater in InertiaUpdaterParameter.ValidValues) {
302        updater.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
303        updater.StartIndexParameter.Value = new IntValue(0);
304        updater.IndexParameter.ActualName = "CurrentIteration";
305        updater.ValueParameter.ActualName = "CurrentInertia";
306        updater.StartValueParameter.Value = new DoubleValue(1);
307        updater.EndValueParameter.Value = new DoubleValue(double.Epsilon);
308      }
309    }
310
311    private void UpdateInertiaUpdater() {
312      IDiscreteDoubleValueModifier oldInertiaUpdater = InertiaUpdater;
313      InertiaUpdaterParameter.ValidValues.Clear();
314      foreach (IDiscreteDoubleValueModifier updater in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
315        InertiaUpdaterParameter.ValidValues.Add(updater);
316      }
317      if (oldInertiaUpdater != null) {
318        IDiscreteDoubleValueModifier updater = InertiaUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldInertiaUpdater.GetType());
319        if (updater != null) InertiaUpdaterParameter.Value = updater;
320      }
321    }
322
323    private void UpdateTopologyInitializer() {
324      ITopologyInitializer oldTopologyInitializer = TopologyInitializer;
325      TopologyInitializerParameter.ValidValues.Clear();
326      foreach (ITopologyInitializer topologyInitializer in ApplicationManager.Manager.GetInstances<ITopologyInitializer>().OrderBy(x => x.Name)) {
327        TopologyInitializerParameter.ValidValues.Add(topologyInitializer);
328      }
329      if (oldTopologyInitializer != null && TopologyInitializerParameter.ValidValues.Any(x => x.GetType() == oldTopologyInitializer.GetType()))
330        TopologyInitializer = TopologyInitializerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldTopologyInitializer.GetType());
331      UpdateTopologyParameters();
332    }
333
334    private void UpdateTopologyParameters() {
335      ITopologyUpdater oldTopologyUpdater = TopologyUpdater;
336      IParticleUpdater oldParticleUpdater = ParticleUpdater;
337      ClearTopologyParameters();
338      if (Problem != null) {
339        if (TopologyInitializer != null) {
340          foreach (ITopologyUpdater topologyUpdater in ApplicationManager.Manager.GetInstances<ITopologyUpdater>())
341            TopologyUpdaterParameter.ValidValues.Add(topologyUpdater);
342          foreach (IParticleUpdater particleUpdater in Problem.Operators.OfType<ILocalParticleUpdater>().OrderBy(x => x.Name))
343            ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
344        } else {
345          foreach (IParticleUpdater particleUpdater in Problem.Operators.OfType<IGlobalParticleUpdater>().OrderBy(x => x.Name))
346            ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
347        }
348        if (oldTopologyUpdater != null) {
349          ITopologyUpdater newTopologyUpdater = TopologyUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
350          if (newTopologyUpdater != null) TopologyUpdater = newTopologyUpdater;
351        }
352        if (oldParticleUpdater != null) {
353          IParticleUpdater newParticleUpdater = ParticleUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
354          if (newParticleUpdater != null) ParticleUpdater = newParticleUpdater;
355        }
356      }
357    }
358
359    private void ClearTopologyParameters() {
360      TopologyUpdaterParameter.ValidValues.Clear();
361      ParticleUpdaterParameter.ValidValues.Clear();
362    }
363
364    private void ParameterizeSolutionsCreator() {
365      if (Problem != null) {
366        solutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
367        solutionsCreator.SolutionCreatorParameter.ActualName = ParticleCreatorParameter.Name;
368      }
369    }
370
371    private void ParameterizeMainLoop() {
372      if (Problem != null) {
373        mainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
374      }
375    }
376
377    private void InitializeSwarmUpdater() {
378      if (Problem != null) {
379        ISwarmUpdater updater = Problem.Operators.OfType<ISwarmUpdater>().FirstOrDefault();
380        SwarmUpdaterParameter.ValidValues.Clear();
381        SwarmUpdaterParameter.ValidValues.Add(updater);
382        SwarmUpdaterParameter.Value = updater;
383      }
384    }
385    #endregion
386
387  }
388}
Note: See TracBrowser for help on using the repository browser.