Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/AdaptiveRandomTopologyUpdater.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/AdaptiveRandomTopologyUpdater.cs	(revision 15181)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/AdaptiveRandomTopologyUpdater.cs	(revision 15181)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
+  [Item("SPSO Adaptive Random Topology Updater", "Each unsuccessful iteration the topology initializer is applied again.")]
+  [StorableClass]
+  public sealed class SPSOAdaptiveRandomTopologyUpdater : SingleSuccessorOperator, ITopologyUpdater, ISingleObjectiveOperator {
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    #region Parameters
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> SwarmBestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["SwarmBestQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> PreviousBestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["PreviousBestQuality"]; }
+    }
+    public ILookupParameter<ITopologyInitializer> TopologyInitializerParameter {
+      get { return (ILookupParameter<ITopologyInitializer>)Parameters["TopologyInitializer"]; }
+    }
+    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
+      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
+    }
+    #endregion
+
+    #region Construction & Cloning
+    [StorableConstructor]
+    private SPSOAdaptiveRandomTopologyUpdater(bool deserializing) : base(deserializing) { }
+    private SPSOAdaptiveRandomTopologyUpdater(SPSOAdaptiveRandomTopologyUpdater original, Cloner cloner) : base(original, cloner) { }
+    public SPSOAdaptiveRandomTopologyUpdater()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether the problem is to be maximized or not."));
+      Parameters.Add(new LookupParameter<DoubleValue>("SwarmBestQuality", "The swarm's best quality."));
+      Parameters.Add(new LookupParameter<DoubleValue>("PreviousBestQuality", "The best quality of the previous iteration."));
+      Parameters.Add(new LookupParameter<ITopologyInitializer>("TopologyInitializer", "The topology initializer is called again in case no improvement is made."));
+      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SPSOAdaptiveRandomTopologyUpdater(this, cloner);
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      var swarmBest = SwarmBestQualityParameter.ActualValue;
+      if (swarmBest == null) return base.Apply();
+
+      var previousBest = PreviousBestQualityParameter.ActualValue;
+      if (previousBest == null) {
+        PreviousBestQualityParameter.ActualValue = new DoubleValue(swarmBest.Value);
+        return base.Apply();
+      };
+
+      var successor = new OperationCollection(new[] { base.Apply() });
+      var max = MaximizationParameter.ActualValue.Value;
+      if (max && swarmBest.Value >= previousBest.Value
+        || !max && swarmBest.Value <= previousBest.Value)
+        successor.Insert(0, ExecutionContext.CreateOperation(TopologyInitializerParameter.ActualValue));
+
+      previousBest.Value = swarmBest.Value;
+      return successor;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3.csproj	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3.csproj	(revision 15181)
@@ -113,7 +113,9 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AdaptiveRandomTopologyUpdater.cs" />
     <Compile Include="MultiPSOTopologyUpdater.cs" />
     <Compile Include="ParticleSwarmOptimizationMainLoop.cs" />
     <Compile Include="Plugin.cs" />
+    <Compile Include="SPSORandomTopologyInitializer.cs" />
     <Compile Include="RandomTopologyInitializer.cs" />
     <Compile Include="VonNeumannTopologyInitializer.cs" />
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/MultiPSOTopologyUpdater.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/MultiPSOTopologyUpdater.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/MultiPSOTopologyUpdater.cs	(revision 15181)
@@ -33,5 +33,5 @@
   [Item("Multi PSO Topology Updater", "Splits swarm into NrOfSwarms non-overlapping sub-swarms. Swarms are re-grouped every regroupingPeriod iteration. The operator is implemented as described in Liang, J.J. and Suganthan, P.N 2005. Dynamic multi-swarm particle swarm optimizer. IEEE Swarm Intelligence Symposium, pp. 124-129.")]
   [StorableClass]
