Ответ 1
Смотрите эту статью CodeProject: Простая генерация случайных чисел. Код очень короткий, и он генерирует выборки из однородных, нормальных и экспоненциальных распределений.
Я хотел бы создать функцию, которая принимает Double mean
, Double deviation
и возвращает случайное число с нормальным распределением.
Пример: если я пройду через 5.00 в качестве среднего и 2.00 в качестве отклонения, 68% времени я получу число между 3.00 и 7.00
Моя статистика немного слаба.... У кого-нибудь есть идея, как я должен подходить к этому? Моя реализация будет С# 2.0, но не стесняйтесь отвечать на вашем языке выбора, если математические функции являются стандартными.
Думаю, этот может быть тем, что я ищу. Любая помощь, конвертирующая это в код?
Заранее благодарим за помощь.
Смотрите эту статью CodeProject: Простая генерация случайных чисел. Код очень короткий, и он генерирует выборки из однородных, нормальных и экспоненциальных распределений.
Вам может быть интересно Math.NET, в частности пакет Numerics.
Предостережение. Пакет численных значений предназначен для .NET 3.5. Возможно, вам придется использовать пакет Iridium, если вы ориентируетесь на более раннюю версию...
Вот несколько C, которые возвращают два значения (rand1 и rand2), только потому, что алгоритм эффективно делает это. Это полярная форма преобразования Box-Muller.
void RandVal (double mean1, double sigma1, double *rand1, double mean2, double sigma2, double *rand2)
{
double u1, u2, v1, v2, s, z1, z2;
do {
u1 = Random (0., 1.); // a uniform random number from 0 to 1
u2 = Random (0., 1.);
v1 = 2.*u1 - 1.;
v2 = 2.*u2 - 1.;
s = v1*v1 + v2*v2;
} while (s > 1. || s==0.);
z1 = sqrt (-2.*log(s)/s)*v1;
z2 = sqrt (-2.*log(s)/s)*v2;
*rand1 = (z1*sigma1 + mean1);
*rand2 = (z2*sigma2 + mean2);
return;
}
Эта библиотека довольно хороша также:
Извините, у меня нет кода для вас, но я могу указать вам на некоторые алгоритмы в Википедии. Выбираемый алгоритм зависит от того, насколько вы точны и насколько быстро он должен быть.
Для тех, кто ссылается на этот вопрос, простым решением может быть:
Random rand = new Random();
double normRand = alglib.invnormaldistribution(rand.NextDouble())
по массе и сигме по мере необходимости.
Библиотека alglib доступна по адресу www.alglib.net
Библиотека MetaNumerics, также .NET, рассчитает нормальное распределение (и почти все остальное из статистики), супер быстро. Посмотрите на страницу Feature для более подробной информации. Страница Codeplex находится здесь: http://metanumerics.codeplex.com/.
из второго верхнего ответа
public static double GenerateRandomVariant(double mean,double deviation,System.Random rand=null, int factor=1)
{
rand = rand ?? new Random();
double randNormal=(MathNet.Numerics.Distributions.Normal.Sample(rand, mean , deviation));
return factor * randNormal;
}
от верхнего ответа по ссылке (в два раза быстрее?)
by u/yoyoyoyosef Случайные гауссовские переменные
public static double GenerateRandomVariant(double mean, double deviation, System.Random rand=null, int factor = 1)
{
rand = rand ?? new Random();
double u1 = 1.0 - rand.NextDouble(); //uniform(0,1] random doubles
double u2 = 1.0 - rand.NextDouble();
double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
double randNormal=(
mean + deviation * randStdNormal); //random normal(mean,stdDev^2)
return randNormal * factor;
}
Я знаю, что этот пост немного стар, но я хотел бы поделиться небольшим проектом, который я создал вчера. Я думаю, что проще использовать С++ 11 и создать .dll в Managed С++. Там ссылка на источник и почтовый индекс, содержащий уже скомпилированную dll.
И код, который я сделал:
// NormalDistributionRandom.h
#include <random>
#pragma once
using namespace System;
namespace NormalDistribution
{
class _NormalDistributionRandom
{
std::default_random_engine engine;
std::normal_distribution<double> distribution;
public:
_NormalDistributionRandom(double mean, double deviation) : distribution(mean, deviation)
{
}
double Next()
{
return distribution(engine);
}
};
public ref class NormalDistributionRandom
{
private:
void* Distribution;
public:
NormalDistributionRandom( double mean, double deviation)
{
Distribution = new _NormalDistributionRandom(mean, deviation);
}
double Next()
{
return ((_NormalDistributionRandom*)Distribution)->Next();
}
~NormalDistributionRandom()
{
this->!NormalDistributionRandom();
}
protected:
!NormalDistributionRandom()
{
if (Distribution != nullptr)
{
delete (_NormalDistributionRandom*)Distribution;
Distribution = nullptr;
}
}
};
}