Changeset 15102 for trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs
- Timestamp:
- 06/30/17 21:57:38 (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/RealVectorSwarmUpdater.cs
r15096 r15102 21 21 22 22 using System; 23 using System.Collections.Generic;24 23 using System.Linq; 25 24 using HeuristicLab.Common; … … 36 35 [Item("RealVectorSwarmUpdater", "Updates personal best point and quality as well as global best point and quality.")] 37 36 [StorableClass] 38 public sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater, ISingleObjectiveOperator { 37 [NonDiscoverableType] 38 [Obsolete("Use SPSOSwarmUpdater")] 39 internal sealed class RealVectorSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater, ISingleObjectiveOperator { 39 40 40 41 [Storable] … … 76 77 get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; } 77 78 } 78 public IValueLookupParameter<Double Value> MaxVelocityParameter {79 get { return (ValueLookupParameter<Double Value>)Parameters["MaxVelocity"]; }80 } 81 public ILookupParameter<Double Value> CurrentMaxVelocityParameter {82 get { return (ILookupParameter<Double Value>)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"]; } 83 84 } 84 85 public LookupParameter<ResultCollection> ResultsParameter { … … 86 87 } 87 88 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"]; } 103 110 } 104 111 #endregion 105 112 106 113 #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 108 175 #region Construction & Cloning 109 176 … … 126 193 Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle.")); 127 194 Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false.")); 128 Parameters.Add(new ValueLookupParameter<Double Value>("MaxVelocity", "Speed limit for each particle.", new DoubleValue(1000000)));129 Parameters.Add(new LookupParameter<Double Value>("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.")); 130 197 Parameters.Add(new LookupParameter<ResultCollection>("Results", "Results")); 131 198 132 199 #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; 140 209 #endregion 141 210 142 211 Initialize(); 212 RegisterEvents(); 143 213 } 144 214 … … 158 228 Parameters.Remove("BestQuality"); 159 229 } 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 161 264 private void Initialize() { 162 265 ResultsCollector = new ResultsCollector(); 163 ResultsCollector.CollectedValues.Add(Current MaxVelocityParameter);164 ResultsCollector.CollectedValues.Add( MaxVelocityParameter);266 ResultsCollector.CollectedValues.Add(CurrentVelocityBoundsParameter); 267 ResultsCollector.CollectedValues.Add(VelocityBoundsParameter); 165 268 166 269 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; 176 279 } 177 280 178 281 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; 213 307 } 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]; 237 321 } 238 322 } 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 }; 240 354 } 241 355 }
Note: See TracChangeset
for help on using the changeset viewer.