Xpoint
   [напомнить пароль]

Кроссплатформенный генератор псевдослучайных чисел

Метки: [без меток]
2006-09-22 19:34:39 [обр] vvvua[досье]
Есть некоторое количиство объектов (n=100..200). Эти объекты описываются 10-ю значениями.
При хранении этих объектов в базе для 100000 наборов - слишком много расходов.
Приняли решение заменить хранение n-объектов на формулу генерации. Генерировать нужно на основании описания (seed), которое хранить в базе для каждого набора. Хочется не сильно сложный способ реализовать для приминения на C++,C# и Python.
Видел реализации на С. Но довольно сложные. Мне бы по-проще для n около 1000.
Кто-то чем-то помочь может?
Можно, конечно, как в Кнуте описано, но явно есть что-то легче.
Заранее спасибо.
спустя 2 дня 22 часа [обр] vvvua[досье]
сообщение промодерировано

Да. Море ответов.
Решение нашли.
При использовании типа double в C# результаты даются те-же.
Вот код на python:

s=0.0;
a=0.0;
c=0.0;
m=0.0;

def init_prandom(seed):
    global s
    global a
    global c
    global m
    a=seed;
    c=1013904223;
    m=1664525;
    t=a*s+c;
    s=fmod(t,m)
    
    
def prandom():
    global s
    global a
    global c
    global m
    
    t=a*s+c;
    s=fmod(t,m)
    return int(s)

def prandom_minmax(min,max):
    
    return min+(prandom()%(max-min+1));

Приминение:

        seed=213421;
   init_prandom(seed);
   for i in range(0,5000):
      print prandom_minmax(-500,500);
спустя 14 минут [обр] Владимир Палант(27/4445)[досье]
Я, правда, не читал Кнута, но сдается мне, что именно этот алгоритм там описан на первом месте... Причем цифры у вас те же, что и здесь, вот только использует их этот код как-то неправильно.
спустя 1 час 8 минут [обр] vvvua[досье]

Алгоритм в Кнуте описан.
Взято решение вот отсюда:
http://www.uni-vologda.ac.ru/students/pm02/bmv/pseudorandom.html

Особо времени не уделялось на анализ. Результат удовлетворительный.

спустя 33 минуты [обр] Владимир Палант(27/4445)[досье]

Так там правильное описание. Вы неправильно константы подставляете. Там ведь написано, что a должно быть равно 1664525, c равно 1013904223. m равно 2^32, соответственно операция modulo выполняется автоматически — это просто переполнение (предполагаю, что ваш int 32-битный). И зачем рассчитывать случайное число при инициализации? Там просто нужно установить для s значение seed.

Выполнять же все эти операции с double-числами не стоит. Если вам нужно дробное число в интервале от 0 до 1, как его выдает функция rand() во многих языках программирования — просто разделите ваш целочисленный результат на m.

спустя 1 минуту [обр] Владимир Палант(27/4445)[досье]
PS: Очень советую все-таки разобраться с Кнутом и понять, что этот алгоритм делает. Чтобы больше не говорить, что "результат удовлетворительный".
спустя 22 часа [обр] vvvua[досье]
сообщение промодерировано

Да, спасибо, действительно ошибся.
Сейчас init имеет вид:

def init_prandom(seed):
    global s
    global a
    global c
    global m
    
    c=1013904223;
    a=1664525;
    #maxint=2147483647;
    #print "maxint=%s"%sys.maxint;
    m=2147483647
    s=seed

P.S. Присвоение числа сделано для того, чтобы числа одинаковые были на 32 или 64 бит платформе
P.P.S. не нашел ссылку на форматирование, сорри. Сайт оч медленно грузится, а времени мало.

Powered by POEM™ Engine Copyright © 2002-2005