/// <summary>
        /// Performs a non uniformly distributed one position manipulation on the given
        /// real <paramref name="vector"/>. The probability of stronger mutations reduces the more <see cref="currentIteration"/> approaches <see cref="maximumIterations"/>.
        /// </summary>
        /// <exception cref="ArgumentException">Thrown when <paramref name="currentIteration"/> is greater than <paramref name="maximumIterations"/>.</exception>
        /// <param name="random">The random number generator.</param>
        /// <param name="vector">The real vector to manipulate.</param>
        /// <param name="bounds">The lower and upper bound (1st and 2nd column) of the positions in the vector. If there are less rows than dimensions, the rows are cycled.</param>
        /// <param name="currentIteration">The current iteration of the algorithm.</param>
        /// <param name="maximumIterations">Maximum number of iterations.</param>
        /// <param name="iterationDependency">Specifies the degree of dependency on the number of iterations. A value of 0 means no dependency and the higher the value the stronger the progress towards maximum iterations will be taken into account by sampling closer around the current position. Value must be >= 0.</param>
        /// <returns>The manipulated real vector.</returns>
        public static void Apply(IRandom random, RealVector vector, DoubleMatrix bounds, IntValue currentIteration, IntValue maximumIterations, DoubleValue iterationDependency)
        {
            if (currentIteration.Value > maximumIterations.Value)
            {
                throw new ArgumentException("MichalewiczNonUniformOnePositionManipulator: CurrentIteration must be smaller or equal than MaximumIterations", "currentIteration");
            }
            if (iterationDependency.Value < 0)
            {
                throw new ArgumentException("MichalewiczNonUniformOnePositionManipulator: iterationDependency must be >= 0.", "iterationDependency");
            }
            int length = vector.Length;
            int index  = random.Next(length);

            double prob = (1 - Math.Pow(random.NextDouble(), Math.Pow(1 - currentIteration.Value / maximumIterations.Value, iterationDependency.Value)));

            double min = bounds[index % bounds.Rows, 0];
            double max = bounds[index % bounds.Rows, 1];

            if (random.NextDouble() < 0.5)
            {
                vector[index] = vector[index] + (max - vector[index]) * prob;
            }
            else
            {
                vector[index] = vector[index] - (vector[index] - min) * prob;
            }
        }
Exemplo n.º 2
0
 public void Visit(FuncExpression <T> expression)
 {
     if (_random.NextDouble() < _mutationRate.GetValue())
     {
         MutateFuncExpression(expression);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        ///     Generates normally distributed numbers. Each operation makes two Gaussian for the price of one, and apparently
        ///     they can be cached or something for better performance, but who cares.
        /// </summary>
        /// <param name="random"></param>
        /// <param name="mu">Mean of the distribution</param>
        /// <param name="sigma">Standard deviation</param>
        /// <returns></returns>
        public static double NextGaussian(
            [NotNull]
            this IRandom random,
            double mu    = 0,
            double sigma = 1)
        {
            if (random == null)
            {
                throw new ArgumentNullException(nameof(random));
            }

            if (sigma <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(sigma));
            }

            double u1 = random.NextDouble( );
            double u2 = random.NextDouble( );

            double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);

            double randNormal = mu + sigma * randStdNormal;

            return(randNormal);
        }
