Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs @ 17138

Last change on this file since 17138 was 17097, checked in by mkommend, 5 years ago

#2520: Merged 16565 - 16579 into stable.

File size: 16.8 KB
RevLine 
[5560]1#region License Information
2/* HeuristicLab
[17097]3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[5560]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
[5905]22using System;
[5561]23using System.Linq;
[5560]24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Operators;
[5568]28using HeuristicLab.Optimization;
[5866]29using HeuristicLab.Optimization.Operators;
[5560]30using HeuristicLab.Parameters;
[17097]31using HEAL.Attic;
[5866]32using HeuristicLab.PluginInfrastructure;
[5560]33
34namespace HeuristicLab.Encodings.RealVectorEncoding {
[5911]35  [Item("RealVectorSwarmUpdater", "Updates personal best point and quality as well as global best point and quality.")]
[17097]36  [StorableType("190172D5-090F-49DA-B2FB-AD2DF8064F77")]
[15277]37  [NonDiscoverableType]
38  [Obsolete("Use SPSOSwarmUpdater")]
39  internal sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater, ISingleObjectiveOperator {
[5592]40
[5866]41    [Storable]
42    private ResultsCollector ResultsCollector;
43
[5560]44    public override bool CanChangeName {
45      get { return false; }
46    }
47
48    #region Parameter properties
[5561]49    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
50      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
[5560]51    }
[5561]52    public IScopeTreeLookupParameter<DoubleValue> PersonalBestQualityParameter {
53      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["PersonalBestQuality"]; }
[5560]54    }
[5568]55    public IScopeTreeLookupParameter<DoubleValue> NeighborBestQualityParameter {
56      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["NeighborBestQuality"]; }
[5560]57    }
[5561]58    public IScopeTreeLookupParameter<RealVector> RealVectorParameter {
59      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["RealVector"]; }
[5560]60    }
[5561]61    public IScopeTreeLookupParameter<RealVector> PersonalBestParameter {
62      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["PersonalBest"]; }
[5560]63    }
[5568]64    public IScopeTreeLookupParameter<RealVector> NeighborBestParameter {
65      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["NeighborBest"]; }
[5560]66    }
[5568]67    public ILookupParameter<BoolValue> MaximizationParameter {
68      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
[5560]69    }
[7073]70    public ILookupParameter<DoubleValue> SwarmBestQualityParameter {
71      get { return (ILookupParameter<DoubleValue>)Parameters["SwarmBestQuality"]; }
[5561]72    }
[5643]73    public ILookupParameter<RealVector> BestRealVectorParameter {
74      get { return (ILookupParameter<RealVector>)Parameters["BestRealVector"]; }
[5561]75    }
76    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
77      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
78    }
[5866]79    public IValueLookupParameter<DoubleMatrix> VelocityBoundsParameter {
80      get { return (ValueLookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
[5568]81    }
[5866]82    public ILookupParameter<DoubleMatrix> CurrentVelocityBoundsParameter {
83      get { return (ILookupParameter<DoubleMatrix>)Parameters["CurrentVelocityBounds"]; }
[5568]84    }
[5866]85    public LookupParameter<ResultCollection> ResultsParameter {
86      get { return (LookupParameter<ResultCollection>)Parameters["Results"]; }
87    }
88
89    #region Velocity Bounds Updating
90    public ILookupParameter<DoubleValue> VelocityBoundsScaleParameter {
91      get { return (ILookupParameter<DoubleValue>)Parameters["VelocityBoundsScale"]; }
92    }
[8121]93    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> VelocityBoundsScalingOperatorParameter {
94      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["VelocityBoundsScalingOperator"]; }
[5866]95    }
96    public IValueLookupParameter<DoubleValue> VelocityBoundsStartValueParameter {
97      get { return (IValueLookupParameter<DoubleValue>)Parameters["VelocityBoundsStartValue"]; }
98    }
99    public IValueLookupParameter<DoubleValue> VelocityBoundsEndValueParameter {
100      get { return (IValueLookupParameter<DoubleValue>)Parameters["VelocityBoundsEndValue"]; }
101    }
102    public ILookupParameter<IntValue> VelocityBoundsIndexParameter {
103      get { return (ILookupParameter<IntValue>)Parameters["VelocityBoundsIndex"]; }
104    }
105    public IValueLookupParameter<IntValue> VelocityBoundsStartIndexParameter {
106      get { return (IValueLookupParameter<IntValue>)Parameters["VelocityBoundsStartIndex"]; }
107    }
108    public IValueLookupParameter<IntValue> VelocityBoundsEndIndexParameter {
109      get { return (IValueLookupParameter<IntValue>)Parameters["VelocityBoundsEndIndex"]; }
110    }
[5560]111    #endregion
112
[5866]113    #endregion
114
[5560]115    #region Parameter values
[7073]116    private DoubleValue SwarmBestQuality {
117      get { return SwarmBestQualityParameter.ActualValue; }
118      set { SwarmBestQualityParameter.ActualValue = value; }
[5560]119    }
[5643]120    private RealVector BestRealVector {
121      get { return BestRealVectorParameter.ActualValue; }
122      set { BestRealVectorParameter.ActualValue = value; }
[5560]123    }
[5561]124    private ItemArray<DoubleValue> Quality {
125      get { return QualityParameter.ActualValue; }
[5560]126    }
[5561]127    private ItemArray<DoubleValue> PersonalBestQuality {
128      get { return PersonalBestQualityParameter.ActualValue; }
[5568]129      set { PersonalBestQualityParameter.ActualValue = value; }
[5561]130    }
[5568]131    private ItemArray<DoubleValue> NeighborBestQuality {
132      get { return NeighborBestQualityParameter.ActualValue; }
133      set { NeighborBestQualityParameter.ActualValue = value; }
[5561]134    }
135    private ItemArray<RealVector> RealVector {
[5560]136      get { return RealVectorParameter.ActualValue; }
137    }
[5561]138    private ItemArray<RealVector> PersonalBest {
[5560]139      get { return PersonalBestParameter.ActualValue; }
140      set { PersonalBestParameter.ActualValue = value; }
141    }
[5568]142    private ItemArray<RealVector> NeighborBest {
143      get { return NeighborBestParameter.ActualValue; }
144      set { NeighborBestParameter.ActualValue = value; }
[5560]145    }
146    private bool Maximization {
147      get { return MaximizationParameter.ActualValue.Value; }
148    }
[5561]149    private ItemArray<IntArray> Neighbors {
150      get { return NeighborsParameter.ActualValue; }
151    }
[5568]152    private DoubleMatrix VelocityBounds {
153      get { return VelocityBoundsParameter.ActualValue; }
154    }
[5866]155    private DoubleMatrix CurrentVelocityBounds {
156      get { return CurrentVelocityBoundsParameter.ActualValue; }
157      set { CurrentVelocityBoundsParameter.ActualValue = value; }
158    }
159    private DoubleValue VelocityBoundsScale {
160      get { return VelocityBoundsScaleParameter.ActualValue; }
161      set { VelocityBoundsScaleParameter.ActualValue = value; }
162    }
163    private DoubleValue VelocityBoundsStartValue {
164      get { return VelocityBoundsStartValueParameter.ActualValue; }
165    }
[8121]166    public IDiscreteDoubleValueModifier VelocityBoundsScalingOperator {
[5866]167      get { return VelocityBoundsScalingOperatorParameter.Value; }
[8121]168      set { VelocityBoundsScalingOperatorParameter.Value = value; }
[5866]169    }
170    private ResultCollection Results {
171      get { return ResultsParameter.ActualValue; }
172    }
[5560]173    #endregion
174
175    #region Construction & Cloning
176
177    [StorableConstructor]
[17097]178    private RealVectorSwarmUpdater(StorableConstructorFlag _) : base(_) { }
[5866]179    private RealVectorSwarmUpdater(RealVectorSwarmUpdater original, Cloner cloner)
180      : base(original, cloner) {
181      ResultsCollector = cloner.Clone(original.ResultsCollector);
182    }
[5560]183    public RealVectorSwarmUpdater()
184      : base() {
[7073]185      Parameters.Add(new LookupParameter<DoubleValue>("SwarmBestQuality", "Swarm's best quality."));
186      Parameters.Add(new LookupParameter<RealVector>("BestRealVector", "Global best particle position."));
187      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "Particles' qualities."));
188      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("PersonalBestQuality", "Particles' personal best qualities."));
189      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("NeighborBestQuality", "Best neighbor particles' qualities."));
190      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("RealVector", "Particles' positions."));
191      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("PersonalBest", "Particles' personal best positions."));
192      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("NeighborBest", "Neighborhood (or global in case of totally connected neighborhood) best particle positions."));
[5561]193      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
[5568]194      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
[5866]195      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("VelocityBounds", "Maximum velocity for each dimension.", new DoubleMatrix(new double[,] { { -1, 1 } })));
196      Parameters.Add(new LookupParameter<DoubleMatrix>("CurrentVelocityBounds", "Current value of velocity bounds."));
197      Parameters.Add(new LookupParameter<ResultCollection>("Results", "Results"));
198
199      #region Velocity Bounds Updating
200      Parameters.Add(new LookupParameter<DoubleValue>("VelocityBoundsScale", "Scale parameter."));
201      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("VelocityBoundsScalingOperator", "Modifies the value"));
202      Parameters.Add(new ValueLookupParameter<DoubleValue>("VelocityBoundsStartValue", "The start value of 'Value'.", new DoubleValue(1)));
203      Parameters.Add(new ValueLookupParameter<DoubleValue>("VelocityBoundsEndValue", "The end value of 'Value'.", new DoubleValue(1E-10)));
[7745]204      Parameters.Add(new LookupParameter<IntValue>("VelocityBoundsIndex", "The current index.", "Iterations"));
[5866]205      Parameters.Add(new ValueLookupParameter<IntValue>("VelocityBoundsStartIndex", "The start index at which to start modifying 'Value'.", new IntValue(0)));
206      Parameters.Add(new ValueLookupParameter<IntValue>("VelocityBoundsEndIndex", "The end index by which 'Value' should have reached 'EndValue'.", "MaxIterations"));
207      VelocityBoundsStartIndexParameter.Hidden = true;
208      VelocityBoundsEndIndexParameter.Hidden = true;
209      #endregion
210
211      Initialize();
[5905]212      RegisterEvents();
[5560]213    }
214
215    public override IDeepCloneable Clone(Cloner cloner) {
216      return new RealVectorSwarmUpdater(this, cloner);
217    }
218
219    #endregion
220
[5905]221    [StorableHook(HookType.AfterDeserialization)]
[7073]222    private void AfterDeserialization() {
223      if (!Parameters.ContainsKey("SwarmBestQuality")) {
[7074]224        ILookupParameter<DoubleValue> oldBestQualityParameter = Parameters["BestQuality"] as ILookupParameter<DoubleValue>;
[7073]225        Parameters.Add(new LookupParameter<DoubleValue>("SwarmBestQuality", "Swarm's best quality."));
[7074]226        if (oldBestQualityParameter.ActualName != oldBestQualityParameter.Name)
227          SwarmBestQualityParameter.ActualName = oldBestQualityParameter.ActualName;
[7073]228        Parameters.Remove("BestQuality");
229      }
230      RegisterEvents();
231    }
232
[5905]233    private void RegisterEvents() {
234      VelocityBoundsStartValueParameter.ValueChanged += new EventHandler(VelocityBoundsStartValueParameter_ValueChanged);
235      VelocityBoundsStartValueParameter.Value.ValueChanged += new EventHandler(VelocityBoundsStartValueParameter_Value_ValueChanged);
236    }
237
238    void VelocityBoundsStartValueParameter_Value_ValueChanged(object sender, EventArgs e) {
[12005]239      UpdateVelocityBoundsParamater();
[5911]240    }
241
242    void UpdateVelocityBoundsParamater() {
[5905]243      if (VelocityBoundsParameter.Value == null) {
244        VelocityBoundsParameter.Value = new DoubleMatrix(1, 2);
245      } else if (VelocityBoundsParameter.Value.Columns != 2) {
246        VelocityBoundsParameter.Value = new DoubleMatrix(VelocityBoundsParameter.Value.Rows, 2);
247      }
248      if (VelocityBoundsStartValueParameter.Value != null) {
249        DoubleMatrix matrix = VelocityBoundsParameter.Value;
250        for (int i = 0; i < matrix.Rows; i++) {
251          matrix[i, 0] = (-1) * VelocityBoundsStartValueParameter.Value.Value;
252          matrix[i, 1] = VelocityBoundsStartValueParameter.Value.Value;
253        }
254      }
255    }
256
257    void VelocityBoundsStartValueParameter_ValueChanged(object sender, EventArgs e) {
258      if (VelocityBoundsStartValueParameter.Value != null) {
259        VelocityBoundsStartValueParameter.Value.ValueChanged += new EventHandler(VelocityBoundsStartValueParameter_Value_ValueChanged);
260      }
[12005]261      UpdateVelocityBoundsParamater();
[5905]262    }
263
[5866]264    private void Initialize() {
265      ResultsCollector = new ResultsCollector();
266      ResultsCollector.CollectedValues.Add(CurrentVelocityBoundsParameter);
267      ResultsCollector.CollectedValues.Add(VelocityBoundsParameter);
268
269      foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>()) {
270        VelocityBoundsScalingOperatorParameter.ValidValues.Add(op);
271        op.ValueParameter.ActualName = VelocityBoundsScaleParameter.Name;
272        op.StartValueParameter.ActualName = VelocityBoundsStartValueParameter.Name;
273        op.EndValueParameter.ActualName = VelocityBoundsEndValueParameter.Name;
274        op.IndexParameter.ActualName = VelocityBoundsIndexParameter.Name;
275        op.StartIndexParameter.ActualName = VelocityBoundsStartIndexParameter.Name;
276        op.EndIndexParameter.ActualName = VelocityBoundsEndIndexParameter.Name;
277      }
278      VelocityBoundsScalingOperatorParameter.Value = null;
279    }
280
[5560]281    public override IOperation Apply() {
[5592]282      UpdateGlobalBest();
283      UpdateNeighborBest();
284      UpdatePersonalBest();
285      return UpdateVelocityBounds();
[5561]286    }
287
[5592]288    private void UpdateGlobalBest() {
[7073]289      if (SwarmBestQuality == null)
290        SwarmBestQuality = new DoubleValue();
291      SwarmBestQuality.Value = Maximization ? Quality.Max(v => v.Value) : Quality.Min(v => v.Value);
292      BestRealVector = (RealVector)RealVector[Quality.FindIndex(v => v.Value == SwarmBestQuality.Value)].Clone();
[5561]293    }
294
[5592]295    private void UpdateNeighborBest() {
296      if (Neighbors.Length > 0) {
297        var neighborBest = new ItemArray<RealVector>(Neighbors.Length);
298        var neighborBestQuality = new ItemArray<DoubleValue>(Neighbors.Length);
[5561]299        for (int n = 0; n < Neighbors.Length; n++) {
300          var pairs = Quality.Zip(RealVector, (q, p) => new { Quality = q, Point = p })
301            .Where((p, i) => i == n || Neighbors[n].Contains(i));
[5592]302          var bestNeighbor = Maximization ?
303            pairs.OrderByDescending(p => p.Quality.Value).First() :
304            pairs.OrderBy(p => p.Quality.Value).First();
305          neighborBest[n] = bestNeighbor.Point;
306          neighborBestQuality[n] = bestNeighbor.Quality;
[5560]307        }
[5592]308        NeighborBest = neighborBest;
309        NeighborBestQuality = neighborBestQuality;
[5560]310      }
311    }
312
[5592]313    private void UpdatePersonalBest() {
314      if (PersonalBestQuality.Length == 0)
[5568]315        PersonalBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
[5561]316      for (int i = 0; i < RealVector.Length; i++) {
317        if (Maximization && Quality[i].Value > PersonalBestQuality[i].Value ||
318          !Maximization && Quality[i].Value < PersonalBestQuality[i].Value) {
319          PersonalBestQuality[i].Value = Quality[i].Value;
320          PersonalBest[i] = RealVector[i];
[5568]321        }
322      }
[5561]323    }
[5592]324
325    private IOperation UpdateVelocityBounds() {
[5866]326      if (CurrentVelocityBounds == null)
327        CurrentVelocityBounds = (DoubleMatrix)VelocityBounds.Clone();
328
329      if (VelocityBoundsScalingOperator == null)
330        return new OperationCollection() {
331          ExecutionContext.CreateChildOperation(ResultsCollector),       
332          base.Apply()
[5592]333        };
[5866]334
335      DoubleMatrix matrix = CurrentVelocityBounds;
336      if (VelocityBoundsScale == null && VelocityBoundsStartValue != null) {
337        VelocityBoundsScale = new DoubleValue(VelocityBoundsStartValue.Value);
338      }
339      for (int i = 0; i < matrix.Rows; i++) {
340        for (int j = 0; j < matrix.Columns; j++) {
341          if (matrix[i, j] >= 0) {
342            matrix[i, j] = VelocityBoundsScale.Value;
343          } else {
344            matrix[i, j] = (-1) * VelocityBoundsScale.Value;
345          }
346        }
347      }
348
349      return new OperationCollection() {
350        ExecutionContext.CreateChildOperation(ResultsCollector),
351        ExecutionContext.CreateChildOperation(VelocityBoundsScalingOperator),       
352        base.Apply()
353      };
[5592]354    }
[5560]355  }
356}
Note: See TracBrowser for help on using the repository browser.