source: branches/2994-AutoDiffForIntervals/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSO2011ParticleUpdater.cs @ 17209

Last change on this file since 17209 was 17209, checked in by gkronber, 5 weeks ago

#2994: merged r17132:17198 from trunk to branch

File size: 5.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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 HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HEAL.Attic;
27using HeuristicLab.Random;
28
29namespace HeuristicLab.Encodings.RealVectorEncoding {
30  [Item("SPSO 2011 Particle Updater", "Updates the particle's position according to the formulae described in SPSO 2011.")]
31  [StorableType("C680E305-159C-4A76-83E5-53982B583F9B")]
32  public sealed class SPSO2011ParticleUpdater : SPSOParticleUpdater {
33    #region Construction & Cloning
34    [StorableConstructor]
35    private SPSO2011ParticleUpdater(StorableConstructorFlag _) : base(_) { }
36    private SPSO2011ParticleUpdater(SPSO2011ParticleUpdater original, Cloner cloner) : base(original, cloner) { }
37    public SPSO2011ParticleUpdater() : base() { }
38    public override IDeepCloneable Clone(Cloner cloner) {
39      return new SPSO2011ParticleUpdater(this, cloner);
40    }
41    #endregion
42   
43    public static void UpdateVelocity(IRandom random, RealVector velocity, RealVector position, RealVector personalBest, RealVector neighborBest, double inertia = 0.721, double personalBestAttraction = 1.193, double neighborBestAttraction = 1.193, double maxVelocity = double.MaxValue) {
44      var gravity = new double[velocity.Length];
45      var direction = new RealVector(velocity.Length);
46      var radius = 0.0;
47
48      var nd = new NormalDistributedRandom(random, 0, 1);
49
50      for (int i = 0; i < velocity.Length; i++) {
51        var g_id = (personalBestAttraction * personalBest[i]
52          + neighborBestAttraction * neighborBest[i]
53          - position[i] * (neighborBestAttraction + personalBestAttraction)) / 3.0;
54        // center of the hyper-sphere
55        gravity[i] = g_id + position[i];
56        // a random direction vector uniform over the surface of hyper-sphere, see http://mathworld.wolfram.com/HyperspherePointPicking.html
57        direction[i] = nd.NextDouble();
58        radius += g_id * g_id;
59      }
60
61      // randomly choose a radius within the hyper-sphere
62      radius = random.NextDouble() * Math.Sqrt(radius);
63
64      // unitscale is used to rescale the random direction vector to unit length, resp. length of the radius
65      var unitscale = Math.Sqrt(direction.DotProduct(direction));
66      if (unitscale > 0) {
67        for (var i = 0; i < velocity.Length; i++) {
68          var sampledPos = gravity[i] + direction[i] * radius / unitscale;
69          velocity[i] = velocity[i] * inertia + sampledPos - position[i];
70        }
71      }
72
73      var speed = Math.Sqrt(velocity.DotProduct(velocity));
74      if (speed > maxVelocity) {
75        for (var i = 0; i < velocity.Length; i++) {
76          velocity[i] *= maxVelocity / speed;
77        }
78      }
79    }
80
81    public static void UpdatePosition(DoubleMatrix bounds, RealVector velocity, RealVector position) {
82      for (int i = 0; i < velocity.Length; i++) {
83        position[i] += velocity[i];
84      }
85
86      for (int i = 0; i < position.Length; i++) {
87        double min = bounds[i % bounds.Rows, 0];
88        double max = bounds[i % bounds.Rows, 1];
89        if (position[i] < min) {
90          position[i] = min;
91          velocity[i] = -0.5 * velocity[i];
92        }
93        if (position[i] > max) {
94          position[i] = max;
95          velocity[i] = -0.5 * velocity[i];
96        }
97      }
98    }
99
100    public override IOperation Apply() {
101      var random = RandomParameter.ActualValue;
102      var velocity = VelocityParameter.ActualValue;
103      var maxVelocity = CurrentMaxVelocityParameter.ActualValue.Value;
104      var position = RealVectorParameter.ActualValue;
105      var bounds = BoundsParameter.ActualValue;
106
107      var inertia = CurrentInertiaParameter.ActualValue.Value;
108      var personalBest = PersonalBestParameter.ActualValue;
109      var personalBestAttraction = PersonalBestAttractionParameter.ActualValue.Value;
110      var neighborBest = NeighborBestParameter.ActualValue;
111      var neighborBestAttraction = NeighborBestAttractionParameter.ActualValue.Value;
112
113      UpdateVelocity(random, velocity, position, personalBest, neighborBest, inertia, personalBestAttraction, neighborBestAttraction, maxVelocity);
114      UpdatePosition(bounds, velocity, position);
115
116      return base.Apply();
117    }
118  }
119}
Note: See TracBrowser for help on using the repository browser.