Exemplo n.º 4
0
        /// <summary>
        /// <para>Sample a value from a gamma distribution.</para>
        /// <para>Implementation of "A Simple Method for Generating Gamma Variables" - Marsaglia & Tsang
        /// ACM Transactions on Mathematical Software, Vol. 26, No. 3, September 2000, Pages 363–372.</para>
        /// </summary>
        /// <param name="uniformRandom">A uniformly-distributed random number generator.</param>
        /// <param name="shape">The shape (k, α) of the Gamma distribution. Range: α ≥ 0.</param>
        /// <param name="rate">The rate or inverse scale (β) of the Gamma distribution. Range: β ≥ 0.</param>
        /// <returns>A sample from a Gamma distributed random variable.</returns>
        public static double NextDouble(IRandom uniformRandom, double shape, double rate)
        {
            if (double.IsPositiveInfinity(rate))
            {
                return(shape);
            }
            var a = 1d;

            if (shape < 1)
            {
                a      = Math.Pow(uniformRandom.NextDouble(), 1 / shape);
                shape += 1;
            }
            var d = shape - 1d / 3d;
            var c = 1 / Math.Sqrt(9 * d);

            for (;;)
            {
                double v, x;
                do
                {
                    x = NormalDistributedRandom.NextDouble(uniformRandom, 0, 1);
                    v = 1 + c * x;
                } while (v <= 0);

                v = v * v * v;
                x = x * x; // save a multiplication below
                var u = uniformRandom.NextDouble();
                if (u < 1 - 0.0331 * x * x || Math.Log(u) < 0.5 * x + d * (1 - v + Math.Log(v)))
                {
                    return(a * d * v / rate);
                }
            }
        }
    /// <summary>
    /// Performs a breeder genetic algorithm manipulation on the given <paramref name="vector"/>.
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="vector">The real vector to manipulate.</param>
    /// <param name="bounds">The lower and upper bound (1st and 2nd column) of the positions in the vector. If there are less rows than dimensions, the rows are cycled.</param>
    /// <param name="searchIntervalFactor">The factor determining the size of the search interval.</param>
    public static void Apply(IRandom random, RealVector vector, DoubleMatrix bounds, DoubleValue searchIntervalFactor) {
      int length = vector.Length;
      double prob, value;
      do {
        value = Sigma(random);
      } while (value == 0);

      prob = 1.0 / (double)length;
      bool wasMutated = false;

      for (int i = 0; i < length; i++) {
        if (random.NextDouble() < prob) {
          double range = bounds[i % bounds.Rows, 1] - bounds[i % bounds.Rows, 0];
          if (random.NextDouble() < 0.5) {
            vector[i] = vector[i] + value * searchIntervalFactor.Value * range;
          } else {
            vector[i] = vector[i] - value * searchIntervalFactor.Value * range;
          }
          wasMutated = true;
        }
      }

      // make sure at least one gene was mutated
      if (!wasMutated) {
        int pos = random.Next(length);
        double range = bounds[pos % bounds.Rows, 1] - bounds[pos % bounds.Rows, 0];
        if (random.NextDouble() < 0.5) {
          vector[pos] = vector[pos] + value * searchIntervalFactor.Value * range;
        } else {
          vector[pos] = vector[pos] - value * searchIntervalFactor.Value * range;
        }
      }
    }
        private IEnumerable <IOrganism> PickItems()
        {
            if (this.candidates.Count == 0)
            {
                throw new ArgumentException("candidates");
            }

            double threshold         = rand.NextDouble();
            double totalFitnessSoFar = 0;

            for (int i = 0; i <= this.candidates.Count - 1; i++)
            {
                totalFitnessSoFar += this.candidates[i].FitnessProportion;
                if (totalFitnessSoFar >= threshold)
                {
                    totalFitnessSoFar = 0;
                    threshold         = rand.NextDouble();
                    yield return(this.candidates[i]);
                }

                if (i == this.candidates.Count - 1)
                {
                    i = 0;
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Returns a sample from the gamma distribution with scale parameter 1, shape parameter alpha
        /// </summary>
        /// <param name="alpha">Shape parameter</param>
        /// <param name="r">The random number generator to use</param>
        /// <returns>Sample from gamma distribution</returns>
        /// <remarks>Uses Marsaglia and Tsang's fast algorithm</remarks>
        public static double SampleFromGamma(IRandom r, double alpha)
        {
            Contracts.CheckParam(alpha > 0, nameof(alpha), "alpha must be positive");

            if (alpha < 1)
            {
                return(SampleFromGamma(r, alpha + 1) * Math.Pow(r.NextDouble(), 1.0 / alpha));
            }

            double d = alpha - 1.0 / 3;
            double c = 1 / Math.Sqrt(9 * d);
            double x;
            double u;
            double v;

            while (true)
            {
                do
                {
                    x = SampleFromGaussian(r);
                    v = Math.Pow(1.0 + c * x, 3);
                } while (v <= 0);
                u = r.NextDouble();
                double xSqr = x * x;
                if (u < 1.0 - 0.0331 * xSqr * xSqr ||
                    Math.Log(u) < 0.5 * xSqr + d * (1.0 - v + Math.Log(v)))
                {
                    return(d * v);
                }
            }
        }
        private void InitSumupInputData(SumupInputData data, double sparsity, IRandom rgen)
        {
            int count = 0;

            foreach (int d in CreateDocIndices(sparsity, rgen))
            {
                data.DocIndices[count++] = d;
            }
            _host.Assert(Utils.IsIncreasing(0, data.DocIndices, count, _len));
            data.TotalCount = count;
            FloatType osum = 0;

            if (data.Weights == null)
            {
                for (int i = 0; i < count; ++i)
                {
                    osum += (data.Outputs[i] = (FloatType)(2 * rgen.NextDouble() - 1));
                }
                data.SumWeights = count;
            }
            else
            {
                FloatType wsum = 0;
                for (int i = 0; i < count; ++i)
                {
                    osum += (data.Outputs[i] = (FloatType)(2 * rgen.NextDouble() - 1));
                    wsum += (data.Weights[i] = (FloatType)(2 * rgen.NextDouble() - 1));
                }
                data.SumWeights = wsum;
            }
            data.SumTargets = osum;
        }
Exemplo n.º 9
0
        public void Update(float delta)
        {
            if (_random.NextDouble() < 0.001)
            {
                Brightness = (float)_random.NextDouble(_maxBrightness - 0.2f, _maxBrightness);

                //thunderInstance.Play();
                //_soundEffectManager.Play("thunder_01", (float)_random.NextDouble(0.05, 0.25), (float)_random.NextDouble(-0.3, 0.3), (float)_random.NextDouble(-0.2, 0.1));
            }

            if (Brightness > _minBrightness)
            {
                Brightness *= 0.9f;

                if (_random.NextDouble() < 0.04)
                {
                    Brightness += (float)_random.NextDouble(0.1, 0.3);
                }

                if (Brightness < _minBrightness)
                {
                    Brightness = _minBrightness;
                }
            }
        }
 public override void ShakeLocalParameters(IRandom random, double shakingFactor)
 {
     // 50% additive & 50% multiplicative (override of functionality of base class because of a BUG)
     if (random.NextDouble() < 0.5)
     {
         double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu, Symbol.WeightManipulatorSigma);
         Weight = Weight + x * shakingFactor;
     }
     else
     {
         double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeWeightManipulatorSigma);
         Weight = Weight * x;
     }
     if (random.NextDouble() < Symbol.VariableChangeProbability)
     {
         var oldName = VariableName;
         VariableName = Symbol.VariableNames.SampleRandom(random);
         // reinitialize weights if variable has changed (similar to FactorVariableTreeNode)
         if (oldName != VariableName)
         {
             Weight = NormalDistributedRandom.NextDouble(random, Symbol.WeightMu, Symbol.WeightSigma);
         }
     }
     variableValue = Symbol.GetVariableValues(VariableName).SampleRandom(random);
 }
Exemplo n.º 11
0
 public static LinearLinkage Apply(IRandom random, LinearLinkage p1, LinearLinkage p2) {
   var length = p1.Length;
   var child = new LinearLinkage(length);
   var endNodes = new HashSet<int>();
   for (var i = 0; i < length; i++) {
     if ((p1[i] == i && p2[i] == i)
       || ((p1[i] == i || p2[i] == i) && random.NextDouble() < 0.5)) {
       child[i] = i;
       endNodes.Add(i);
     }
   }
   for (var i = 0; i < length; i++) {
     if (endNodes.Contains(i)) continue;
     var p1End = endNodes.Contains(p1[i]);
     var p2End = endNodes.Contains(p2[i]);
     if ((p1End && p2End) || (!p1End && !p2End)) {
       child[i] = random.NextDouble() < 0.5 ? p1[i] : p2[i];
     } else if (p1End) {
       child[i] = p1[i];
     } else {
       child[i] = p2[i];
     }
   }
   child.LinearizeTreeStructures();
   return child;
 }
Exemplo n.º 12
0
        public void Merge(T parent1, T parent2, T child)
        {
            double parent1Percent = _random.NextDouble();
            double newValue       = _getterFunc(parent1) * parent1Percent + _getterFunc(parent2) * (1 - parent1Percent);

            _setterAction(child, newValue);
        }
Exemplo n.º 13
0
        public override void ShakeLocalParameters(IRandom random, double shakingFactor)
        {
            // mutate only one randomly selected weight
            var idx = random.Next(weights.Length);

            // 50% additive & 50% multiplicative
            if (random.NextDouble() < 0.5)
            {
                double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu,
                                                              Symbol.WeightManipulatorSigma);
                weights[idx] = weights[idx] + x * shakingFactor;
            }
            else
            {
                double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeWeightManipulatorSigma);
                weights[idx] = weights[idx] * x;
            }
            if (random.NextDouble() < Symbol.VariableChangeProbability)
            {
                VariableName = Symbol.VariableNames.SampleRandom(random);
                if (weights.Length != Symbol.GetVariableValues(VariableName).Count())
                {
                    // if the length of the weight array does not match => re-initialize weights
                    weights =
                        Symbol.GetVariableValues(variableName)
                        .Select(_ => NormalDistributedRandom.NextDouble(random, 0, 1))
                        .ToArray();
                }
            }
        }
Exemplo n.º 14
0
        /// <summary>Returns a random point within a triangle</summary>
        /// <param name="randomNumberGenerator">Random number generator that will be used</param>
        /// <param name="a">Location of the triangle's first corner</param>
        /// <param name="b">Location of the triangle's second corner</param>
        /// <param name="c">Location of the triangle's third corner</param>
        /// <returns>A random point within the triangle</returns>
        public static Vector3 GenerateRandomPointWithin(
            IRandom randomNumberGenerator, Vector3 a, Vector3 b, Vector3 c
            )
        {
            // Treat triangle as the half of a parallelogram. Then calculate a
            // random point along the width and the height.
            //
            //       Width
            //    -----------
            //   a___________
            //   /          /  /
            //  /          /  / Height
            // /__________/  /
            // b         c
            //
            // Now split the parallelogram along a-c and mirror any points that
            // end up on the other side.
            //
            //   xx = rand(1.0)
            //   yy = rand(1.0)
            //
            //   if((xx + yy) > 1.0) {
            //     xx = 1.0 - xx;
            //     yy = 1.0 - yy;
            //   }
            //
            // Then calculate the absolute coordinates of the point
            //
            //   a.
            //   /  .
            //  /     .
            // /________.
            // b         c
            //
            // x = b.x + xx * (c.x - b.x) + (b.x - a.x) * yy
            // y = yy * (a.y - b.y)

            // This might be using the same approach, not sure though :)
            // http://vcg.isti.cnr.it/activities/geometryegraphics/pointintetraedro.html

            // Calculate random barycentric coordinates inside the unit
            // triangle (0,0)-(1,0)-(0,1). First, we take random x and y coordinates in
            // a box with side lengths ab, ac
            float x = (float)randomNumberGenerator.NextDouble();
            float y = (float)randomNumberGenerator.NextDouble();

            // The triangle covers exactly half of the box our random points are distributed
            // in. Instead of rejecting these coordinates, we mirror the other half of the box
            // back into the triangle (on the bc edge of the triangle)
            if (x + y > 1.0f)
            {
                x = 1.0f - x;
                y = 1.0f - y;
            }
            float z = 1.0f - x - y;

            // Convert the barycentric coordinates back into cartesian coordinates
            return((a * x) + (b * y) + (c * z));
        }
Exemplo n.º 15
0
        /// <summary>Returns a random point within a rectangle</summary>
        /// <param name="randomNumberGenerator">Random number generator that will be used</param>
        /// <param name="extents">Extents of the rectangle</param>
        /// <returns>A random point within the rectangle</returns>
        public static Vector2 GenerateRandomPointWithin(
            IRandom randomNumberGenerator, Vector2 extents
            )
        {
            float x = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;
            float y = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;

            return(new Vector2(x * extents.X, y * extents.Y));
        }
