Как написать линейный конгруэнтный генератор (LCG) в C #?Или есть какие-то известные реализации? - PullRequest
3 голосов
/ 14 октября 2010

Я хочу создать случайный массив последовательностей, которые повторяются и используют каждое число только один раз. Например, при диапазоне от 0 до 9 с двумя разными семенами вы можете получить

Seed 1: 7 3 5 9 0 8 1 2 6 4 | 7 3 5 9 0 8 1 2 6 4 | 7 3 5 9 0 8 1 2 6 4
Seed 2: 2 5 7 1 4 9 6 8 3 0 | 2 5 7 1 4 9 6 8 3 0 | 2 5 7 1 4 9 6 8 3 0

Из того, что я понимаю, линейный конгруэнтный генератор случайных чисел или LCRNG или LCG может дать мне это http://en.wikipedia.org/wiki/Linear_congruential_generator

Любая идея, если реализация существует в C # или как я бы начал писать ее.

Чем Mersenne Twister отличается от LCG?

Не уверен, что на все мои вопросы дан ответ, но вот что я в итоге использовал. Поскольку я ограничиваю размер выборки диапазоном значений от макс. До мин., Я выбираю другое простое число, которое остается статичным, пока дается одно и то же начальное начальное число. Я делаю это, потому что я хочу, чтобы одна и та же последовательность давала одинаковое начальное число и одинаковые минимальные / максимальные границы для повторяемости тестирования.

Пожалуйста, критикуйте все, что я здесь делаю, это просто то, что я придумал в один миг:

using System;
using System.Collections.Generic;

namespace FULLCYCLE
{
    public class RandomNumber
    {
        private int _value;
        private int _prime;
        private static List<int> primes = new List<int>()
        {
            11,
            23,
            47,
            97,
            797,
            1597,
            6421,
            25717,
            51437,
            102877,
            411527,
            823117,
            1646237,
            3292489,
            6584983,
            13169977,
            26339969,
            52679969,
            105359939,
            210719881,
            421439783,
            842879579,
            1685759167
        };

        public RandomNumber( int seed )
        {
            _prime = primes[seed%primes.Count];
            _value = seed;
        }

        public int Next( int min, int max )
        {
            int maxrate = (max-min+1);
            if (_value > maxrate)
            {
                _value = _value % maxrate;
            }

            _value = (_value + _prime) % maxrate;
            return _value + min;
        }
    }
}

Ответы [ 2 ]

1 голос
/ 15 октября 2010

Относительно вашего редактирования, есть несколько проблем с вашей LCG как генератором случайных чисел ...

  1. Это может привести к очевидным паттернам:

    // generates 3, 4, 5, 6, 7, 8, 9, 0, 1, 2
    var rng = new RandomNumber(42);
    for (int i = 0; i < 10; i++) Console.WriteLine(rng.Next(0, 9));
    
  2. Он может повторяться:

    // generates 579, 579, 579, 579, 579, 579, 579, 579, 579, 579
    var rng = new RandomNumber(123);
    for (int i = 0; i < 10; i++) Console.WriteLine(rng.Next(456, 51892));
    

Существует множество других комбинаций семян / мин / макс, которые могут привести к проблемным результатам.

1 голос
/ 14 октября 2010

Почему бы просто не использовать существующий класс Random и Knuth shuffle на входной последовательности?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...