Changeset 15071


Ignore:
Timestamp:
06/27/17 14:23:30 (7 weeks ago)
Author:
abeham
Message:

#2748: fixed personal best tracking in RealVectorSwarmUpdater

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs

    r14185 r15071  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.Linq;
    2425using HeuristicLab.Common;
     
    110111
    111112    #endregion
    112 
    113     #region Parameter values
    114     private DoubleValue SwarmBestQuality {
    115       get { return SwarmBestQualityParameter.ActualValue; }
    116       set { SwarmBestQualityParameter.ActualValue = value; }
    117     }
    118     private RealVector BestRealVector {
    119       get { return BestRealVectorParameter.ActualValue; }
    120       set { BestRealVectorParameter.ActualValue = value; }
    121     }
    122     private ItemArray<DoubleValue> Quality {
    123       get { return QualityParameter.ActualValue; }
    124     }
    125     private ItemArray<DoubleValue> PersonalBestQuality {
    126       get { return PersonalBestQualityParameter.ActualValue; }
    127       set { PersonalBestQualityParameter.ActualValue = value; }
    128     }
    129     private ItemArray<DoubleValue> NeighborBestQuality {
    130       get { return NeighborBestQualityParameter.ActualValue; }
    131       set { NeighborBestQualityParameter.ActualValue = value; }
    132     }
    133     private ItemArray<RealVector> RealVector {
    134       get { return RealVectorParameter.ActualValue; }
    135     }
    136     private ItemArray<RealVector> PersonalBest {
    137       get { return PersonalBestParameter.ActualValue; }
    138       set { PersonalBestParameter.ActualValue = value; }
    139     }
    140     private ItemArray<RealVector> NeighborBest {
    141       get { return NeighborBestParameter.ActualValue; }
    142       set { NeighborBestParameter.ActualValue = value; }
    143     }
    144     private bool Maximization {
    145       get { return MaximizationParameter.ActualValue.Value; }
    146     }
    147     private ItemArray<IntArray> Neighbors {
    148       get { return NeighborsParameter.ActualValue; }
    149     }
    150     private DoubleMatrix VelocityBounds {
    151       get { return VelocityBoundsParameter.ActualValue; }
    152     }
    153     private DoubleMatrix CurrentVelocityBounds {
    154       get { return CurrentVelocityBoundsParameter.ActualValue; }
    155       set { CurrentVelocityBoundsParameter.ActualValue = value; }
    156     }
    157     private DoubleValue VelocityBoundsScale {
    158       get { return VelocityBoundsScaleParameter.ActualValue; }
    159       set { VelocityBoundsScaleParameter.ActualValue = value; }
    160     }
    161     private DoubleValue VelocityBoundsStartValue {
    162       get { return VelocityBoundsStartValueParameter.ActualValue; }
    163     }
    164     public IDiscreteDoubleValueModifier VelocityBoundsScalingOperator {
    165       get { return VelocityBoundsScalingOperatorParameter.Value; }
    166       set { VelocityBoundsScalingOperatorParameter.Value = value; }
    167     }
    168     private ResultCollection Results {
    169       get { return ResultsParameter.ActualValue; }
    170     }
    171     #endregion
    172 
     113   
    173114    #region Construction & Cloning
    174115
     
    278219
    279220    public override IOperation Apply() {
    280       UpdateGlobalBest();
    281       UpdateNeighborBest();
    282       UpdatePersonalBest();
     221      var max = MaximizationParameter.ActualValue.Value;
     222      var points = RealVectorParameter.ActualValue;
     223      var qualities = QualityParameter.ActualValue;
     224      var particles = points.Select((p, i) => new { Particle = p, Index = i })
     225        .Zip(qualities, (p, q) => Tuple.Create(p.Index, p.Particle, q.Value)).ToList();
     226      UpdateGlobalBest(max, particles);
     227      UpdateNeighborBest(max, particles);
     228      UpdatePersonalBest(max, particles);
    283229      return UpdateVelocityBounds();
    284230    }
    285231
    286     private void UpdateGlobalBest() {
    287       if (SwarmBestQuality == null)
    288         SwarmBestQuality = new DoubleValue();
    289       SwarmBestQuality.Value = Maximization ? Quality.Max(v => v.Value) : Quality.Min(v => v.Value);
    290       BestRealVector = (RealVector)RealVector[Quality.FindIndex(v => v.Value == SwarmBestQuality.Value)].Clone();
    291     }
    292 
    293     private void UpdateNeighborBest() {
    294       if (Neighbors.Length > 0) {
    295         var neighborBest = new ItemArray<RealVector>(Neighbors.Length);
    296         var neighborBestQuality = new ItemArray<DoubleValue>(Neighbors.Length);
    297         for (int n = 0; n < Neighbors.Length; n++) {
    298           var pairs = Quality.Zip(RealVector, (q, p) => new { Quality = q, Point = p })
    299             .Where((p, i) => i == n || Neighbors[n].Contains(i));
    300           var bestNeighbor = Maximization ?
    301             pairs.OrderByDescending(p => p.Quality.Value).First() :
    302             pairs.OrderBy(p => p.Quality.Value).First();
    303           neighborBest[n] = bestNeighbor.Point;
    304           neighborBestQuality[n] = bestNeighbor.Quality;
     232    private void UpdateGlobalBest(bool maximization, IList<Tuple<int, RealVector, double>> particles) {
     233      var best = maximization ? particles.MaxItems(x => x.Item3).First() : particles.MinItems(x => x.Item3).First();
     234      var bestQuality = SwarmBestQualityParameter.ActualValue;
     235      if (bestQuality == null) {
     236        SwarmBestQualityParameter.ActualValue = new DoubleValue(best.Item3);
     237      } else bestQuality.Value = best.Item3;
     238      BestRealVectorParameter.ActualValue = (RealVector)best.Item2.Clone();
     239    }
     240
     241    private void UpdateNeighborBest(bool maximization, IList<Tuple<int, RealVector, double>> particles) {
     242      var neighbors = NeighborsParameter.ActualValue;
     243      if (neighbors.Length > 0) {
     244        var neighborBest = new ItemArray<RealVector>(neighbors.Length);
     245        var neighborBestQuality = new ItemArray<DoubleValue>(neighbors.Length);
     246        for (int n = 0; n < neighbors.Length; n++) {
     247          var pairs = particles.Where(x => x.Item1 == n || neighbors[n].Contains(x.Item1));
     248          var bestNeighbor = (maximization ? pairs.MaxItems(p => p.Item3)
     249                                           : pairs.MinItems(p => p.Item3)).First();
     250          neighborBest[n] = bestNeighbor.Item2;
     251          neighborBestQuality[n] = new DoubleValue(bestNeighbor.Item3);
    305252        }
    306         NeighborBest = neighborBest;
    307         NeighborBestQuality = neighborBestQuality;
    308       }
    309     }
    310 
    311     private void UpdatePersonalBest() {
    312       if (PersonalBestQuality.Length == 0)
    313         PersonalBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
    314       for (int i = 0; i < RealVector.Length; i++) {
    315         if (Maximization && Quality[i].Value > PersonalBestQuality[i].Value ||
    316           !Maximization && Quality[i].Value < PersonalBestQuality[i].Value) {
    317           PersonalBestQuality[i].Value = Quality[i].Value;
    318           PersonalBest[i] = RealVector[i];
     253        NeighborBestParameter.ActualValue = neighborBest;
     254        NeighborBestQualityParameter.ActualValue = neighborBestQuality;
     255      }
     256    }
     257
     258    private void UpdatePersonalBest(bool maximization, IList<Tuple<int, RealVector, double>> particles) {
     259      var personalBest = PersonalBestParameter.ActualValue;
     260      var personalBestQuality = PersonalBestQualityParameter.ActualValue;
     261
     262      if (personalBestQuality.Length == 0) {
     263        personalBestQuality = new ItemArray<DoubleValue>(particles.Select(x => new DoubleValue(x.Item3)));
     264        PersonalBestQualityParameter.ActualValue = personalBestQuality;
     265      }
     266      foreach (var p in particles) {
     267        if (maximization && p.Item3 > personalBestQuality[p.Item1].Value ||
     268          !maximization && p.Item3 < personalBestQuality[p.Item1].Value) {
     269          personalBestQuality[p.Item1].Value = p.Item3;
     270          personalBest[p.Item1] = p.Item2;
    319271        }
    320272      }
     273      PersonalBestParameter.ActualValue = personalBest;
    321274    }
    322275
    323276    private IOperation UpdateVelocityBounds() {
    324       if (CurrentVelocityBounds == null)
    325         CurrentVelocityBounds = (DoubleMatrix)VelocityBounds.Clone();
    326 
    327       if (VelocityBoundsScalingOperator == null)
     277      var currentVelocityBounds = CurrentVelocityBoundsParameter.ActualValue;
     278
     279      if (currentVelocityBounds == null) {
     280        currentVelocityBounds = (DoubleMatrix)VelocityBoundsParameter.ActualValue.Clone();
     281        CurrentVelocityBoundsParameter.ActualValue = currentVelocityBounds;
     282      }
     283      if (VelocityBoundsScalingOperatorParameter.Value == null)
    328284        return new OperationCollection() {
    329285          ExecutionContext.CreateChildOperation(ResultsCollector),       
     
    331287        };
    332288
    333       DoubleMatrix matrix = CurrentVelocityBounds;
    334       if (VelocityBoundsScale == null && VelocityBoundsStartValue != null) {
    335         VelocityBoundsScale = new DoubleValue(VelocityBoundsStartValue.Value);
    336       }
    337       for (int i = 0; i < matrix.Rows; i++) {
    338         for (int j = 0; j < matrix.Columns; j++) {
    339           if (matrix[i, j] >= 0) {
    340             matrix[i, j] = VelocityBoundsScale.Value;
     289      var velocityBoundsScale = VelocityBoundsScaleParameter.ActualValue;
     290      var velocityBoundsStartValue = VelocityBoundsStartValueParameter.ActualValue;
     291
     292      if (velocityBoundsScale == null && velocityBoundsStartValue != null) {
     293        velocityBoundsScale = new DoubleValue(velocityBoundsStartValue.Value);
     294        VelocityBoundsScaleParameter.ActualValue = velocityBoundsScale;
     295      }
     296      for (int i = 0; i < currentVelocityBounds.Rows; i++) {
     297        for (int j = 0; j < currentVelocityBounds.Columns; j++) {
     298          if (currentVelocityBounds[i, j] >= 0) {
     299            currentVelocityBounds[i, j] = velocityBoundsScale.Value;
    341300          } else {
    342             matrix[i, j] = (-1) * VelocityBoundsScale.Value;
     301            currentVelocityBounds[i, j] = (-1) * velocityBoundsScale.Value;
    343302          }
    344303        }
     
    347306      return new OperationCollection() {
    348307        ExecutionContext.CreateChildOperation(ResultsCollector),
    349         ExecutionContext.CreateChildOperation(VelocityBoundsScalingOperator),       
     308        ExecutionContext.CreateChildOperation(VelocityBoundsScalingOperatorParameter.Value),
    350309        base.Apply()
    351310      };
Note: See TracChangeset for help on using the changeset viewer.