Exemplo n.º 16
0
        /// <summary>Returns a random point on the surface of a box</summary>
        /// <param name="randomNumberGenerator">Random number generator that will be used</param>
        /// <param name="extents">Extents of the box</param>
        /// <returns>A random point on the box' surface</returns>
        /// <remarks>
        ///   The performance of this algorithm varies slightly depending on the face
        ///   that is chosen for the random point because a different number of
        ///   comparisons and subtractions will be performed.
        /// </remarks>
        public static Vector3 GenerateRandomPointOnSurface(
            IRandom randomNumberGenerator, Vector3 extents
            )
        {
            // For this task, we also need the dimensions of the box
            Vector3 dimensions = extents * 2.0f;

            // Determine the area covered by the sides of the box
            float leftRightArea = dimensions.Z * dimensions.Y;
            float topBottomArea = dimensions.X * dimensions.Z;
            float frontBackArea = dimensions.X * dimensions.Y;

            // Choose which face of the box the point is going be on
            float side = (float)randomNumberGenerator.NextDouble() *
                         (leftRightArea * 2.0f) * (topBottomArea * 2.0f) * (frontBackArea * 2.0f);

            // Now obtain were the point will be located
            float u = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;
            float v = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;

            // Calculate the final world space coordinates of the point
            side -= leftRightArea;
            if (side < 0.0)
            {
                return(new Vector3(-extents.X, v * extents.Y, u * extents.Z));
            }

            side -= leftRightArea;
            if (side < 0.0)
            {
                return(new Vector3(+extents.X, v * extents.Y, u * extents.Z));
            }

            side -= topBottomArea;
            if (side < 0.0)
            {
                return(new Vector3(u * extents.X, +extents.Y, v * extents.Z));
            }

            side -= topBottomArea;
            if (side < 0.0)
            {
                return(new Vector3(u * extents.X, -extents.Y, v * extents.Z));
            }

            side -= frontBackArea;
            if (side < 0.0)
            {
                return(new Vector3(u * extents.X, v * extents.Y, -extents.Z));
            }

            else
            {
                return(new Vector3(u * extents.X, v * extents.Y, +extents.Z));
            }
        }
