Exemplo n.º 1
0
        /// <summary>
        /// Performs a high-quality random shuffling of the list.
        /// Uses a user-provided random number generator, which
        /// </summary>
        /// <typeparam name="T">The type of elements in the list.</typeparam>
        /// <typeparam name="N">The type of numbers generated by the random numbers generator.</typeparam>
        /// <param name="list">The calling list object.</param>
        /// <param name="generator">A floating-point random number generator for the <typeparamref name="N"/> type.</param>
        /// <param name="numericComparer">An optional numeric comparer for <typeparamref name="N"/> type. If <c>null</c>, a standard comparer will be used (if exists, otherwise, an exception will be thrown).</param>
        public static void Shuffle <T, N>(this IList <T> list, IRandomFloatingPoint <N> generator, IComparer <N> numericComparer = null)
        {
            Contract.Requires <ArgumentNullException>(list != null, "list");
            Contract.Requires <ArgumentNullException>(generator != null, "generator");

            if (numericComparer == null)
            {
                numericComparer = Comparer <N> .Default;
            }

            // Генерируем массив пар со случайными ключами,
            // сортируем их по ключу (а значения оказываются случайно перемешанными).

            List <KeyValuePair <N, T> > pairList = new List <KeyValuePair <N, T> >(list.Count);

            foreach (T element in list)
            {
                pairList.Add(new KeyValuePair <N, T>(generator.Next_SingleInterval(), element));
            }

            IComparer <KeyValuePair <N, T> > pairComparer = numericComparer.createKVPComparerOnKey <N, T>();

            pairList.Sort(pairComparer);

            // Восстанавливаем.

            for (int i = 0; i < pairList.Count; i++)
            {
                list[i] = pairList[i].Value;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Constructs a Fibonacci lagged pseudo-random number generator using the lag values and
        /// another generator for the first sequence members.
        ///
        /// Examples of recommended lag values:
        ///
        /// a) 17; 5
        /// b) 55; 24
        /// c) 97; 33.
        ///
        /// It is not recommended to provide random lag values as it will affect
        /// the quality of the generator randomization.
        /// </summary>
        /// <param name="firstGenerator">The IRandom(T) implementer object to receive the first values of the pseudo-random sequence.</param>
        /// <param name="a">The first lag of the fibonacci generator. Optional. By default, equals 97.</param>
        /// <param name="b">The second lag of the fibonacci generator. Optional. By default, equals 33.</param>
        public RandomLaggedFibonacci(IRandomFloatingPoint <double> firstGenerator, int a = 97, int b = 33)
        {
            this.a = a;
            this.b = b;

            this.max = Math.Max(a, b);

            for (int i = 0; i < max; i++)
            {
                list.AddLast(firstGenerator.Next_SingleInterval());
            }

            xkmaNode = list.First;
            xkmbNode = list.First;

            for (int i = 0; i < max - a; i++)
            {
                xkmaNode = xkmaNode.Next;
            }

            for (int i = 0; i < max - b; i++)
            {
                xkmbNode = xkmbNode.Next;
            }

            return;
        }
Exemplo n.º 3
0
            /// <summary>
            /// Initializes the wrapper instance with a floating-point generator
            /// and a numeric interval.
            /// </summary>
            /// <param name="gen">A floating-point generator.</param>
            /// <param name="minimum">The lower inclusive boundary for generated numbers.</param>
            /// <param name="maximum">The upper exclusive boundary for generated numbers.</param>
            public ___RandomFP_UnboundedWrapper(IRandomFloatingPoint <T> gen, T minimum, T maximum)
            {
                Contract.Requires <ArgumentNullException>(gen != null, "gen");
                Contract.Requires <ArgumentException>(Numeric <T, C> .Calculator.mor(maximum, minimum), "The upper boundary of generated values should be bigger than the lower boundary.");

                this.Generator = gen;
                this.Minimum   = minimum;
                this.Maximum   = maximum;
            }
Exemplo n.º 4
0
        public RandomNormalBoxMuller(IRandomFloatingPoint <T> uniformGenerator, T mean, T standardDeviation, Func <T, T> naturalLogarithmFunction, Func <T, T> squareRootFunction)
        {
            this.generator = uniformGenerator;

            this.mean = mean;
            this.standardDeviation = standardDeviation;

            this.naturalLogarithmFunction = naturalLogarithmFunction;
            this.squareRootFunction       = squareRootFunction;

            this.nextAvailable = false;
            this.next          = default(T);

            this.transformFunction = delegate(T value, T squareSum)
            {
                return((Numeric <T, C>)value * squareRootFunction(-Numeric <T, C> ._2 * naturalLogarithmFunction(squareSum) / squareSum));
            };
        }
Exemplo n.º 5
0
        // ------------------------------------------------------------------------------
        // ----------------------------- Floating-point generator extensions ------------

        /// <summary>
        /// Makes use of an <c>IRandomFloatingPoint&lt;<typeparamref name="T"/>&gt;</c>
        /// instance and enables it to produce values in an arbitrary range (i.e. wraps it
        /// around to make it an <c>IRandomBounded&lt;<typeparamref name="T"/>&gt;</c> object).
        /// </summary>
        /// <remarks>
        /// Because the wrapper object will use multiplication scaling to produce random numbers,
        /// please notice that for bigger intervals the quality of the distribution
        /// may seriously suffer due to scale irregularity of some numeric types, e.g. <c>double</c>.
        /// </remarks>
        /// <typeparam name="T">The type of numbers generated by <paramref name="gen"/>.</typeparam>
        /// <typeparam name="C">A calculator type for the <typeparamref name="T"/> type.</typeparam>
        /// <param name="gen">An <c>IRandomFloatingPoint&lt;<typeparamref name="T"/>&gt;</c> instance.</param>
        /// <returns>
        /// An <c>IRandomBounded&lt;<typeparamref name="T"/>&gt;</c> object that makes use
        /// of <paramref name="gen"/> and produces values in arbitrary ranges by scaling.</returns>
        public static IRandomBounded <T> TreatAsBoundedGenerator <T, C>(this IRandomFloatingPoint <T> gen) where C : ICalc <T>, new()
        {
            return(new ___RandomFP_BoundedWrapper <T, C>(gen));
        }
Exemplo n.º 6
0
 /// <summary>
 /// Initializes the wrapper instance with a floating-point generator.
 /// </summary>
 /// <param name="gen">A floating-point generator for the type <typeparamref name="T"/></param>
 public ___RandomFP_BoundedWrapper(IRandomFloatingPoint <T> gen)
 {
     Contract.Requires <ArgumentNullException>(gen != null, "gen");
     this.Generator = gen;
 }
Exemplo n.º 7
0
 /// <summary>
 /// Makes use of an <c>IRandomFloatingPoint&lt;<typeparamref name="T"/>&gt;</c>
 /// instance and enables it to produce values in a constant, pre-set range (i.e. wraps it
 /// around to make it an as an <c>IRandomUnbounded&lt;<typeparamref name="T"/>&gt;</c> object).
 /// </summary>
 /// <remarks>
 /// Because the wrapper object will use multiplication scaling to produce random numbers,
 /// please notice that for bigger intervals the quality of the distribution
 /// may seriously suffer due to scale irregularity of some numeric types, e.g. <c>double</c>.
 /// </remarks>
 /// <typeparam name="T">The type of numbers generated by <paramref name="gen"/>.</typeparam>
 /// <typeparam name="C">A calculator type for the <typeparamref name="T"/> type.</typeparam>
 /// <param name="gen">An <c>IRandomFloatingPoint&lt;<typeparamref name="T"/>&gt;</c> instance.</param>
 /// <param name="minimum">The lower inclusive boundary for generated values.</param>
 /// <param name="maximum">The upper exclusive boundary for generated values.</param>
 /// <returns>
 /// An <c>IRandomBounded&lt;<typeparamref name="T"/>&gt;</c> object that makes use
 /// of <paramref name="gen"/> and produces values in arbitrary ranges by scaling.</returns>
 public static IRandomUnbounded <T> TreatAsUnboundedGenerator <T, C>(this IRandomFloatingPoint <T> gen, T minimum, T maximum) where C : ICalc <T>, new()
 {
     return(new ___RandomFP_UnboundedWrapper <T, C>(gen, minimum, maximum));
 }
Exemplo n.º 8
0
 public RandomNormalBoxMuller(IRandomFloatingPoint <T> uniformGenerator, Func <T, T> naturalLogarithmFunction, Func <T, T> squareRootFunction)
     : this(uniformGenerator, Numeric <T, C> .Zero, Numeric <T, C> ._1, naturalLogarithmFunction, squareRootFunction)
 {
 }