Как в C++ сгенерировать случайные числа по нормальному закону распределения?
Есть ли какие-нибудь библиотечные функции для генерирования случайных чисел по нормальному закону распределения?
Если нет таких библиотечных функций, то как это сделать?
1613 г. = 2024 г.
Re: Генерация случайных чисел по нормальному закону распределения
Здравствуйте, RussianFellow, Вы писали:
RF>Как в C++ сгенерировать случайные числа по нормальному закону распределения? RF>Есть ли какие-нибудь библиотечные функции для генерирования случайных чисел по нормальному закону распределения? RF>Если нет таких библиотечных функций, то как это сделать?
Если интересует, как задача генерации случайных чисел по заданному распределению решается в общем виде — см. "производящая функция".
К сожалению, интеграл функции ошибок (erf), тоже появились в с++11.
Re: Генерация случайных чисел по нормальному закону распреде
Здравствуйте, RussianFellow, Вы писали:
RF>Как в C++ сгенерировать случайные числа по нормальному закону распределения? RF>Есть ли какие-нибудь библиотечные функции для генерирования случайных чисел по нормальному закону распределения? RF>Если нет таких библиотечных функций, то как это сделать?
Элементарно: вот код на lua
function normal()
local a,b=math.random(),math.random()
return
math.sqrt(-2*math.log(a))*math.cos(2*math.pi*b),
math.sqrt(-2*math.log(b))*math.sin(2*math.pi*a)
end
Эта функция возвращает пару чисел распределенных по нормальному закону
Здравствуйте, Chorkov, Вы писали:
C>Здравствуйте, RussianFellow, Вы писали:
RF>>Как в C++ сгенерировать случайные числа по нормальному закону распределения? RF>>Есть ли какие-нибудь библиотечные функции для генерирования случайных чисел по нормальному закону распределения? RF>>Если нет таких библиотечных функций, то как это сделать?
C>C++11 : https://en.cppreference.com/w/cpp/numeric/random/normal_distribution C>Если C++11 недоступен, то boost.
C>Если интересует, как задача генерации случайных чисел по заданному распределению решается в общем виде — см. "производящая функция". C>К сожалению, интеграл функции ошибок (erf), тоже появились в с++11.
А написать реализацию его вычисления 99% современных программистов не способны.
По первой ссылке в гугле, ту что сможете скачать и поставить.
P.S. С удовольствием читаю ваши вопросы. Мне вот интересно, у вас есть хотя-бы один завершённый коммерческий проект? Не обязательно свой, пойдёт и работа обычным программистом. Просто вы уже много лет задаёте странные вопросы, в том числе которые элементарно гуглятся.
Re[3]: Генерация случайных чисел по нормальному закону распределения
Здравствуйте, Шахтер, Вы писали:
Ш>А написать реализацию его вычисления 99% современных программистов не способны.
Да я думаю вспомнить что такое нормально распределение и что оно распределяет не смогут 60% программистов =\
Sic luceat lux!
Re: Генерация случайных чисел по нормальному закону распреде
Здравствуйте, RussianFellow, Вы писали:
RF>Как в C++ сгенерировать случайные числа по нормальному закону распределения?
Биномиальное распределение при больших N приближается к нормальному
Треугольник Паскаля тоже
Их легко реализовать, главное переполнение контролировать
RF>Если нет таких библиотечных функций, то как это сделать?
Обычно, все сложные распределения моделируются через равномерно распределенные случайные величины (а их моделировать достаточно просто). Для нормального распределения можно применить Преобразование Бокса-Мюллера. Это, думаю, самый простой способ. Код на ЛУА kov_serg привел выше
Здравствуйте, Kernan, Вы писали:
Ш>>А написать реализацию его вычисления 99% современных программистов не способны. K>Да я думаю вспомнить что такое нормально распределение и что оно распределяет не смогут 60% программистов =\
Я думаю, что нормальные люди, нормальным и естественным распределением считают — равномерное. И не надо заблуждаться на счет их умственных способностей.
Нормальное же распределение получило своё имя совершенно неоправданно, потому, что никоим образом данное распределение в человеческом мозгу нормальным считаться не может (ну может конечно — у упоротых математикой на голову).
А программисты, кто вообще слышал о функции Гаусса, либо о колоколо-образном распределении, либо кто с этим сталкивался, безусловно смогут его реализовать с необходимыми характеристиками. В добавок математически-правильное распределение тоже нужно далеко не всегда, на практике можно увидеть необходимость генерации случайного числа по заданной форме "колокола" (bell-shape), при чем никакими "нормальными" формулами её разумеется никто описывать не будет, т.к. в нормальном софте — пользователь задаёт саму кривую а не какие-то там формулы.
Поэтому рассказы про то что там не умеют 60% это такое себе занятие, и нытье по вещам о которых слушал в университете N десятков лет назад — мягко говоря странны. Те кто слышал и в курсе — при необходимости, даже если забыли — подымут нужную информацию за 5 минут. Те кто не в курсе терминологии видимо не программисты и не математики по образованию, и возможно им неведом раздел статистики вообще — но так и механики же нам прощают, когда мы ебалду называем ****ой, вместо лонжерона, ляды и прочих куда более заковыристых терминов?
Re[2]: Генерация случайных чисел по нормальному закону распреде
Здравствуйте, TailWind, Вы писали:
TW>У этой формулы есть проблема
У реализации может быть, но алгоритм не причем. TW>Она справедлива, если на вход подают непрерывную случайную величину TW>rand() в C++ возвращает дискретные значения
так непрерывные значения мы моделируем дискретными, если не хватает то увеличиваем разрядность.
rand — 15bit => 4*15=60 что больше чем 52бита мантисы double
Это проблема конкретной реализации. Замените rand на более православный генератор.
И вообще в c++ есть сразу готовые библиотеки для нормального распределения.
TW>Соответственно на выходе у вас получится, тоже дискретное распределение
И что вас смущает. Выбирайте рабочие диапазоны где это не критично. Не используйте дальние хвосты.
Или возьмите проверенные варианты: https://www.netlib.org/random/index.html
Re[3]: Генерация случайных чисел по нормальному закону распр
Эта функция возвращает пару чисел распределенных по нормальному закону TW>У этой формулы есть проблема TW>Она справедлива, если на вход подают непрерывную случайную величину TW>Что не клёво, если вы хотите строить графики или проверять статистические теоремы
LOL. Если вы придрались к этому аспекту, то у вас явная проблема в приоритетах
В предложенной функции есть куда бóльший недостаток.
Его проще всего показать на картинке. Раз функция генерирует пары чисел (x, y), то поставим точку с этими координатами на плоскости и нарисуем плотность такого распределения:
Слева миллион точек полученных вызовом numpy.random.normal. А справа вариант, генерируемый функцией за авторством kov_serg.
Правда ведь правый вариант выглядит немного не похожим на нормальное распределение?
То есть проблема функции в том, что она хотя и генерирует числа с нормальным распределением, но даёт независимость только y отдельных компонент (только у первых чисел из пары или только у вторых), а всё множество не независимо.
Это примерно как если сгенерировать последовательность из чисел U = [uniform_random()]. Она случайная и элементы независимы. И последовательность чисел V = [(1 — x) for x in U] тоже случайная и в ней тоже элементы независимы. Но объединение последовательностей U и V уже не будет обладать таким свойством.
Здравствуйте, watchmaker, Вы писали:
W>Слева вариант по формулам из википедии. А справа вариант, генерируемый функцией за авторством kov_serg. W>Правда ведь правый вариант выглядит немного не похожим на нормальное распределение?
Да косяк.
function normal()
local a=math.sqrt(-2*math.log(math.random()))
local b=2*math.pi*math.random()
return a*math.cos(b), a*math.sin(b)
end
Re[5]: Генерация случайных чисел по нормальному закону распреде
Разве тут вторую компоненту через первую нельзя выразить?
W>>Слева вариант по формулам из википедии. А справа вариант, генерируемый функцией за авторством kov_serg. W>>Правда ведь правый вариант выглядит немного не похожим на нормальное распределение? _>Да косяк. _>
_>function normal()
_> local a=math.sqrt(-2*math.log(math.random()))
_> local b=2*math.pi*math.random()
_> return a*math.cos(b), a*math.sin(b)
_>end
_>
Re[6]: Генерация случайных чисел по нормальному закону распреде
Здравствуйте, TailWind, Вы писали:
_>>Нет
TW>Да ладно?
TW>cos(b) нельзя выразить через sin(b)?
Зная значение sin(b) можно хорошо предсказать возможные значения cos(b).
Но всё становится несколько интереснее, если вам известно лишь значение a * sin(b) и неизвестно значение a. Тогда предсказать возможные значения a * cos(b) становится не так просто.
Вообще это известный метод Box–Muller transform, и несмотря на кажущуюся похожесть выражений, зависимости между случайными величинами нет.