Exemplo n.º 17
0
 /// <summary>Returns a random point within a box</summary>
 /// <param name="randomNumberGenerator">Random number generator that will be used</param>
 /// <param name="extents">Extents of the box</param>
 /// <returns>A random point within the box</returns>
 public static Vector3 GenerateRandomPointWithin(
     IRandom randomNumberGenerator, Vector3 extents
     )
 {
     return(new Vector3(
                ((float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f) * extents.X,
                ((float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f) * extents.Y,
                ((float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f) * extents.Z
                ));
 }
Exemplo n.º 18
0
        /// <summary>Returns a random point on the surface of a cylinder</summary>
        /// <param name="randomNumberGenerator">Random number generator that will be used</param>
        /// <param name="orientation">Orientation of the cylinder</param>
        /// <param name="radius">Radius of the cylinder</param>
        /// <param name="length">Length of the cylinder</param>
        /// <returns>A random point on the volume's surface</returns>
        public static Vector3 GenerateRandomPointOnSurface(
            IRandom randomNumberGenerator,
            Matrix orientation, float radius, float length
            )
        {
            // Calculate the surface areas of the three sections our cylinder has:
            // Upper cap, side and lower cap
            float capArea        = MathHelper.Pi * (radius * radius);
            float sideArea       = 2.0f * MathHelper.Pi * radius * length;
            float capAndSideArea = capArea + sideArea;

            // We need a phi value (angle of the random point) in any of the cases
            float phi = (float)randomNumberGenerator.NextDouble() * MathHelper.TwoPi;

            // Choose the section that the random point will be generated on in relation
            // to its surface area so the probability is constant on the entire surface
            float section = (float)randomNumberGenerator.NextDouble() * (capArea * 2.0f + sideArea);

            // Depending on the section, these two values are calculated differently
            float randomRadius;
            float randomZ;

            // Upper cap: Generate a random radius
            if (section < capArea)
            {
                randomZ      = length / 2.0f;
                randomRadius = (float)Math.Sqrt(randomNumberGenerator.NextDouble()) * radius;

                // Side: Generate a random height
            }
            else if (section < capAndSideArea)
            {
                randomZ      = ((float)randomNumberGenerator.NextDouble() - 0.5f) * length;
                randomRadius = radius;

                // Lower cap: Generate a random radius
            }
            else
            {
                randomZ      = -length / 2.0f;
                randomRadius = (float)Math.Sqrt(randomNumberGenerator.NextDouble()) * radius;
            }

            // Now transform the point to cartesian coordinates and rotate it into
            // the global coordinate frame
            return(Vector3.Transform(
                       new Vector3(
                           randomRadius * (float)Math.Cos(phi),
                           randomRadius * (float)Math.Sin(phi),
                           randomZ
                           ),
                       orientation
                       ));
        }
        // use the Box-Mueller transform in the polar form to generate a N(0,1) random variable out of two uniformly distributed random variables
        private static double Gauss(IRandom random)
        {
            double u = 0.0, v = 0.0, s = 0.0;

            do
            {
                u = (random.NextDouble() * 2) - 1;
                v = (random.NextDouble() * 2) - 1;
                s = Math.Sqrt(u * u + v * v);
            } while (s < Double.Epsilon || s > 1);
            return(u * Math.Sqrt((-2.0 * Math.Log(s)) / s));
        }
Exemplo n.º 20
0
        /// <summary>Returns a random point inside the area</summary>
        /// <param name="randomNumberGenerator">Random number generator that will be used</param>
        /// <returns>A random point inside the area</returns>
        public Vector2 RandomPointWithin(IRandom randomNumberGenerator)
        {
            Vector2 randomPoint = new Vector2(
                (float)randomNumberGenerator.NextDouble(),
                (float)randomNumberGenerator.NextDouble()
                );

            Vector2 result;

            Vector2.Transform(ref randomPoint, ref this.Transform, out result);
            return(result);
        }
Exemplo n.º 21
0
        public void RecordedRates_TestRecording_ValuesAddedProperly()
        {
            _randomValue = 1;
            A.CallTo(() => _mockRandom.NextDouble()).Returns(_randomValue);
            _logic.StartRecording();
            _logic.StartGenerating();

            BuySellRate buySellRate = _logic.RecordedRates.First();

            Assert.AreEqual(3.55m, buySellRate.BuyRate);
            Assert.AreEqual(3.8m, buySellRate.SellRate);
        }
Exemplo n.º 22
0
        public override double RandNormal(IRandom random, double mu, double sigma)
        {
            double z, zz, u1, u2;

            do
            {
                u1 = random.NextDouble();
                u2 = 1 - random.NextDouble();
                z  = NormalMagicConst * (u1 - 0.5) / u2;
                zz = z * z / 4.0;
            } while (zz > -Math.Log(u2));
            return(mu + z * sigma);
        }
Exemplo n.º 23
0
        private static double GetNormal(IRandom rand, double mu, double sigma)
        {
            double z, zz, u1, u2;

            do
            {
                u1 = rand.NextDouble();
                u2 = 1 - rand.NextDouble();
                z  = NormalMagicConst * (u1 - 0.5) / u2;
                zz = z * z / 4.0;
            } while (zz > -Math.Log(u2));
            return(mu + z * sigma);
        }
    /// <summary>Returns a random point on the surface of a cylinder</summary>
    /// <param name="randomNumberGenerator">Random number generator that will be used</param>
    /// <param name="orientation">Orientation of the cylinder</param>
    /// <param name="radius">Radius of the cylinder</param>
    /// <param name="length">Length of the cylinder</param>
    /// <returns>A random point on the volume's surface</returns>
    public static Vector3 GenerateRandomPointOnSurface(
      IRandom randomNumberGenerator,
      Matrix orientation, float radius, float length
    ) {

      // Calculate the surface areas of the three sections our cylinder has:
      // Upper cap, side and lower cap
      float capArea = MathHelper.Pi * (radius * radius);
      float sideArea = 2.0f * MathHelper.Pi * radius * length;
      float capAndSideArea = capArea + sideArea;

      // We need a phi value (angle of the random point) in any of the cases
      float phi = (float)randomNumberGenerator.NextDouble() * MathHelper.TwoPi;

      // Choose the section that the random point will be generated on in relation
      // to its surface area so the probability is constant on the entire surface
      float section = (float)randomNumberGenerator.NextDouble() * (capArea * 2.0f + sideArea);

      // Depending on the section, these two values are calculated differently
      float randomRadius;
      float randomZ;

      // Upper cap: Generate a random radius
      if(section < capArea) {
        randomZ = length / 2.0f;
        randomRadius = (float)Math.Sqrt(randomNumberGenerator.NextDouble()) * radius;

      // Side: Generate a random height
      } else if(section < capAndSideArea) {
        randomZ = ((float)randomNumberGenerator.NextDouble() - 0.5f) * length;
        randomRadius = radius;

      // Lower cap: Generate a random radius
      } else {
        randomZ = -length / 2.0f;
        randomRadius = (float)Math.Sqrt(randomNumberGenerator.NextDouble()) * radius;
      }

      // Now transform the point to cartesian coordinates and rotate it into
      // the global coordinate frame
      return Vector3.Transform(
        new Vector3(
          randomRadius * (float)Math.Cos(phi),
          randomRadius * (float)Math.Sin(phi),
          randomZ
        ),
        orientation
      );

    }
Exemplo n.º 25
0
        /// <summary>Returns a random point within a disc</summary>
        /// <param name="randomNumberGenerator">Random number generator that will be used</param>
        /// <param name="radius">Radius of the disc</param>
        /// <returns>A random point within the disc</returns>
        public static Vector2 GenerateRandomPointWithin(
            IRandom randomNumberGenerator, float radius
            )
        {
            // Choose a random angle for the point
            float phi = (float)randomNumberGenerator.NextDouble() * MathHelper.Pi * 2.0f;

            // Get a random radius with compensated probability for the outer regions of the disc
            float r = (float)Math.Sqrt(randomNumberGenerator.NextDouble()) * radius;

            // Calculate the final position of the point in world space
            return(new Vector2(
                       r * (float)Math.Cos(phi),
                       r * (float)Math.Sin(phi)));
        }
Exemplo n.º 26
0
        /// <summary>
        /// Performs the simulated binary crossover on a real vector. Each position is crossed with a probability of 50% and if crossed either a contracting crossover or an expanding crossover is performed, again with equal probability.
        /// For more details refer to the paper by Deb and Agrawal.
        /// </summary>
        /// <exception cref="ArgumentException">Thrown when the parents' vectors are of unequal length or when <paramref name="contiguity"/> is smaller than 0.</exception>
        /// <remarks>
        /// The manipulated value is not restricted by the (possibly) specified lower and upper bounds. Use the <see cref="BoundsChecker"/> to correct the values after performing the crossover.
        /// </remarks>
        /// <param name="random">The random number generator to use.</param>
        /// <param name="parent1">The first parent vector.</param>
        /// <param name="parent2">The second parent vector.</param>
        /// <param name="contiguity">The contiguity value that specifies how close a child should be to its parents (larger value means closer). The value must be greater or equal than 0. Typical values are in the range [2;5].</param>
        /// <returns>The vector resulting from the crossover.</returns>
        public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue contiguity)
        {
            if (parent1.Length != parent2.Length)
            {
                throw new ArgumentException("SimulatedBinaryCrossover: Parents are of unequal length");
            }
            if (contiguity.Value < 0)
            {
                throw new ArgumentException("SimulatedBinaryCrossover: Contiguity value is smaller than 0", "contiguity");
            }
            int        length = parent1.Length;
            RealVector result = new RealVector(length);

            for (int i = 0; i < length; i++)
            {
                if (length == 1 || random.NextDouble() < 0.5) // cross this variable
                {
                    double u    = random.NextDouble();
                    double beta = 0;
                    if (u < 0.5) // if u is smaller than 0.5 perform a contracting crossover
                    {
                        beta = Math.Pow(2 * u, 1.0 / (contiguity.Value + 1));
                    }
                    else if (u > 0.5) // otherwise perform an expanding crossover
                    {
                        beta = Math.Pow(0.5 / (1.0 - u), 1.0 / (contiguity.Value + 1));
                    }
                    else if (u == 0.5)
                    {
                        beta = 1;
                    }

                    if (random.NextDouble() < 0.5)
                    {
                        result[i] = ((parent1[i] + parent2[i]) / 2.0) - beta * 0.5 * Math.Abs(parent1[i] - parent2[i]);
                    }
                    else
                    {
                        result[i] = ((parent1[i] + parent2[i]) / 2.0) + beta * 0.5 * Math.Abs(parent1[i] - parent2[i]);
                    }
                }
                else
                {
                    result[i] = parent1[i];
                }
            }
            return(result);
        }
Exemplo n.º 27
0
    /// <summary>Returns a random point within a disc</summary>
    /// <param name="randomNumberGenerator">Random number generator that will be used</param>
    /// <param name="radius">Radius of the disc</param>
    /// <returns>A random point within the disc</returns>
    public static Vector2 GenerateRandomPointWithin(
      IRandom randomNumberGenerator, float radius
    ) {

      // Choose a random angle for the point
      float phi = (float)randomNumberGenerator.NextDouble() * MathHelper.Pi * 2.0f;

      // Get a random radius with compensated probability for the outer regions of the disc
      float r = (float)Math.Sqrt(randomNumberGenerator.NextDouble()) * radius;

      // Calculate the final position of the point in world space
      return new Vector2(
        r * (float)Math.Cos(phi),
        r * (float)Math.Sin(phi));

    }
Exemplo n.º 28
0
        protected static int SelectRandomTourBiasedByLength(IRandom random, PotvinEncoding individual, IVRPProblemInstance instance)
        {
            int tourIndex = -1;

            double sum = 0.0;

            double[] probabilities = new double[individual.Tours.Count];
            for (int i = 0; i < individual.Tours.Count; i++)
            {
                probabilities[i] = 1.0 / ((double)individual.Tours[i].Stops.Count / (double)instance.Cities.Value);
                sum += probabilities[i];
            }

            for (int i = 0; i < probabilities.Length; i++)
            {
                probabilities[i] = probabilities[i] / sum;
            }

            double rand = random.NextDouble();
            double cumulatedProbabilities = 0.0;
            int    index = 0;

            while (tourIndex == -1 && index < probabilities.Length)
            {
                if (cumulatedProbabilities <= rand && rand <= cumulatedProbabilities + probabilities[index])
                {
                    tourIndex = index;
                }

                cumulatedProbabilities += probabilities[index];
                index++;
            }

            return(tourIndex);
        }
Exemplo n.º 29
0
 public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
   // mutation
   var d = random.NextDouble() * 2.0 - 1.0;
   value += shakingFactor * d;
   if (value < 0.1) value = 0.1;
   if (value > 3) value = 3;
 }
Exemplo n.º 30
0
    protected static int SelectRandomTourBiasedByLength(IRandom random, PotvinEncoding individual, IVRPProblemInstance instance) {
      int tourIndex = -1;

      double sum = 0.0;
      double[] probabilities = new double[individual.Tours.Count];
      for (int i = 0; i < individual.Tours.Count; i++) {
        probabilities[i] = 1.0 / ((double)individual.Tours[i].Stops.Count / (double)instance.Cities.Value);
        sum += probabilities[i];
      }

      for (int i = 0; i < probabilities.Length; i++)
        probabilities[i] = probabilities[i] / sum;

      double rand = random.NextDouble();
      double cumulatedProbabilities = 0.0;
      int index = 0;
      while (tourIndex == -1 && index < probabilities.Length) {
        if (cumulatedProbabilities <= rand && rand <= cumulatedProbabilities + probabilities[index])
          tourIndex = index;

        cumulatedProbabilities += probabilities[index];
        index++;
      }

      return tourIndex;
    }
Exemplo n.º 31
0
        /// <summary>
        /// Chooses <paramref name="count"/> elements from a sequence with repetition with equal chances for each element.
        /// </summary>
        /// <remarks>
        /// Runtime complexity is O(count) for sequences that are <see cref="IList{T}"/> and
        /// O(N * count) for all other. No exception is thrown if the sequence is empty.
        ///
        /// The method is online.
        /// </remarks>
        /// <typeparam name="T">The type of the items to be selected.</typeparam>
        /// <param name="source">The sequence of elements.</param>
        /// <param name="random">The random number generator to use, its NextDouble() method must produce values in the range [0;1)</param>
        /// <param name="count">The number of items to be selected.</param>
        /// <returns>A sequence of elements that have been chosen randomly.</returns>
        public static IEnumerable <T> SampleRandom <T>(this IEnumerable <T> source, IRandom random, int count)
        {
            var listSource = source as IList <T>;

            if (listSource != null)
            {
                while (count > 0)
                {
                    yield return(listSource[random.Next(listSource.Count)]);

                    count--;
                }
            }
            else
            {
                while (count > 0)
                {
                    var enumerator = source.GetEnumerator();
                    enumerator.MoveNext();
                    T   selectedItem = enumerator.Current;
                    int counter      = 1;
                    while (enumerator.MoveNext())
                    {
                        counter++;
                        if (counter * random.NextDouble() < 1.0)
                        {
                            selectedItem = enumerator.Current;
                        }
                    }
                    yield return(selectedItem);

                    count--;
                }
            }
        }
Exemplo n.º 32
0
        /// <summary>
        /// Create a symbolic expression tree using 'RampedHalfAndHalf' strategy.
        /// Half the trees are created with the 'Grow' method, and the other half are created with the 'Full' method.
        /// </summary>
        /// <param name="random">Random generator</param>
        /// <param name="grammar">Available tree grammar</param>
        /// <param name="maxTreeLength">Maximum tree length (this parameter is ignored)</param>
        /// <param name="maxTreeDepth">Maximum tree depth</param>
        /// <returns></returns>
        public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth)
        {
            var tree     = new SymbolicExpressionTree();
            var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();

            if (rootNode.HasLocalParameters)
            {
                rootNode.ResetLocalParameters(random);
            }
            rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar());

            var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();

            if (startNode.HasLocalParameters)
            {
                startNode.ResetLocalParameters(random);
            }
            startNode.SetGrammar(grammar.CreateExpressionTreeGrammar());

            rootNode.AddSubtree(startNode);

            double p = random.NextDouble();

            if (p < 0.5)
            {
                GrowTreeCreator.Create(random, startNode, maxTreeDepth - 2);
            }
            else
            {
                FullTreeCreator.Create(random, startNode, maxTreeDepth - 2);
            }

            tree.Root = rootNode;
            return(tree);
        }
 private DoubleArray Randomize(IRandom random, int length, DoubleMatrix bounds) {
   var result = new DoubleArray(length);
   for (int i = 0; i < length; i++) {
     result[i] = random.NextDouble() * bounds[i % bounds.Rows, 1] - bounds[i % bounds.Rows, 0];
   }
   return result;
 }
