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

Last change on this file since 5866 was 5866, checked in by epitzer, 11 years ago
  • Remove superfluous placeholders
  • Hide ParticleUpdater
  • Add CurrentVelocityBounds parameter analogous to CurrentInertia
  • Add (Current)VelocityBounds to results
  • Merge VelocityBoundsModifier directly into SwarmUpdater (#852)
File size: 14.5 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.Optimization.Operators;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.PluginInfrastructure;
32
33namespace HeuristicLab.Encodings.RealVectorEncoding {
34  [Item("Swarm Updater", "Updates personal best point and quality as well as global best point and quality.")]
35  [StorableClass]
36  public sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater {
37
38    [Storable]
39    private ResultsCollector ResultsCollector;
40
41    public override bool CanChangeName {
42      get { return false; }
43    }
44
45    #region Parameter properties
46    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
47      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
48    }
49    public IScopeTreeLookupParameter<DoubleValue> PersonalBestQualityParameter {
50      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["PersonalBestQuality"]; }
51    }
52    public IScopeTreeLookupParameter<DoubleValue> NeighborBestQualityParameter {
53      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["NeighborBestQuality"]; }
54    }
55    public IScopeTreeLookupParameter<RealVector> RealVectorParameter {
56      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["RealVector"]; }
57    }
58    public IScopeTreeLookupParameter<RealVector> PersonalBestParameter {
59      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["PersonalBest"]; }
60    }
61    public IScopeTreeLookupParameter<RealVector> NeighborBestParameter {
62      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["NeighborBest"]; }
63    }
64    public ILookupParameter<BoolValue> MaximizationParameter {
65      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
66    }
67    public ILookupParameter<DoubleValue> BestQualityParameter {
68      get { return (ILookupParameter<DoubleValue>)Parameters["BestQuality"]; }
69    }
70    public ILookupParameter<RealVector> BestRealVectorParameter {
71      get { return (ILookupParameter<RealVector>)Parameters["BestRealVector"]; }
72    }
73    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
74      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
75    }
76    public IValueLookupParameter<DoubleMatrix> VelocityBoundsParameter {
77      get { return (ValueLookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
78    }
79    public ILookupParameter<DoubleMatrix> CurrentVelocityBoundsParameter {
80      get { return (ILookupParameter<DoubleMatrix>)Parameters["CurrentVelocityBounds"]; }
81    }
82    public LookupParameter<ResultCollection> ResultsParameter {
83      get { return (LookupParameter<ResultCollection>)Parameters["Results"]; }
84    }
85
86    #region Velocity Bounds Updating
87    public ILookupParameter<DoubleValue> VelocityBoundsScaleParameter {
88      get { return (ILookupParameter<DoubleValue>)Parameters["VelocityBoundsScale"]; }
89    }
90    public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> VelocityBoundsScalingOperatorParameter {
91      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["VelocityBoundsScalingOperator"]; }
92    }
93    public IValueLookupParameter<DoubleValue> VelocityBoundsStartValueParameter {
94      get { return (IValueLookupParameter<DoubleValue>)Parameters["VelocityBoundsStartValue"]; }
95    }
96    public IValueLookupParameter<DoubleValue> VelocityBoundsEndValueParameter {
97      get { return (IValueLookupParameter<DoubleValue>)Parameters["VelocityBoundsEndValue"]; }
98    }
99    public ILookupParameter<IntValue> VelocityBoundsIndexParameter {
100      get { return (ILookupParameter<IntValue>)Parameters["VelocityBoundsIndex"]; }
101    }
102    public IValueLookupParameter<IntValue> VelocityBoundsStartIndexParameter {
103      get { return (IValueLookupParameter<IntValue>)Parameters["VelocityBoundsStartIndex"]; }
104    }
105    public IValueLookupParameter<IntValue> VelocityBoundsEndIndexParameter {
106      get { return (IValueLookupParameter<IntValue>)Parameters["VelocityBoundsEndIndex"]; }
107    }
108    #endregion
109
110    #endregion
111
112    #region Parameter values
113    private DoubleValue BestQuality {
114      get { return BestQualityParameter.ActualValue; }
115      set { BestQualityParameter.ActualValue = value; }
116    }
117    private RealVector BestRealVector {
118      get { return BestRealVectorParameter.ActualValue; }
119      set { BestRealVectorParameter.ActualValue = value; }
120    }
121    private ItemArray<DoubleValue> Quality {
122      get { return QualityParameter.ActualValue; }
123    }
124    private ItemArray<DoubleValue> PersonalBestQuality {
125      get { return PersonalBestQualityParameter.ActualValue; }
126      set { PersonalBestQualityParameter.ActualValue = value; }
127    }
128    private ItemArray<DoubleValue> NeighborBestQuality {
129      get { return NeighborBestQualityParameter.ActualValue; }
130      set { NeighborBestQualityParameter.ActualValue = value; }
131    }
132    private ItemArray<RealVector> RealVector {
133      get { return RealVectorParameter.ActualValue; }
134    }
135    private ItemArray<RealVector> PersonalBest {
136      get { return PersonalBestParameter.ActualValue; }
137      set { PersonalBestParameter.ActualValue = value; }
138    }
139    private ItemArray<RealVector> NeighborBest {
140      get { return NeighborBestParameter.ActualValue; }
141      set { NeighborBestParameter.ActualValue = value; }
142    }
143    private bool Maximization {
144      get { return MaximizationParameter.ActualValue.Value; }
145    }
146    private ItemArray<IntArray> Neighbors {
147      get { return NeighborsParameter.ActualValue; }
148    }
149    private DoubleMatrix VelocityBounds {
150      get { return VelocityBoundsParameter.ActualValue; }
151    }
152    private DoubleMatrix CurrentVelocityBounds {
153      get { return CurrentVelocityBoundsParameter.ActualValue; }
154      set { CurrentVelocityBoundsParameter.ActualValue = value; }
155    }
156    private DoubleValue VelocityBoundsScale {
157      get { return VelocityBoundsScaleParameter.ActualValue; }
158      set { VelocityBoundsScaleParameter.ActualValue = value; }
159    }
160    private DoubleValue VelocityBoundsStartValue {
161      get { return VelocityBoundsStartValueParameter.ActualValue; }
162    }
163    private IDiscreteDoubleValueModifier VelocityBoundsScalingOperator {
164      get { return VelocityBoundsScalingOperatorParameter.Value; }
165    }
166    private ResultCollection Results {
167      get { return ResultsParameter.ActualValue; }
168    }
169    #endregion
170
171    #region Construction & Cloning
172
173    [StorableConstructor]
174    private RealVectorSwarmUpdater(bool deserializing) : base(deserializing) { }
175    private RealVectorSwarmUpdater(RealVectorSwarmUpdater original, Cloner cloner)
176      : base(original, cloner) {
177      ResultsCollector = cloner.Clone(original.ResultsCollector);
178    }
179    public RealVectorSwarmUpdater()
180      : base() {
181      Parameters.Add(new LookupParameter<DoubleValue>("BestQuality", "Overall best quality."));
182      Parameters.Add(new LookupParameter<RealVector>("BestRealVector", "Global best particle position"));
183      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "Particle's quality"));
184      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("PersonalBestQuality", "Particle's personal best quality"));
185      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("NeighborBestQuality", "Global best particle quality"));
186      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("RealVector", "Particle's position"));
187      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("PersonalBest", "Particle's personal best position"));
188      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("NeighborBest", "Neighborhood (or global in case of totally connected neighborhood) best particle position"));
189      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
190      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
191      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("VelocityBounds", "Maximum velocity for each dimension.", new DoubleMatrix(new double[,] { { -1, 1 } })));
192      Parameters.Add(new LookupParameter<DoubleMatrix>("CurrentVelocityBounds", "Current value of velocity bounds."));
193      Parameters.Add(new LookupParameter<ResultCollection>("Results", "Results"));
194
195      #region Velocity Bounds Updating
196      Parameters.Add(new LookupParameter<DoubleValue>("VelocityBoundsScale", "Scale parameter."));
197      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("VelocityBoundsScalingOperator", "Modifies the value"));
198      Parameters.Add(new ValueLookupParameter<DoubleValue>("VelocityBoundsStartValue", "The start value of 'Value'.", new DoubleValue(1)));
199      Parameters.Add(new ValueLookupParameter<DoubleValue>("VelocityBoundsEndValue", "The end value of 'Value'.", new DoubleValue(1E-10)));
200      Parameters.Add(new LookupParameter<IntValue>("VelocityBoundsIndex", "The current index.", "CurrentIteration"));
201      Parameters.Add(new ValueLookupParameter<IntValue>("VelocityBoundsStartIndex", "The start index at which to start modifying 'Value'.", new IntValue(0)));
202      Parameters.Add(new ValueLookupParameter<IntValue>("VelocityBoundsEndIndex", "The end index by which 'Value' should have reached 'EndValue'.", "MaxIterations"));
203      VelocityBoundsStartIndexParameter.Hidden = true;
204      VelocityBoundsEndIndexParameter.Hidden = true;
205      #endregion
206
207      Initialize();
208    }
209
210    public override IDeepCloneable Clone(Cloner cloner) {
211      return new RealVectorSwarmUpdater(this, cloner);
212    }
213
214    #endregion
215
216    private void Initialize() {
217      ResultsCollector = new ResultsCollector();
218      ResultsCollector.CollectedValues.Add(CurrentVelocityBoundsParameter);
219      ResultsCollector.CollectedValues.Add(VelocityBoundsParameter);
220
221      foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>()) {
222        VelocityBoundsScalingOperatorParameter.ValidValues.Add(op);
223        op.ValueParameter.ActualName = VelocityBoundsScaleParameter.Name;
224        op.StartValueParameter.ActualName = VelocityBoundsStartValueParameter.Name;
225        op.EndValueParameter.ActualName = VelocityBoundsEndValueParameter.Name;
226        op.IndexParameter.ActualName = VelocityBoundsIndexParameter.Name;
227        op.StartIndexParameter.ActualName = VelocityBoundsStartIndexParameter.Name;
228        op.EndIndexParameter.ActualName = VelocityBoundsEndIndexParameter.Name;
229      }
230      VelocityBoundsScalingOperatorParameter.Value = null;
231    }
232
233    public override IOperation Apply() {
234      UpdateGlobalBest();
235      UpdateNeighborBest();
236      UpdatePersonalBest();
237      return UpdateVelocityBounds();
238    }
239
240    private void UpdateGlobalBest() {
241      if (BestQuality == null)
242        BestQuality = new DoubleValue();
243      BestQuality.Value = Maximization ? Quality.Max(v => v.Value) : Quality.Min(v => v.Value);
244      BestRealVector = (RealVector)RealVector[Quality.FindIndex(v => v.Value == BestQuality.Value)].Clone();
245    }
246
247    private void UpdateNeighborBest() {
248      if (Neighbors.Length > 0) {
249        var neighborBest = new ItemArray<RealVector>(Neighbors.Length);
250        var neighborBestQuality = new ItemArray<DoubleValue>(Neighbors.Length);
251        for (int n = 0; n < Neighbors.Length; n++) {
252          var pairs = Quality.Zip(RealVector, (q, p) => new { Quality = q, Point = p })
253            .Where((p, i) => i == n || Neighbors[n].Contains(i));
254          var bestNeighbor = Maximization ?
255            pairs.OrderByDescending(p => p.Quality.Value).First() :
256            pairs.OrderBy(p => p.Quality.Value).First();
257          neighborBest[n] = bestNeighbor.Point;
258          neighborBestQuality[n] = bestNeighbor.Quality;
259        }
260        NeighborBest = neighborBest;
261        NeighborBestQuality = neighborBestQuality;
262      }
263    }
264
265    private void UpdatePersonalBest() {
266      if (PersonalBestQuality.Length == 0)
267        PersonalBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
268      for (int i = 0; i < RealVector.Length; i++) {
269        if (Maximization && Quality[i].Value > PersonalBestQuality[i].Value ||
270          !Maximization && Quality[i].Value < PersonalBestQuality[i].Value) {
271          PersonalBestQuality[i].Value = Quality[i].Value;
272          PersonalBest[i] = RealVector[i];
273        }
274      }
275    }
276
277
278
279    private IOperation UpdateVelocityBounds() {
280      if (CurrentVelocityBounds == null)
281        CurrentVelocityBounds = (DoubleMatrix)VelocityBounds.Clone();
282
283      if (VelocityBoundsScalingOperator == null)
284        return new OperationCollection() {
285          ExecutionContext.CreateChildOperation(ResultsCollector),       
286          base.Apply()
287        };
288
289
290      DoubleMatrix matrix = CurrentVelocityBounds;
291      if (VelocityBoundsScale == null && VelocityBoundsStartValue != null) {
292        VelocityBoundsScale = new DoubleValue(VelocityBoundsStartValue.Value);
293      }
294      for (int i = 0; i < matrix.Rows; i++) {
295        for (int j = 0; j < matrix.Columns; j++) {
296          if (matrix[i, j] >= 0) {
297            matrix[i, j] = VelocityBoundsScale.Value;
298          } else {
299            matrix[i, j] = (-1) * VelocityBoundsScale.Value;
300          }
301        }
302      }
303
304      return new OperationCollection() {
305        ExecutionContext.CreateChildOperation(ResultsCollector),
306        ExecutionContext.CreateChildOperation(VelocityBoundsScalingOperator),       
307        base.Apply()
308      };
309    }
310  }
311}
Note: See TracBrowser for help on using the repository browser.