source: trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs @ 5643

Last change on this file since 5643 was 5643, checked in by mkofler, 11 years ago

#852: PSO code refactoring. Cleanup and minor improvements.

File size: 9.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.Linq;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Encodings.RealVectorEncoding {
32  [Item("Swarm Updater", "Updates personal best point and quality as well as global best point and quality.")]
33  [StorableClass]
34  public sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater {
35
36    public override bool CanChangeName {
37      get { return false; }
38    }
39
40    #region Parameter properties
41    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
42      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
43    }
44    public IScopeTreeLookupParameter<DoubleValue> PersonalBestQualityParameter {
45      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["PersonalBestQuality"]; }
46    }
47    public IScopeTreeLookupParameter<DoubleValue> NeighborBestQualityParameter {
48      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["NeighborBestQuality"]; }
49    }
50    public IScopeTreeLookupParameter<RealVector> RealVectorParameter {
51      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["RealVector"]; }
52    }
53    public IScopeTreeLookupParameter<RealVector> PersonalBestParameter {
54      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["PersonalBest"]; }
55    }
56    public IScopeTreeLookupParameter<RealVector> NeighborBestParameter {
57      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["NeighborBest"]; }
58    }
59    public ILookupParameter<BoolValue> MaximizationParameter {
60      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
61    }
62    public ILookupParameter<DoubleValue> BestQualityParameter {
63      get { return (ILookupParameter<DoubleValue>)Parameters["BestQuality"]; }
64    }
65    public ILookupParameter<RealVector> BestRealVectorParameter {
66      get { return (ILookupParameter<RealVector>)Parameters["BestRealVector"]; }
67    }
68    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
69      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
70    }
71    public ValueLookupParameter<IDiscreteDoubleMatrixModifier> VelocityBoundsUpdaterParameter {
72      get { return (ValueLookupParameter<IDiscreteDoubleMatrixModifier>)Parameters["VelocityBoundsUpdater"]; }
73    }
74    public LookupParameter<DoubleMatrix> VelocityBoundsParameter {
75      get { return (LookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
76    }
77    #endregion
78
79    #region Parameter values
80    private DoubleValue BestQuality {
81      get { return BestQualityParameter.ActualValue; }
82      set { BestQualityParameter.ActualValue = value; }
83    }
84    private RealVector BestRealVector {
85      get { return BestRealVectorParameter.ActualValue; }
86      set { BestRealVectorParameter.ActualValue = value; }
87    }
88    private ItemArray<DoubleValue> Quality {
89      get { return QualityParameter.ActualValue; }
90    }
91    private ItemArray<DoubleValue> PersonalBestQuality {
92      get { return PersonalBestQualityParameter.ActualValue; }
93      set { PersonalBestQualityParameter.ActualValue = value; }
94    }
95    private ItemArray<DoubleValue> NeighborBestQuality {
96      get { return NeighborBestQualityParameter.ActualValue; }
97      set { NeighborBestQualityParameter.ActualValue = value; }
98    }
99    private ItemArray<RealVector> RealVector {
100      get { return RealVectorParameter.ActualValue; }
101    }
102    private ItemArray<RealVector> PersonalBest {
103      get { return PersonalBestParameter.ActualValue; }
104      set { PersonalBestParameter.ActualValue = value; }
105    }
106    private ItemArray<RealVector> NeighborBest {
107      get { return NeighborBestParameter.ActualValue; }
108      set { NeighborBestParameter.ActualValue = value; }
109    }
110    private bool Maximization {
111      get { return MaximizationParameter.ActualValue.Value; }
112    }
113    private ItemArray<IntArray> Neighbors {
114      get { return NeighborsParameter.ActualValue; }
115    }
116    private IDiscreteDoubleMatrixModifier VelocityBoundsUpdater {
117      get { return VelocityBoundsUpdaterParameter.ActualValue; }
118    }
119    private DoubleMatrix VelocityBounds {
120      get { return VelocityBoundsParameter.ActualValue; }
121      set { VelocityBoundsParameter.ActualValue = value; }
122    }
123    #endregion
124
125    #region Construction & Cloning
126
127    [StorableConstructor]
128    private RealVectorSwarmUpdater(bool deserializing) : base(deserializing) { }
129    private RealVectorSwarmUpdater(RealVectorSwarmUpdater original, Cloner cloner) : base(original, cloner) { }
130    public RealVectorSwarmUpdater()
131      : base() {
132      Parameters.Add(new LookupParameter<DoubleValue>("BestQuality", "Overall best quality."));
133      Parameters.Add(new LookupParameter<RealVector>("BestRealVector", "Global best particle position"));
134      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "Particle's quality"));
135      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("PersonalBestQuality", "Particle's personal best quality"));
136      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("NeighborBestQuality", "Global best particle quality"));
137      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("RealVector", "Particle's position"));
138      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("PersonalBest", "Particle's personal best position"));
139      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("NeighborBest", "Neighborhood (or global in case of totally connected neighborhood) best particle position"));
140      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
141      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
142      Parameters.Add(new ValueLookupParameter<IDiscreteDoubleMatrixModifier>("VelocityBoundsUpdater", "Modifies the velocity bounds in the course of optimization."));
143      Parameters.Add(new LookupParameter<DoubleMatrix>("VelocityBounds", "Maximum velocity for each dimension."));
144    }
145
146    public override IDeepCloneable Clone(Cloner cloner) {
147      return new RealVectorSwarmUpdater(this, cloner);
148    }
149
150    #endregion
151
152    public override IOperation Apply() {
153      UpdateGlobalBest();
154      UpdateNeighborBest();
155      UpdatePersonalBest();
156      return UpdateVelocityBounds();
157    }
158
159    private void UpdateGlobalBest() {
160      if (BestQuality == null)
161        BestQuality = new DoubleValue();
162      BestQuality.Value = Maximization ? Quality.Max(v => v.Value) : Quality.Min(v => v.Value);
163      BestRealVector = (RealVector)RealVector[Quality.FindIndex(v => v.Value == BestQuality.Value)].Clone();
164    }
165
166    private void UpdateNeighborBest() {
167      if (Neighbors.Length > 0) {
168        var neighborBest = new ItemArray<RealVector>(Neighbors.Length);
169        var neighborBestQuality = new ItemArray<DoubleValue>(Neighbors.Length);
170        for (int n = 0; n < Neighbors.Length; n++) {
171          var pairs = Quality.Zip(RealVector, (q, p) => new { Quality = q, Point = p })
172            .Where((p, i) => i == n || Neighbors[n].Contains(i));
173          var bestNeighbor = Maximization ?
174            pairs.OrderByDescending(p => p.Quality.Value).First() :
175            pairs.OrderBy(p => p.Quality.Value).First();
176          neighborBest[n] = bestNeighbor.Point;
177          neighborBestQuality[n] = bestNeighbor.Quality;
178        }
179        NeighborBest = neighborBest;
180        NeighborBestQuality = neighborBestQuality;
181      }
182    }
183
184    private void UpdatePersonalBest() {
185      if (PersonalBestQuality.Length == 0)
186        PersonalBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
187      for (int i = 0; i < RealVector.Length; i++) {
188        if (Maximization && Quality[i].Value > PersonalBestQuality[i].Value ||
189          !Maximization && Quality[i].Value < PersonalBestQuality[i].Value) {
190          PersonalBestQuality[i].Value = Quality[i].Value;
191          PersonalBest[i] = RealVector[i];
192        }
193      }
194    }
195
196    private IOperation UpdateVelocityBounds() {
197      if (VelocityBounds == null)
198        VelocityBounds = new DoubleMatrix(new double[,] { { -1, 1 } });
199      return VelocityBoundsUpdater == null ?
200        base.Apply() :
201        new OperationCollection() {
202          ExecutionContext.CreateChildOperation(VelocityBoundsUpdater),
203          ExecutionContext.CreateOperation(Successor)
204        };
205    }
206  }
207}
Note: See TracBrowser for help on using the repository browser.