Exemplo n.º 34
0
        /// <summary>
        /// Performs the arithmetic crossover on some positions by taking either x = alpha * p1 + (1 - alpha) * p2 or x = p1 depending on the probability for a gene to be crossed.
        /// </summary>
        /// <param name="random">The random number generator.</param>
        /// <param name="parent1">The first parent vector.</param>
        /// <param name="parent2">The second parent vector.</param>
        /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
        /// <param name="probability">The probability parameter (<see cref="ProbabilityParameter"/>).</param>
        /// <returns>The vector resulting from the crossover.</returns>
        public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue alpha, DoubleValue probability)
        {
            int length = parent1.Length;

            if (length != parent2.Length)
            {
                throw new ArgumentException("UniformSomePositionsArithmeticCrossover: The parent vectors are of different length.", "parent1");
            }
            if (alpha.Value < 0 || alpha.Value > 1)
            {
                throw new ArgumentException("UniformSomePositionsArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
            }
            if (probability.Value < 0 || probability.Value > 1)
            {
                throw new ArgumentException("UniformSomePositionsArithmeticCrossover: Parameter probability must be in the range [0;1]", "probability");
            }

            RealVector result = new RealVector(length);

            for (int i = 0; i < length; i++)
            {
                if (random.NextDouble() < probability.Value)
                {
                    result[i] = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
                }
                else
                {
                    result[i] = parent1[i];
                }
            }
            return(result);
        }
        /// <summary>
        /// Performs the blend alpha beta crossover (BLX-a-b) on two parent vectors.
        /// </summary>
        /// <exception cref="ArgumentException">
        /// Thrown when either:<br/>
        /// <list type="bullet">
        /// <item><description>The length of <paramref name="betterParent"/> and <paramref name="worseParent"/> is not equal.</description></item>
        /// <item><description>The parameter <paramref name="alpha"/> is smaller than 0.</description></item>
        /// <item><description>The parameter <paramref name="beta"/> is smaller than 0.</description></item>
        /// </list>
        /// </exception>
        /// <param name="random">The random number generator to use.</param>
        /// <param name="betterParent">The better of the two parents with regard to their fitness.</param>
        /// <param name="worseParent">The worse of the two parents with regard to their fitness.</param>
        /// <param name="alpha">The parameter alpha.</param>
        /// <param name="beta">The parameter beta.</param>
        /// <returns>The real vector that results from the crossover.</returns>
        public static RealVector Apply(IRandom random, RealVector betterParent, RealVector worseParent, DoubleValue alpha, DoubleValue beta)
        {
            if (betterParent.Length != worseParent.Length)
            {
                throw new ArgumentException("BlendAlphaBetaCrossover: The parents' vectors are of different length.", "betterParent");
            }
            if (alpha.Value < 0)
            {
                throw new ArgumentException("BlendAlphaBetaCrossover: Parameter alpha must be greater or equal to 0.", "alpha");
            }
            if (beta.Value < 0)
            {
                throw new ArgumentException("BlendAlphaBetaCrossover: Parameter beta must be greater or equal to 0.", "beta");
            }
            int        length = betterParent.Length;
            double     min, max, d;
            RealVector result = new RealVector(length);

            for (int i = 0; i < length; i++)
            {
                d = Math.Abs(betterParent[i] - worseParent[i]);
                if (betterParent[i] <= worseParent[i])
                {
                    min = betterParent[i] - d * alpha.Value;
                    max = worseParent[i] + d * beta.Value;
                }
                else
                {
                    min = worseParent[i] - d * beta.Value;
                    max = betterParent[i] + d * alpha.Value;
                }
                result[i] = min + random.NextDouble() * (max - min);
            }
            return(result);
        }
 /// <summary>
 /// Performs the some positions bitflip mutation on a binary vector.
 /// </summary>
 /// <param name="random">The random number generator to use.</param>
 /// <param name="vector">The vector that should be manipulated.</param>
 /// <param name="pm">The probability a bit is flipped.</param>
 public static void Apply(IRandom random, BinaryVector vector, DoubleValue pm) {
   for (int i = 0; i < vector.Length; i++) {
     if (random.NextDouble() < pm.Value) {
       vector[i] = !vector[i];
     }
   }
 }
Exemplo n.º 37
0
        /**
         * Taken {@code weightedSampleWithReplacement} out of {@link ParticleFiltering} and extended by a minimum weight.
         * @param samples the samples to be re-sampled.
         * @param w the probability distribution on the samples.
         * @return the new set of samples.
         */
        protected ISet <P> extendedWeightedSampleWithReplacement(ISet <P> samples, double[] w)
        {
            int i = 0;

            for (; i < samples.Size(); ++i)
            {
                if (w[i] > weightCutOff)
                {
                    break;
                }
            }
            if (i >= samples.Size())
            {
                return(generateCloud(samples.Size()));                     /*If all particleCloud are below weightCutOff, generate a new set of samples, as we are lost.*/
            }
            /*WEIGHTED-SAMPLE-WITH-REPLACEMENT:*/
            double[] normalizedW = Util.normalize(w);
            ISet <P> newSamples  = CollectionFactory.CreateSet <P>();

            P[] array = samples.ToArray();
            for (i = 0; i < samples.Size(); ++i)
            {
                int selectedSample = (int)ProbUtil.sample(randomizer.NextDouble(), sampleIndexes, normalizedW);
                newSamples.Add((array[selectedSample]).Clone());
            }
            return(newSamples);
        }
Exemplo n.º 38
0
        public override void ResetLocalParameters(IRandom random)
        {
            base.ResetLocalParameters(random);
            var range = Symbol.MaxValue - Symbol.MinValue;

            Value = random.NextDouble() * range + Symbol.MinValue;
        }
Exemplo n.º 39
0
 public virtual void Randomize(IRandom random, int startIndex, int length, double min, double max) {
   double delta = max - min;
   if (length > 0) {
     for (int i = 0; i < length; i++)
       array[startIndex + i] = min + delta * random.NextDouble();
     OnReset();
   }
 }
Exemplo n.º 40
0
    /// <summary>Returns a random point on the surface of a box</summary>
    /// <param name="randomNumberGenerator">Random number generator that will be used</param>
    /// <param name="extents">Extents of the box</param>
    /// <returns>A random point on the box' surface</returns>
    /// <remarks>
    ///   The performance of this algorithm varies slightly depending on the face
    ///   that is chosen for the random point because a different number of
    ///   comparisons and subtractions will be performed.
    /// </remarks>
    public static Vector3 GenerateRandomPointOnSurface(
      IRandom randomNumberGenerator, Vector3 extents
    ) {

      // For this task, we also need the dimensions of the box
      Vector3 dimensions = extents * 2.0f;

      // Determine the area covered by the sides of the box
      float leftRightArea = dimensions.Z * dimensions.Y;
      float topBottomArea = dimensions.X * dimensions.Z;
      float frontBackArea = dimensions.X * dimensions.Y;

      // Choose which face of the box the point is going be on
      float side = (float)randomNumberGenerator.NextDouble() *
        (leftRightArea * 2.0f) * (topBottomArea * 2.0f) * (frontBackArea * 2.0f);

      // Now obtain were the point will be located
      float u = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;
      float v = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;

      // Calculate the final world space coordinates of the point
      side -= leftRightArea;
      if(side < 0.0)
        return new Vector3(-extents.X, v * extents.Y, u * extents.Z);

      side -= leftRightArea;
      if(side < 0.0)
        return new Vector3(+extents.X, v * extents.Y, u * extents.Z);

      side -= topBottomArea;
      if(side < 0.0)
        return new Vector3(u * extents.X, +extents.Y, v * extents.Z);

      side -= topBottomArea;
      if(side < 0.0)
        return new Vector3(u * extents.X, -extents.Y, v * extents.Z);

      side -= frontBackArea;
      if(side < 0.0)
        return new Vector3(u * extents.X, v * extents.Y, -extents.Z);

      else
        return new Vector3(u * extents.X, v * extents.Y, +extents.Z);
    }
Exemplo n.º 41
0
 public virtual void Randomize(IRandom random, int startIndex, int length, DoubleMatrix bounds) {
   if (length > 0) {
     for (int i = startIndex; i < startIndex + length; i++) {
       double min = bounds[i % bounds.Rows, 0];
       double max = bounds[i % bounds.Rows, 1];
       array[i] = min + (max - min) * random.NextDouble();
     }
     OnReset();
   }
 }
Exemplo n.º 42
0
 public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
   base.ShakeLocalParameters(random, shakingFactor);
   // 50% additive & 50% multiplicative
   if (random.NextDouble() < 0.5) {
     double x = NormalDistributedRandom.NextDouble(random, Symbol.ManipulatorMu, Symbol.ManipulatorSigma);
     Value = Value + x * shakingFactor;
   } else {
     double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeManipulatorSigma);
     Value = Value * x;
   }
 }
