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) { var gravity = new double[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 = (personalBestAttraction * personalBest[i] + neighborBestAttraction * neighborBest[i] - position[i] * (neighborBestAttraction + personalBestAttraction)) / 3.0; // center of the hyper-sphere gravity[i] = g_id + position[i]; // 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); // 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++) { var sampledPos = gravity[i] + direction[i] * radius / unitscale; velocity[i] = velocity[i] * inertia + sampledPos - position[i]; } } var speed = Math.Sqrt(velocity.DotProduct(velocity)); if (speed > maxVelocity) { for (var i = 0; i < velocity.Length; i++) { velocity[i] *= maxVelocity / speed; } } }
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) { for (int i = 0; i < velocity.Length; i++) { double r_p = random.NextDouble(); double r_g = random.NextDouble(); velocity[i] = velocity[i] * inertia + (personalBest[i] - position[i]) * personalBestAttraction * r_p + (neighborBest[i] - position[i]) * neighborBestAttraction * r_g; } var speed = Math.Sqrt(velocity.DotProduct(velocity)); if (speed > maxVelocity) { for (var i = 0; i < velocity.Length; i++) { velocity[i] *= maxVelocity / speed; } } }