-  public sealed class MultiPSOTopologyUpdater : SingleSuccessorOperator, ITopologyUpdater {
+  public sealed class MultiPSOTopologyUpdater : SingleSuccessorOperator, ITopologyUpdater, IStochasticOperator {
 
     public override bool CanChangeName {
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs	(revision 15181)
@@ -177,8 +177,8 @@
       Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
       Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
-      Parameters.Add(new ValueParameter<IntValue>("SwarmSize", "Size of the particle swarm.", new IntValue(20)));
+      Parameters.Add(new ValueParameter<IntValue>("SwarmSize", "Size of the particle swarm.", new IntValue(40)));
       Parameters.Add(new ValueParameter<IntValue>("MaxIterations", "Maximal number of iterations.", new IntValue(1000)));
       Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
-      Parameters.Add(new ValueParameter<DoubleValue>("Inertia", "Inertia weight on a particle's movement (omega).", new DoubleValue(0.8)));
+      Parameters.Add(new ValueParameter<DoubleValue>("Inertia", "Inertia weight on a particle's movement (omega).", new DoubleValue(0.721)));
       Parameters.Add(new ValueParameter<DoubleValue>("PersonalBestAttraction", "Weight for particle's pull towards its personal best soution (phi_p).", new DoubleValue(1)));
       Parameters.Add(new ValueParameter<DoubleValue>("NeighborBestAttraction", "Weight for pull towards the neighborhood best solution or global best solution in case of a totally connected topology (phi_g).", new DoubleValue(1)));
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimizationMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimizationMainLoop.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimizationMainLoop.cs	(revision 15181)
@@ -122,4 +122,5 @@
       Placeholder evaluatorPlaceholder = new Placeholder();
       Placeholder analyzerPlaceholder = new Placeholder();
+      Placeholder analyzer2Placeholder = new Placeholder();
       UniformSubScopesProcessor uniformSubScopeProcessor = new UniformSubScopesProcessor();
       Placeholder particleUpdaterPlaceholder = new Placeholder();
@@ -192,4 +193,8 @@
       conditionalBranch.ConditionParameter.ActualName = "ContinueIteration";
       conditionalBranch.TrueBranch = analyzerPlaceholder;
+      conditionalBranch.FalseBranch = analyzer2Placeholder;
+
+      analyzer2Placeholder.Name = "(Analyzer)";
+      analyzer2Placeholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
       #endregion
     }
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RandomTopologyInitializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RandomTopologyInitializer.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RandomTopologyInitializer.cs	(revision 15181)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
-  [Item("Random Topology Initializer", "Randomly connectes every particle with k other particles.")]
+  [Item("Random Topology Initializer", "Each particle is informed by exactly k+1 distinct other particles (including itself).")]
   [StorableClass]
   public sealed class RandomTopologyInitializer : TopologyInitializer, IStochasticOperator {
@@ -65,5 +65,6 @@
         var numbers = Enumerable.Range(0, swarmSize).ToList();
         numbers.RemoveAt(i);
-        var selectedNumbers = new List<int>(nrOfConnections);
+        var selectedNumbers = new List<int>(nrOfConnections + 1);
+        selectedNumbers.Add(i);
         for (int j = 0; j < nrOfConnections && numbers.Count > 0; j++) {
           int index = random.Next(numbers.Count);
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RingTopologyInitializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RingTopologyInitializer.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RingTopologyInitializer.cs	(revision 15181)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
-  [Item("Ring Topology Initializer", "Connected every particle with its preceeding and its following particle.")]
+  [Item("Ring Topology Initializer", "Each particle is informed by its preceeding and its succeeding particle wrapping around at the beginning and the end of the swarm (in addition each particle also informs itself).")]
   [StorableClass]
   public sealed class RingTopologyInitializer : TopologyInitializer {
@@ -47,5 +47,5 @@
       ItemArray<IntArray> neighbors = new ItemArray<IntArray>(swarmSize);
       for (int i = 0; i < swarmSize; i++) {
-        neighbors[i] = new IntArray(new[] { (swarmSize + i - 1) % swarmSize, (i + 1) % swarmSize });
+        neighbors[i] = new IntArray(new[] { (swarmSize + i - 1) % swarmSize, i, (i + 1) % swarmSize });
       }
       NeighborsParameter.ActualValue = neighbors;
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/SPSORandomTopologyInitializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/SPSORandomTopologyInitializer.cs	(revision 15181)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/SPSORandomTopologyInitializer.cs	(revision 15181)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
+  [Item("SPSO Random Topology Initializer", "Each particle informs k+1 other particles (including itself). The same particle (including itself) can be informed multiple times.")]
+  [StorableClass]
+  public sealed class SPSORandomTopologyInitializer : TopologyInitializer, IStochasticOperator {
+    #region Parameters
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> KParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["K"]; }
+    }
+    #endregion
+    
+    #region Construction & Cloning
+    [StorableConstructor]
+    private SPSORandomTopologyInitializer(bool deserializing) : base(deserializing) { }
+    private SPSORandomTopologyInitializer(SPSORandomTopologyInitializer original, Cloner cloner) : base(original, cloner) { }
+    public SPSORandomTopologyInitializer() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "A random number generation."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("K", "The number of informed particles (excluding itself).", new IntValue(3)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SPSORandomTopologyInitializer(this, cloner);
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var swarmSize = SwarmSizeParameter.ActualValue.Value;
+      var k = KParameter.ActualValue.Value;
+
+      // SPSO: Each particle informs at most K+1 particles (at least itself and K others)
+      var particlesInform = Enumerable.Repeat(k + 1, swarmSize)
+        .Select((v, i) => new HashSet<int>(Enumerable.Range(0, v).Select(x => x == 0 ? i : random.Next(swarmSize)))).ToList();
+
+      var neighbors = new ItemArray<IntArray>(swarmSize);
+      for (int i = 0; i < swarmSize; i++) {
+        // calculate the informants for each particle
+        var informants = particlesInform.Select((val, idx) => val.Contains(i) ? idx : -1).Where(x => x >= 0).ToArray();
+        neighbors[i] = new IntArray(informants);
+      }
+      NeighborsParameter.ActualValue = neighbors;
+      return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/VonNeumannTopologyInitializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/VonNeumannTopologyInitializer.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/VonNeumannTopologyInitializer.cs	(revision 15181)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
-  [Item("Von Neumann Topology Initializer", "Every particle is connected with the two following and the two previous particles wrapping around at the beginning and the end of the population.")]
+  [Item("Von Neumann Topology Initializer", "Every particle is informed by the two following and the two previous particles wrapping around at the beginning and the end of the swarm (in addition each particle also informs itself).")]
   [StorableClass]
   public sealed class VonNeumannTopologyInitializer : TopologyInitializer {
@@ -51,4 +51,5 @@
           (swarmSize + i-2) % swarmSize,
           (swarmSize + i-1) % swarmSize,
+          i,
           (i+1) % swarmSize,
           (i+2) % swarmSize
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSO2011ParticleUpdater.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSO2011ParticleUpdater.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSO2011ParticleUpdater.cs	(revision 15181)
@@ -25,4 +25,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Encodings.RealVectorEncoding {
@@ -42,20 +43,27 @@
     public static void UpdateVelocity(IRandom random, RealVector velocity, double maxVelocity, RealVector position, double inertia, RealVector personalBest, double personalBestAttraction, RealVector neighborBest, double neighborBestAttraction, double c = 1.193) {
       var gravity = new double[velocity.Length];
-      var direct = new RealVector(velocity.Length);
+      var direction = new RealVector(velocity.Length);
       var radius = 0.0;
+
+      var nd = new NormalDistributedRandom(random, 0, 1);
 
       for (int i = 0; i < velocity.Length; i++) {
         var g_id = c * ((personalBest[i] + neighborBest[i] - 2 * position[i]) / 3.0);
+        // center of the hyper-sphere
         gravity[i] = g_id + position[i];
-        direct[i] = (random.NextDouble() - 0.5) * 2;
+        // a random direction vector uniform over the surface of hyper-sphere, see http://mathworld.wolfram.com/HyperspherePointPicking.html
+        direction[i] = nd.NextDouble();
         radius += g_id * g_id;
       }
 
+      // randomly choose a radius within the hyper-sphere
       radius = random.NextDouble() * Math.Sqrt(radius);
 
-      var unitscale = Math.Sqrt(direct.DotProduct(direct));
+      // unitscale is used to rescale the random direction vector to unit length, resp. length of the radius
+      var unitscale = Math.Sqrt(direction.DotProduct(direction));
       if (unitscale > 0) {
         for (var i = 0; i < velocity.Length; i++) {
-          velocity[i] = velocity[i] * inertia + gravity[i] + direct[i] * radius / unitscale - position[i];
+          var sampledPos = gravity[i] + direction[i] * radius / unitscale;
+          velocity[i] = velocity[i] * inertia + sampledPos - position[i];
         }
       }
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSOSwarmUpdater.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSOSwarmUpdater.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ParticleOperators/SPSOSwarmUpdater.cs	(revision 15181)
@@ -34,5 +34,5 @@
 
 namespace HeuristicLab.Encodings.RealVectorEncoding {
-  [Item("Swarm Updater (SPSO)", "Updates personal best point and quality as well as global best point and quality.")]
+  [Item("Swarm Updater (SPSO)", "Updates personal best point and quality as well as neighbor best point and quality.")]
   [StorableClass]
   public sealed class SPSOSwarmUpdater : SingleSuccessorOperator, IRealVectorSwarmUpdater, ISingleObjectiveOperator {
@@ -126,5 +126,5 @@
       Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaxVelocity", "Speed limit for each particle.", new DoubleValue(1000000)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaxVelocity", "The maximum velocity for each particle and initial velocity if scaling is used.", new DoubleValue(double.MaxValue)));
       Parameters.Add(new LookupParameter<DoubleValue>("CurrentMaxVelocity", "Current value of the speed limit."));
       Parameters.Add(new LookupParameter<ResultCollection>("Results", "Results"));
@@ -132,5 +132,5 @@
       #region Max Velocity Updating
       Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("MaxVelocityScalingOperator", "Modifies the value"));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("FinalMaxVelocity", "The value of maximum velocity if PSO has reached maximum iterations.", new DoubleValue(1E-10)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("FinalMaxVelocity", "The value of maximum velocity if scaling is used and PSO has reached maximum iterations.", new DoubleValue(1E-10)));
       Parameters.Add(new LookupParameter<IntValue>("MaxVelocityIndex", "The current index.", "Iterations"));
       Parameters.Add(new ValueLookupParameter<IntValue>("MaxVelocityStartIndex", "The start index at which to start modifying 'Value'.", new IntValue(0)));
@@ -195,18 +195,29 @@
         var neighborBest = new ItemArray<RealVector>(neighbors.Length);
         var neighborBestQuality = new ItemArray<DoubleValue>(neighbors.Length);
+        double overallBest = double.NaN;
+        RealVector overallBestVector = null;
         for (int n = 0; n < neighbors.Length; n++) {
-          var pairs = particles.Where(x => x.Item1 == n || neighbors[n].Contains(x.Item1));
-          var bestNeighbor = (maximization ? pairs.MaxItems(p => p.Item3)
-                                           : pairs.MinItems(p => p.Item3)).First();
+          var neighborhood = particles.Where(x => neighbors[n].Contains(x.Item1));
+          var bestNeighbor = (maximization ? neighborhood.MaxItems(p => p.Item3)
+                                           : neighborhood.MinItems(p => p.Item3)).First();
           neighborBest[n] = bestNeighbor.Item2;
           neighborBestQuality[n] = new DoubleValue(bestNeighbor.Item3);
+          if (double.IsNaN(overallBest) || maximization && bestNeighbor.Item3 > overallBest
+            || !maximization && bestNeighbor.Item3 < overallBest) {
+            overallBest = bestNeighbor.Item3;
+            overallBestVector = bestNeighbor.Item2;
+          }
         }
         NeighborBestParameter.ActualValue = neighborBest;
         NeighborBestQualityParameter.ActualValue = neighborBestQuality;
+        SwarmBestQualityParameter.ActualValue = new DoubleValue(overallBest);
+        BestRealVectorParameter.ActualValue = overallBestVector;
       } else {
         // Neighbor best = Global best
         var best = maximization ? particles.MaxItems(x => x.Item3).First() : particles.MinItems(x => x.Item3).First();
-        NeighborBestParameter.ActualValue = new ItemArray<RealVector>(particles.Select(x => best.Item2));
-        NeighborBestQualityParameter.ActualValue = new ItemArray<DoubleValue>(particles.Select(x => new DoubleValue(best.Item3)));
+        NeighborBestParameter.ActualValue = new ItemArray<RealVector>(Enumerable.Repeat(best.Item2, particles.Count));
+        NeighborBestQualityParameter.ActualValue = new ItemArray<DoubleValue>(Enumerable.Repeat(new DoubleValue(best.Item3), particles.Count));
+        SwarmBestQualityParameter.ActualValue = new DoubleValue(best.Item3);
+        BestRealVectorParameter.ActualValue = best.Item2;
       }
     }
@@ -224,5 +235,5 @@
           !maximization && p.Item3 < personalBestQuality[p.Item1].Value) {
           personalBestQuality[p.Item1].Value = p.Item3;
-          personalBest[p.Item1] = (RealVector)p.Item2.Clone();
+          personalBest[p.Item1] = new RealVector(p.Item2);
         }
       }
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVector.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVector.cs	(revision 15181)
@@ -45,4 +45,8 @@
         array[i] = elements[i];
     }
+    public RealVector(RealVector other)
+      : this(other.Length) {
+      Array.Copy(other.array, array, other.Length);
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab-3.3/Samples/PsoSchwefelSampleTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab-3.3/Samples/PsoSchwefelSampleTest.cs	(revision 15180)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab-3.3/Samples/PsoSchwefelSampleTest.cs	(revision 15181)
@@ -52,12 +52,12 @@
       SamplesUtils.RunAlgorithm(pso);
       if (Environment.Is64BitProcess) {
-        Assert.AreEqual(2.8334909529803554E-08, SamplesUtils.GetDoubleResult(pso, "BestQuality"));
-        Assert.AreEqual(128.08680460446624, SamplesUtils.GetDoubleResult(pso, "CurrentAverageQuality"));
-        Assert.AreEqual(713.67728101375587, SamplesUtils.GetDoubleResult(pso, "CurrentWorstQuality"));
+        Assert.AreEqual(2.6641411068339949E-05, SamplesUtils.GetDoubleResult(pso, "BestQuality"));
+        Assert.AreEqual(94.28800902426002, SamplesUtils.GetDoubleResult(pso, "CurrentAverageQuality"));
+        Assert.AreEqual(992.93251114761892, SamplesUtils.GetDoubleResult(pso, "CurrentWorstQuality"));
         Assert.AreEqual(200, SamplesUtils.GetIntResult(pso, "Iterations"));
       } else {
-        Assert.AreEqual(2.8334909529803554E-08, SamplesUtils.GetDoubleResult(pso, "BestQuality"));
-        Assert.AreEqual(128.08680460446624, SamplesUtils.GetDoubleResult(pso, "CurrentAverageQuality"));
-        Assert.AreEqual(713.67728101375587, SamplesUtils.GetDoubleResult(pso, "CurrentWorstQuality"));
+        Assert.AreEqual(2.6641411068339949E-05, SamplesUtils.GetDoubleResult(pso, "BestQuality"));
+        Assert.AreEqual(94.28800902426002, SamplesUtils.GetDoubleResult(pso, "CurrentAverageQuality"));
+        Assert.AreEqual(992.93251114761892, SamplesUtils.GetDoubleResult(pso, "CurrentWorstQuality"));
         Assert.AreEqual(200, SamplesUtils.GetIntResult(pso, "Iterations"));
       }