Exemplo n.º 43
0
    /// <summary>Returns a random point within a sphere</summary>
    /// <param name="randomNumberGenerator">Random number generator that will be used</param>
    /// <param name="radius">Radius of the sphere</param>
    /// <returns>A random point with the sphere</returns>
    public static Vector3 GenerateRandomPointWithin(
      IRandom randomNumberGenerator, float radius
    ) {

      // TODO: This is just an approximation. Find the real algorithm.
      float r = (float)randomNumberGenerator.NextDouble();
      r = (float)Math.Sqrt(r * r);
      r = (float)Math.Sqrt(r * r);

      return GenerateRandomPointOnSurface(randomNumberGenerator, r);

    }
Exemplo n.º 44
0
    /// <summary>
    /// Performs a random convex crossover on the two given parents.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent vector for the crossover.</param>
    /// <param name="parent2">The second parent vector for the crossover.</param>
    /// <returns>The newly created real vector, resulting from the random convex crossover.</returns>
    public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2) {
      if (parent1.Length != parent2.Length)
        throw new ArgumentException("ERROR in RandomConvexCrossover: the two parents are not of the same length");

      int length = parent1.Length;
      double[] result = new double[length];
      double factor = random.NextDouble();

      for (int i = 0; i < length; i++)
        result[i] = (factor * parent1[i]) + ((1 - factor) * parent2[i]);
      return new RealVector(result);
    }
Exemplo n.º 45
0
    /// <summary>
    /// Perfomrs a heuristic crossover on the two given parents.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="betterParent">The first parent for the crossover operation.</param>
    /// <param name="worseParent">The second parent for the crossover operation.</param>
    /// <returns>The newly created real vector, resulting from the heuristic crossover.</returns>
    public static RealVector Apply(IRandom random, RealVector betterParent, RealVector worseParent) {
      if (betterParent.Length != worseParent.Length)
        throw new ArgumentException("HeuristicCrossover: the two parents are not of the same length");

      int length = betterParent.Length;
      double[] result = new double[length];
      double factor = random.NextDouble();

      for (int i = 0; i < length; i++) {
        result[i] = betterParent[i] + factor * (betterParent[i] - worseParent[i]);
      }
      return new RealVector(result);
    }
Exemplo n.º 46
0
    /// <summary>Returns a random point on the surface of a sphere</summary>
    /// <param name="randomNumberGenerator">Random number generator that will be used</param>
    /// <param name="radius">Radius of the sphere</param>
    /// <returns>A random point on the sphere's surface</returns>
    public static Vector3 GenerateRandomPointOnSurface(
      IRandom randomNumberGenerator, float radius
    ) {

      // Choose a random longitude for the point
      float phi = (float)randomNumberGenerator.NextDouble() * MathHelper.TwoPi;

      // The z axis goes straight through the sphere and is chosen in random.
      float z = (float)randomNumberGenerator.NextDouble() * 2.0f - 1.0f;

      // From that, we'll calculate the latitude this point will have on the
      // sphere's surface.
      float theta = (float)Math.Sqrt(1.0f - z * z);

      // Calculate the final position of the point in world space
      return new Vector3(
        radius * theta * (float)Math.Cos(phi),
        radius * theta * (float)Math.Sin(phi),
        radius * z
      );

    }
