Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/30/17 21:57:38 (7 years ago)
Author:
abeham
Message:

#2797:

  • Recreated backwards compatibility by readding old operators and renaming new operators to SPSO*
    • If a previously configured algorithm is run again, the same results should be obtained
  • Set all old operators to internal, NonDiscoverableType, and Obsolete (they are also not fixed, e.g. PersonalBest update remains flawed)
  • Added SPSO 2007 velocity initializer and let users choose in SPSOParticleCreator
  • Changed description of PSO
  • Updated sample
File:
1 edited

Legend:

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

    r15096 r15102  
    2121
    2222using System;
    23 using System.Collections.Generic;
    2423using System.Linq;
    2524using HeuristicLab.Common;
     
    3635  [Item("RealVectorSwarmUpdater", "Updates personal best point and quality as well as global best point and quality.")]
    3736  [StorableClass]
    38   public sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater, ISingleObjectiveOperator {
     37  [NonDiscoverableType]
     38  [Obsolete("Use SPSOSwarmUpdater")]
     39  internal sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater, ISingleObjectiveOperator {
    3940
    4041    [Storable]
     
    7677      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
    7778    }
    78     public IValueLookupParameter<DoubleValue> MaxVelocityParameter {
    79       get { return (ValueLookupParameter<DoubleValue>)Parameters["MaxVelocity"]; }
    80     }
    81     public ILookupParameter<DoubleValue> CurrentMaxVelocityParameter {
    82       get { return (ILookupParameter<DoubleValue>)Parameters["CurrentMaxVelocity"]; }
     79    public IValueLookupParameter<DoubleMatrix> VelocityBoundsParameter {
     80      get { return (ValueLookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
     81    }
     82    public ILookupParameter<DoubleMatrix> CurrentVelocityBoundsParameter {
     83      get { return (ILookupParameter<DoubleMatrix>)Parameters["CurrentVelocityBounds"]; }
    8384    }
    8485    public LookupParameter<ResultCollection> ResultsParameter {
     
    8687    }
    8788
    88     #region Max Velocity Updating
    89     public IConstrainedValueParameter<IDiscreteDoubleValueModifier> MaxVelocityScalingOperatorParameter {
    90       get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["MaxVelocityScalingOperator"]; }
    91     }
    92     public IValueLookupParameter<DoubleValue> FinalMaxVelocityParameter {
    93       get { return (IValueLookupParameter<DoubleValue>)Parameters["FinalMaxVelocity"]; }
    94     }
    95     public ILookupParameter<IntValue> MaxVelocityIndexParameter {
    96       get { return (ILookupParameter<IntValue>)Parameters["MaxVelocityIndex"]; }
    97     }
    98     public IValueLookupParameter<IntValue> MaxVelocityStartIndexParameter {
    99       get { return (IValueLookupParameter<IntValue>)Parameters["MaxVelocityStartIndex"]; }
    100     }
    101     public IValueLookupParameter<IntValue> MaxVelocityEndIndexParameter {
    102       get { return (IValueLookupParameter<IntValue>)Parameters["MaxVelocityEndIndex"]; }
     89    #region Velocity Bounds Updating
     90    public ILookupParameter<DoubleValue> VelocityBoundsScaleParameter {
     91      get { return (ILookupParameter<DoubleValue>)Parameters["VelocityBoundsScale"]; }
     92    }
     93    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> VelocityBoundsScalingOperatorParameter {
     94      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["VelocityBoundsScalingOperator"]; }
     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"]; }
    103110    }
    104111    #endregion
    105112
    106113    #endregion
    107    
     114
     115    #region Parameter values
     116    private DoubleValue SwarmBestQuality {
     117      get { return SwarmBestQualityParameter.ActualValue; }
     118      set { SwarmBestQualityParameter.ActualValue = value; }
     119    }
     120    private RealVector BestRealVector {
     121      get { return BestRealVectorParameter.ActualValue; }
     122      set { BestRealVectorParameter.ActualValue = value; }
     123    }
     124    private ItemArray<DoubleValue> Quality {
     125      get { return QualityParameter.ActualValue; }
     126    }
     127    private ItemArray<DoubleValue> PersonalBestQuality {
     128      get { return PersonalBestQualityParameter.ActualValue; }
     129      set { PersonalBestQualityParameter.ActualValue = value; }
     130    }
     131    private ItemArray<DoubleValue> NeighborBestQuality {
     132      get { return NeighborBestQualityParameter.ActualValue; }
     133      set { NeighborBestQualityParameter.ActualValue = value; }
     134    }
     135    private ItemArray<RealVector> RealVector {
     136      get { return RealVectorParameter.ActualValue; }
     137    }
     138    private ItemArray<RealVector> PersonalBest {
     139      get { return PersonalBestParameter.ActualValue; }
     140      set { PersonalBestParameter.ActualValue = value; }
     141    }
     142    private ItemArray<RealVector> NeighborBest {
     143      get { return NeighborBestParameter.ActualValue; }
     144      set { NeighborBestParameter.ActualValue = value; }
     145    }
     146    private bool Maximization {
     147      get { return MaximizationParameter.ActualValue.Value; }
     148    }
     149    private ItemArray<IntArray> Neighbors {
     150      get { return NeighborsParameter.ActualValue; }
     151    }
     152    private DoubleMatrix VelocityBounds {
     153      get { return VelocityBoundsParameter.ActualValue; }
     154    }
     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    }
     166    public IDiscreteDoubleValueModifier VelocityBoundsScalingOperator {
     167      get { return VelocityBoundsScalingOperatorParameter.Value; }
     168      set { VelocityBoundsScalingOperatorParameter.Value = value; }
     169    }
     170    private ResultCollection Results {
     171      get { return ResultsParameter.ActualValue; }
     172    }
     173    #endregion
     174
    108175    #region Construction & Cloning
    109176
     
    126193      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
    127194      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
    128       Parameters.Add(new ValueLookupParameter<DoubleValue>("MaxVelocity", "Speed limit for each particle.", new DoubleValue(1000000)));
    129       Parameters.Add(new LookupParameter<DoubleValue>("CurrentMaxVelocity", "Current value of the speed limit."));
     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."));
    130197      Parameters.Add(new LookupParameter<ResultCollection>("Results", "Results"));
    131198
    132199      #region Velocity Bounds Updating
    133       Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("MaxVelocityScalingOperator", "Modifies the value"));
    134       Parameters.Add(new ValueLookupParameter<DoubleValue>("FinalMaxVelocity", "The value of maximum velocity if PSO has reached maximum iterations.", new DoubleValue(1E-10)));
    135       Parameters.Add(new LookupParameter<IntValue>("MaxVelocityIndex", "The current index.", "Iterations"));
    136       Parameters.Add(new ValueLookupParameter<IntValue>("MaxVelocityStartIndex", "The start index at which to start modifying 'Value'.", new IntValue(0)));
    137       Parameters.Add(new ValueLookupParameter<IntValue>("MaxVelocityEndIndex", "The end index by which 'Value' should have reached 'EndValue'.", "MaxIterations"));
    138       MaxVelocityStartIndexParameter.Hidden = true;
    139       MaxVelocityEndIndexParameter.Hidden = true;
     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)));
     204      Parameters.Add(new LookupParameter<IntValue>("VelocityBoundsIndex", "The current index.", "Iterations"));
     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;
    140209      #endregion
    141210
    142211      Initialize();
     212      RegisterEvents();
    143213    }
    144214
     
    158228        Parameters.Remove("BestQuality");
    159229      }
    160     }
     230      RegisterEvents();
     231    }
     232
     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) {
     239      UpdateVelocityBoundsParamater();
     240    }
     241
     242    void UpdateVelocityBoundsParamater() {
     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      }
     261      UpdateVelocityBoundsParamater();
     262    }
     263
    161264    private void Initialize() {
    162265      ResultsCollector = new ResultsCollector();
    163       ResultsCollector.CollectedValues.Add(CurrentMaxVelocityParameter);
    164       ResultsCollector.CollectedValues.Add(MaxVelocityParameter);
     266      ResultsCollector.CollectedValues.Add(CurrentVelocityBoundsParameter);
     267      ResultsCollector.CollectedValues.Add(VelocityBoundsParameter);
    165268
    166269      foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>()) {
    167         MaxVelocityScalingOperatorParameter.ValidValues.Add(op);
    168         op.ValueParameter.ActualName = CurrentMaxVelocityParameter.Name;
    169         op.StartValueParameter.ActualName = MaxVelocityParameter.Name;
    170         op.EndValueParameter.ActualName = FinalMaxVelocityParameter.Name;
    171         op.IndexParameter.ActualName = MaxVelocityIndexParameter.Name;
    172         op.StartIndexParameter.ActualName = MaxVelocityStartIndexParameter.Name;
    173         op.EndIndexParameter.ActualName = MaxVelocityEndIndexParameter.Name;
    174       }
    175       MaxVelocityScalingOperatorParameter.Value = null;
     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;
    176279    }
    177280
    178281    public override IOperation Apply() {
    179       var max = MaximizationParameter.ActualValue.Value;
    180       // Update of the personal bests
    181       var points = RealVectorParameter.ActualValue;
    182       var qualities = QualityParameter.ActualValue;
    183       var particles = points.Select((p, i) => new { Particle = p, Index = i })
    184         .Zip(qualities, (p, q) => Tuple.Create(p.Index, p.Particle, q.Value)).ToList();
    185       UpdatePersonalBest(max, particles);
    186 
    187       // SPSO: update of the neighbor bests from the personal bests
    188       var personalBestPoints = PersonalBestParameter.ActualValue;
    189       var personalBestQualities = PersonalBestQualityParameter.ActualValue;
    190       particles = personalBestPoints.Select((p, i) => new { Particle = p, Index = i })
    191         .Zip(personalBestQualities, (p, q) => Tuple.Create(p.Index, p.Particle, q.Value)).ToList();
    192       UpdateNeighborBest(max, particles);
    193 
    194       var next = new OperationCollection() { base.Apply() };
    195       next.Insert(0, ExecutionContext.CreateChildOperation(ResultsCollector));
    196       if (MaxVelocityScalingOperatorParameter.Value != null) {
    197         next.Insert(0, ExecutionContext.CreateChildOperation(MaxVelocityScalingOperatorParameter.Value));
    198       } else CurrentMaxVelocityParameter.ActualValue = new DoubleValue(MaxVelocityParameter.ActualValue.Value);
    199       return next;
    200     }
    201 
    202     private void UpdateNeighborBest(bool maximization, IList<Tuple<int, RealVector, double>> particles) {
    203       var neighbors = NeighborsParameter.ActualValue;
    204       if (neighbors.Length > 0) {
    205         var neighborBest = new ItemArray<RealVector>(neighbors.Length);
    206         var neighborBestQuality = new ItemArray<DoubleValue>(neighbors.Length);
    207         for (int n = 0; n < neighbors.Length; n++) {
    208           var pairs = particles.Where(x => x.Item1 == n || neighbors[n].Contains(x.Item1));
    209           var bestNeighbor = (maximization ? pairs.MaxItems(p => p.Item3)
    210                                            : pairs.MinItems(p => p.Item3)).First();
    211           neighborBest[n] = bestNeighbor.Item2;
    212           neighborBestQuality[n] = new DoubleValue(bestNeighbor.Item3);
     282      UpdateGlobalBest();
     283      UpdateNeighborBest();
     284      UpdatePersonalBest();
     285      return UpdateVelocityBounds();
     286    }
     287
     288    private void UpdateGlobalBest() {
     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();
     293    }
     294
     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);
     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));
     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;
    213307        }
    214         NeighborBestParameter.ActualValue = neighborBest;
    215         NeighborBestQualityParameter.ActualValue = neighborBestQuality;
    216       } else {
    217         // Neighbor best = Global best
    218         var best = maximization ? particles.MaxItems(x => x.Item3).First() : particles.MinItems(x => x.Item3).First();
    219         NeighborBestParameter.ActualValue = new ItemArray<RealVector>(particles.Select(x => best.Item2));
    220         NeighborBestQualityParameter.ActualValue = new ItemArray<DoubleValue>(particles.Select(x => new DoubleValue(best.Item3)));
    221       }
    222     }
    223 
    224     private void UpdatePersonalBest(bool maximization, IList<Tuple<int, RealVector, double>> particles) {
    225       var personalBest = PersonalBestParameter.ActualValue;
    226       var personalBestQuality = PersonalBestQualityParameter.ActualValue;
    227 
    228       if (personalBestQuality.Length == 0) {
    229         personalBestQuality = new ItemArray<DoubleValue>(particles.Select(x => new DoubleValue(x.Item3)));
    230         PersonalBestQualityParameter.ActualValue = personalBestQuality;
    231       }
    232       foreach (var p in particles) {
    233         if (maximization && p.Item3 > personalBestQuality[p.Item1].Value ||
    234           !maximization && p.Item3 < personalBestQuality[p.Item1].Value) {
    235           personalBestQuality[p.Item1].Value = p.Item3;
    236           personalBest[p.Item1] = (RealVector)p.Item2.Clone();
     308        NeighborBest = neighborBest;
     309        NeighborBestQuality = neighborBestQuality;
     310      }
     311    }
     312
     313    private void UpdatePersonalBest() {
     314      if (PersonalBestQuality.Length == 0)
     315        PersonalBestQuality = (ItemArray<DoubleValue>)Quality.Clone();
     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];
    237321        }
    238322      }
    239       PersonalBestParameter.ActualValue = personalBest;
     323    }
     324
     325    private IOperation UpdateVelocityBounds() {
     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()
     333        };
     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      };
    240354    }
    241355  }
Note: See TracChangeset for help on using the changeset viewer.