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;
                }
            }
        }
Ejemplo n.º 2
0
        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;
                }
            }
        }