Exemplo n.º 47
0
    /// <summary>Returns a random point on the perimeter of a disc</summary>
    /// <param name="randomNumberGenerator">Random number generator that will be used</param>
    /// <param name="radius">Radius of the disc</param>
    /// <returns>A random point on the disc's perimeter</returns>
    public static Vector2 GenerateRandomPointOnPerimeter(
      IRandom randomNumberGenerator, float radius
    ) {

      // Choose a random angle for the point
      float phi = (float)randomNumberGenerator.NextDouble() * MathHelper.TwoPi;

      // Calculate the final position of the point in world space
      return new Vector2(
        radius * (float)Math.Cos(phi),
        radius * (float)Math.Sin(phi)
      );

    }
    /// <summary>
    /// Performs the arithmetic crossover on some positions by taking either x = alpha * p1 + (1 - alpha) * p2 or x = p1 depending on the probability for a gene to be crossed.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent vector.</param>
    /// <param name="parent2">The second parent vector.</param>
    /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
    /// <param name="probability">The probability parameter (<see cref="ProbabilityParameter"/>).</param>
    /// <returns>The vector resulting from the crossover.</returns>
    public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue alpha, DoubleValue probability) {
      int length = parent1.Length;
      if (length != parent2.Length) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: The parent vectors are of different length.", "parent1");
      if (alpha.Value < 0 || alpha.Value > 1) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
      if (probability.Value < 0 || probability.Value > 1) throw new ArgumentException("UniformSomePositionsArithmeticCrossover: Parameter probability must be in the range [0;1]", "probability");

      RealVector result = new RealVector(length);
      for (int i = 0; i < length; i++) {
        if (random.NextDouble() < probability.Value)
          result[i] = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
        else result[i] = parent1[i];
      }
      return result;
    }
    /// <summary>
    /// Changes randomly several, but at least one, positions in the given integer <paramref name="vector"/>, according to the given probabilities.
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="vector">The integer vector to manipulate.</param>
    /// <param name="bounds"> Contains the minimum value (inclusive), maximum value (exclusive), and step size of the sampling range for 
    /// the vector element to change.</param>
    /// <param name="probability">The probability for each dimension to be manipulated..</param>
    public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds, double probability) {
      if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2) throw new ArgumentException("UniformSomePositionsManipulator: Invalid bounds specified", "bounds");
      bool atLeastOneManipulated = false;
      for (int index = 0; index < vector.Length; index++) {
        if (random.NextDouble() < probability) {
          atLeastOneManipulated = true;
          UniformOnePositionManipulator.Manipulate(random, vector, bounds, index);
        }
      }

      if (!atLeastOneManipulated) {
        UniformOnePositionManipulator.Manipulate(random, vector, bounds, random.Next(vector.Length));
      }
    }
Exemplo n.º 50
0
    public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
      base.ShakeLocalParameters(random, shakingFactor);
      // 50% additive & 50% multiplicative
      if (random.NextDouble() < 0) {
        double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu, Symbol.WeightManipulatorSigma);
        weight = weight + x * shakingFactor;
      } else {
        double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeWeightManipulatorSigma);
        weight = weight * x;
      }
#pragma warning disable 612, 618
      variableName = Symbol.VariableNames.SelectRandom(random);
#pragma warning restore 612, 618
    }
    public static TwoPointFiveMove Apply(Permutation permutation, IRandom random) {
      int length = permutation.Length;
      if (length == 1) throw new ArgumentException("Stochastic 2.5-SingleMoveGenerator: There cannot be an inversion move given a permutation of length 1.", "permutation");
      int index1 = random.Next(length - 1);
      int index2 = random.Next(index1 + 1, length);
      if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
        if (length > 3) {
          while (index2 - index1 >= length - 2)
            index2 = random.Next(index1 + 1, length);
        }
      }
      bool isInvert = random.NextDouble() > 0.5;
      return new TwoPointFiveMove(index1, index2, isInvert);

    }
    /// <summary>
    /// Performs the simulated binary crossover on a real vector. Each position is crossed with a probability of 50% and if crossed either a contracting crossover or an expanding crossover is performed, again with equal probability.
    /// For more details refer to the paper by Deb and Agrawal.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when the parents' vectors are of unequal length or when <paramref name="contiguity"/> is smaller than 0.</exception>
    /// <remarks>
    /// The manipulated value is not restricted by the (possibly) specified lower and upper bounds. Use the <see cref="BoundsChecker"/> to correct the values after performing the crossover.
    /// </remarks>
    /// <param name="random">The random number generator to use.</param>
    /// <param name="parent1">The first parent vector.</param>
    /// <param name="parent2">The second parent vector.</param>
    /// <param name="contiguity">The contiguity value that specifies how close a child should be to its parents (larger value means closer). The value must be greater or equal than 0. Typical values are in the range [2;5].</param>
    /// <returns>The vector resulting from the crossover.</returns>
    public static RealVector Apply(IRandom random, RealVector parent1, RealVector parent2, DoubleValue contiguity) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("SimulatedBinaryCrossover: Parents are of unequal length");
      if (contiguity.Value < 0) throw new ArgumentException("SimulatedBinaryCrossover: Contiguity value is smaller than 0", "contiguity");
      int length = parent1.Length;
      RealVector result = new RealVector(length);
      for (int i = 0; i < length; i++) {
        if (length == 1 || random.NextDouble() < 0.5) { // cross this variable
          double u = random.NextDouble();
          double beta = 0;
          if (u < 0.5) { // if u is smaller than 0.5 perform a contracting crossover
            beta = Math.Pow(2 * u, 1.0 / (contiguity.Value + 1));
          } else if (u > 0.5) { // otherwise perform an expanding crossover
            beta = Math.Pow(0.5 / (1.0 - u), 1.0 / (contiguity.Value + 1));
          } else if (u == 0.5)
            beta = 1;

          if (random.NextDouble() < 0.5)
            result[i] = ((parent1[i] + parent2[i]) / 2.0) - beta * 0.5 * Math.Abs(parent1[i] - parent2[i]);
          else
            result[i] = ((parent1[i] + parent2[i]) / 2.0) + beta * 0.5 * Math.Abs(parent1[i] - parent2[i]);
        } else result[i] = parent1[i];
      }
      return result;
    }
    /// <summary>
    /// Performs the polynomial mutation on a single position in the real vector.
    /// </summary>
    /// <param name="random">The random number generator to use.</param>
    /// <param name="vector">The vector that should be manipulated.</param>
    /// <param name="contiguity">A parameter describing the shape of the probability density function which influences the strength of the manipulation.</param>
    /// <param name="maxManipulation">The maximum strength of the manipulation.</param>
    public static void Apply(IRandom random, RealVector vector, DoubleValue contiguity, DoubleValue maxManipulation) {
      if (contiguity.Value < 0) throw new ArgumentException("PolynomialAllPositionManipulator: Contiguity value is smaller than 0", "contiguity");
      double u, delta = 0;

      for (int index = 0; index < vector.Length; index++) {
        u = random.NextDouble();
        if (u < 0.5) {
          delta = Math.Pow(2 * u, 1.0 / (contiguity.Value + 1)) - 1.0;
        } else if (u >= 0.5) {
          delta = 1.0 - Math.Pow(2.0 - 2.0 * u, 1.0 / (contiguity.Value + 1));
        }

        vector[index] += delta * maxManipulation.Value;
      }
    }
