Crappy Генератор случайных чисел - PullRequest
6 голосов
/ 08 октября 2009

Это может показаться странным вопросом, но где я могу найти генератор случайных чисел, который работает на C или C ++, который не очень хорош?

Контекст: я создаю некоторое программное обеспечение для построения древовидных графиков и тестирую его, используя многозначные случайные числа (поэтому каждая цифра становится узлом дерева) Генератор случайных чисел, который я использовал - тот, который поставляется с компилятором GNU C ++ - дает мне хороший разброс значений. Это хорошо, но я хочу посмотреть, как выглядит таблица, когда числа объединяются и становятся менее однородными.

Кто-нибудь может предложить генератор случайных чисел, который, как было доказано, не так уж случайен?

(О, любой, кто ссылается на xkcd и / или предлагает мне просто вернуть 4, получит сарказм в ответ).

Ответы [ 11 ]

8 голосов
/ 08 октября 2009

Я всегда думал о randu как о крестном отце плохих генераторов случайных чисел.

3 голосов
/ 08 октября 2009

Библиотека Boost предлагает функции для генерации случайных значений, распределенных по различным неоднородным распределениям, включая нормальное распределение, которое может генерировать деревья интересной формы.

3 голосов
/ 08 октября 2009

Реализовать довольно короткий регистр сдвига с линейной обратной связью с помощью битовой манипуляции в C.

Большинство опубликованных материалов по LFSR будут сконцентрированы на максимальных последовательностях, но похоже, что вы могли бы саботировать один из них, чтобы получить более короткую последовательность, с небольшими экспериментами.

2 голосов
/ 08 октября 2009

Стандарт С предлагает:

static unsigned long int next = 1;

int rand(void) // RAND_MAX assumed to be 32767
{
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

void srand(unsigned int seed)
{
    next = seed;
}

Как простой линейный конгруэнтный генератор (LCG), он не плохой (есть много худших наборов констант, которые вы можете использовать), но это, конечно, не хороший генератор псевдослучайных чисел по сравнению с другими членами вселенной криптографических и почти криптографических генераторов псевдослучайных чисел. Это может быть достаточно плохо для вас, или вы можете проконсультироваться с Кнутом, том 2, чтобы найти другие неверные наборы чисел. (Моя (старая) копия Седжвика имеет довольно короткую главу 35 о случайных числах с некоторыми иллюстрациями плохих констант.)

1 голос
/ 08 октября 2009

Глава 7 книги «Численные рецепты в C » посвящена различным генераторам случайных чисел. Раздел 7.7 охватывает квази- (то есть суб-) случайные последовательности.

1 голос
/ 08 октября 2009

Использовать генератор случайных чисел ( Страница Википедии ) с ограничениями.

Некоторые другие возможности: UChicago , UMich , FSU

1 голос
/ 08 октября 2009

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

1 голос
/ 08 октября 2009

C ++ решение:

class ClumpedRandom
{
  public:
    ClumpedRandom(int maxClumpSize) 
     : mMaxClump(maxClumpSize)
     , mCurrentClumpSize(0)
     , mCurrentCount(0)
    {
       if (!sInitialized) {
         sInitialized = true;
         srand(time(NULL));
       } 
    }

    int operator()()
    {
      if (++mCurrentCount >= mCurrentClumpSize) {
        // Need a new clump:
        mCurrentClumpSize = rand() % mMaxClump;
        mCurrentCount = 0;
        mCurrentValue = rand();
      }

      return mCurrentValue;   
    }


  private:
    static bool sInitialized;
    int mMaxClump;
    int mCurrentClumpSize;
    int mCurrentCount;
    int mCurrentValue;
};

Создает случайные последовательности длин не более maxClumpSize экземпляров с одинаковым значением случайного числа. (Я не сказал это очень ясно ... надеюсь, вы поняли идею).

0 голосов
/ 22 января 2010

Часто для дрянных случайных чисел, а мне обычно нужны детерминированные числа, я вычисляю синусы и косинусы простых выражений со значениями большого числа и фазовой модуляцией. Обычно я генерирую цвета в двух измерениях для графических целей («процедурные текстуры» и т. Д.), Поэтому приведу такой пример в общем псевдокоде:

for i=1,N
  for j=1,N
    value[i*n+j] = sin(51*i*i+cos(80*j)) + sin(300*j+3*sin(111*i-j))

Гарантированно не пройдут самые серьезные тесты на случайность. Результаты дрянные, что полезно для искусства.

Забавно сидеть и играть с такими формулами в интерактивной графической среде, такой как Matlab или Python с numpy и matplotlib.

0 голосов
/ 08 октября 2009

На самом деле функция rand () действительно довольно плохая. Я использую GameRand , который ДЕЙСТВИТЕЛЬНО прост и дает приличные результаты, но он все еще может быть недостаточно хреновым для вас.

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