Exemplo n.º 54
0
    /// <summary>
    /// Performs a uniform crossover between two binary vectors.
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="parent1">The first parent for crossover.</param>
    /// <param name="parent2">The second parent for crossover.</param>
    /// <returns>The newly created binary vector, resulting from the uniform crossover.</returns>
    public static BinaryVector Apply(IRandom random, BinaryVector parent1, BinaryVector parent2) {
      if (parent1.Length != parent2.Length)
        throw new ArgumentException("UniformCrossover: The parents are of different length.");

      int length = parent1.Length;
      bool[] result = new bool[length];

      for (int i = 0; i < length; i++) {
        if (random.NextDouble() < 0.5)
          result[i] = parent1[i];
        else
          result[i] = parent2[i];
      }

      return new BinaryVector(result);
    }
    public static PotvinEncoding Apply(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2, IVRPProblemInstance problemInstance, bool allowInfeasible) {
      PotvinEncoding child = parent1.Clone() as PotvinEncoding;
      Tour newTour = new Tour();

      int cities = problemInstance.Cities.Value;

      if (cities > 0) {
        int breakPoint1 = random.Next(1, cities + 1);
        Tour tour1 = FindRoute(child, breakPoint1);
        breakPoint1 = tour1.Stops.IndexOf(breakPoint1);

        for (int i = 0; i < breakPoint1; i++)
          newTour.Stops.Add(tour1.Stops[i]);

        int breakPoint2 = random.Next(1, cities + 1);
        Tour tour2 = FindRoute(parent2, breakPoint2);
        breakPoint2 = tour2.Stops.IndexOf(breakPoint2);

        for (int i = breakPoint2; i < tour2.Stops.Count; i++)
          newTour.Stops.Add(tour2.Stops[i]);

        int tour1Index = child.Tours.IndexOf(tour1);
        child.Tours.Remove(tour1);
        child.Tours.Insert(tour1Index, newTour);

        foreach (int city in tour1.Stops)
          if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
            child.Unrouted.Add(city);

        foreach (int city in tour2.Stops)
          if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
            child.Unrouted.Add(city);

        if (Repair(random, child, newTour, problemInstance, allowInfeasible) || allowInfeasible) {
          return child;
        } else {
          if (random.NextDouble() < 0.5)
            return parent1.Clone() as PotvinEncoding;
          else
            return parent2.Clone() as PotvinEncoding;
        }
      } else {
        return child;
      }
    }
    /// <summary>
    /// Perfomrs a heuristic crossover on the two given parents.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="betterParent">The first parent for the crossover operation.</param>
    /// <param name="worseParent">The second parent for the crossover operation.</param>
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <returns>The newly created integer vector, resulting from the heuristic crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector betterParent, IntegerVector worseParent, IntMatrix bounds) {
      if (betterParent.Length != worseParent.Length)
        throw new ArgumentException("HeuristicCrossover: the two parents are not of the same length");

      int length = betterParent.Length;
      var result = new IntegerVector(length);
      double factor = random.NextDouble();

      int min, max, step = 1;
      for (int i = 0; i < length; i++) {
        min = bounds[i % bounds.Rows, 0];
        max = bounds[i % bounds.Rows, 1];
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
        max = FloorFeasible(min, max, step, max - 1);
        result[i] = RoundFeasible(min, max, step, betterParent[i] + factor * (betterParent[i] - worseParent[i]));
      }
      return result;
    }
    /// <summary>
    /// Performs the arithmetic crossover on some positions by taking either x = alpha * p1 + (1 - alpha) * p2 or x = p1 depending on the probability for a gene to be crossed.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent vector.</param>
    /// <param name="parent2">The second parent vector.</param>
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
    /// <param name="probability">The probability parameter (<see cref="ProbabilityParameter"/>).</param>
    /// <returns>The vector resulting from the crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds, DoubleValue alpha, DoubleValue probability) {
      int length = parent1.Length;
      if (length != parent2.Length) throw new ArgumentException("RoundedUniformArithmeticCrossover: The parent vectors are of different length.", "parent1");
      if (alpha.Value < 0 || alpha.Value > 1) throw new ArgumentException("RoundedUniformArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
      if (probability.Value < 0 || probability.Value > 1) throw new ArgumentException("RoundedUniformArithmeticCrossover: Parameter probability must be in the range [0;1]", "probability");

      var result = new IntegerVector(length);
      for (int i = 0; i < length; i++) {
        if (random.NextDouble() < probability.Value) {
          int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
          if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
          max = FloorFeasible(min, max, step, max - 1);
          double value = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
          result[i] = RoundFeasible(min, max, step, value);
        } else result[i] = parent1[i];
      }
      return result;
    }
    public static Schedule Apply(IRandom random, Schedule parent1, Schedule parent2, ItemList<Job> jobData, double mutProp) {
      var child = new Schedule(parent1.Resources.Count);

      //Reset scheduled tasks in result
      foreach (Job j in jobData) {
        foreach (Task t in j.Tasks) {
          t.IsScheduled = false;
        }
      }

      //GT-Algorithm
      //STEP 0 - Compute a list of "earliest operations"
      ItemList<Task> earliestTasksList = GTAlgorithmUtils.GetEarliestNotScheduledTasks(jobData);
      while (earliestTasksList.Count > 0) {
        //STEP 1 - Get earliest not scheduled operation with minimal earliest completing time
        Task minimal = GTAlgorithmUtils.GetTaskWithMinimalEC(earliestTasksList, child);
        int conflictedResourceNr = minimal.ResourceNr;
        Resource conflictedResource = child.Resources[conflictedResourceNr];

        //STEP 2 - Compute a conflict set of all operations that can be scheduled on the conflicted resource
        ItemList<Task> conflictSet = GTAlgorithmUtils.GetConflictSetForTask(minimal, earliestTasksList, jobData, child);

        //STEP 3 - Select a task from the conflict set
        int progressOnResource = conflictedResource.Tasks.Count;
        Task selectedTask = null;
        if (random.NextDouble() < mutProp) {
          //Mutation
          selectedTask = conflictSet[random.Next(conflictSet.Count)];
        } else {
          //Crossover
          selectedTask = SelectTaskFromConflictSet(conflictSet, ((random.Next(2) == 0) ? parent1 : parent2), conflictedResourceNr, progressOnResource);
        }

        //STEP 4 - Add the selected task to the current schedule 
        selectedTask.IsScheduled = true;
        double startTime = GTAlgorithmUtils.ComputeEarliestStartTime(selectedTask, child);
        child.ScheduleTask(selectedTask.ResourceNr, startTime, selectedTask.Duration, selectedTask.JobNr);

        //STEP 5 - Back to STEP 1
        earliestTasksList = GTAlgorithmUtils.GetEarliestNotScheduledTasks(jobData);
      }

      return child;
    }
    /// <summary>
    /// Performs a local crossover on the two given parent vectors.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent for the crossover operation.</param>
    /// <param name="parent2">The second parent for the crossover operation.</param>
    /// <returns>The newly created integer vector, resulting from the local crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds) {
      if (parent1.Length != parent2.Length)
        throw new ArgumentException("RoundedLocalCrossover: the two parents are not of the same length");

      double factor;
      int length = parent1.Length;
      var result = new IntegerVector(length);

      int min, max, step = 1;
      for (int i = 0; i < length; i++) {
        min = bounds[i % bounds.Rows, 0];
        max = bounds[i % bounds.Rows, 1];
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
        max = FloorFeasible(min, max, step, max - 1);
        factor = random.NextDouble();
        result[i] = RoundFeasible(min, max, step, (factor * parent1[i]) + ((1 - factor) * parent2[i]));
      }
      return result;
    }
Exemplo n.º 60
0
    /// <summary>
    /// Performs the cyclic crossover on <paramref name="parent1"/> and <paramref name="parent2"/>.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are not of equal length.</exception>
    /// <exception cref="InvalidOperationException">Thrown if the numbers in the permutation elements are not in the range [0;N) with N = length of the permutation.</exception>
    /// <remarks>
    /// First this method randomly determines from which parent to start with equal probability.
    /// Then it copies the first cycle from the chosen parent starting from index 0 in the permutation.
    /// After the cycle is complete it copies the next cycle starting from the index closest to 0 which was not yet copied from the other parent.
    /// It continues to switch between parents for each completed cycle until no new cycle is found anymore.<br /><br />
    /// The stochasticity of this operator is rather low. There are only two possible outcomes for a given pair of parents.
    /// </remarks>
    /// <exception cref="ArgumentException">Thrown if the two parents are not of equal length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The parent scope 1 to cross over.</param>
    /// <param name="parent2">The parent scope 2 to cross over.</param>
    /// <returns>The created cross over permutation as int array.</returns>
    public static Permutation Apply(IRandom random, Permutation parent1, Permutation parent2) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("CyclicCrossover: The parent permutations are of unequal length.");
      int length = parent1.Length;
      int[] result = new int[length];
      bool[] indexCopied = new bool[length];
      int[] invParent1 = new int[length];
      int[] invParent2 = new int[length];

      // calculate inverse mappings (number -> index) for parent1 and parent2
      try {
        for (int i = 0; i < length; i++) {
          invParent1[parent1[i]] = i;
          invParent2[parent2[i]] = i;
        }
      }
      catch (IndexOutOfRangeException) {
        throw new InvalidOperationException("CyclicCrossover: The permutation must consist of numbers in the interval [0;N) with N = length of the permutation.");
      }

      // randomly choose whether to start copying from parent1 or parent2
      bool copyFromParent1 = ((random.NextDouble() < 0.5) ? (false) : (true));

      int j = 0;
      do {
        do {
          if (copyFromParent1) {
            result[j] = parent1[j]; // copy number at position j from parent1
            indexCopied[j] = true;
            j = invParent2[result[j]]; // set position j to the position of the copied number in parent2
          } else {
            result[j] = parent2[j]; // copy number at position j from parent2
            indexCopied[j] = true;
            j = invParent1[result[j]]; // set position j to the position of the copied number in parent1
          }
        } while (!indexCopied[j]);
        copyFromParent1 = !copyFromParent1;
        j = 0;
        while (j < length && indexCopied[j]) j++;
      } while (j < length);

      return new Permutation(parent1.PermutationType, result);
    }