C#正常随机数

时间:2009-10-26 17:12:11

标签: c# algorithm math statistics random

我想创建一个接受Double meanDouble deviation的函数,并返回一个正态分布的随机数。

示例:如果我传入5.00作为平均值而2.00作为偏差,68%的时间我会得到一个介于3.00和7.00之间的数字

我的统计数据有点弱......任何人都知道我应该如何处理这个问题?我的实现将是C#2.0,但只要数学函数是标准的,就可以用您选择的语言回答。

我认为this可能实际上就是我想要的。有任何帮助将其转换为代码吗?

提前感谢您的帮助。

9 个答案:

答案 0 :(得分:21)

请参阅此CodeProject文章:Simple Random Number Generation。代码非常短,它可以从均匀分布,正态分布和指数分布生成样本。

答案 1 :(得分:12)

您可能对Math.NET感兴趣,特别是Numerics包。

警告:数字包以.NET 3.5为目标。如果您的目标是早期版本,则可能需要使用Iridium包...

答案 2 :(得分:7)

这是一些返回两个值(rand1和rand2)的C,只是因为算法有效地这样做了。它是Box-Muller transform的极性形式。

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;

}

答案 3 :(得分:5)

答案 4 :(得分:2)

抱歉,我没有任何代码,但我可以指向some algorithms on Wikipedia。我猜你选择的算法取决于你想要它的准确程度以及它需要多快。

答案 5 :(得分:1)

对于那些引用这个问题的人来说,一个简单的解决方案可能是:

Random rand = new Random();
double normRand  = alglib.invnormaldistribution(rand.NextDouble())

根据需要按mu和sigma缩放。
alglib库可在www.alglib.net

获得

答案 6 :(得分:0)

MetaNumerics库,也是.NET,将超快速地计算正态分布(以及统计中的任何其他内容)。有关更多详细信息,请查看功能页面。 Codeplex页面位于:http://metanumerics.codeplex.com/

答案 7 :(得分:0)

MathNet

来自第二个答案

    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;

    }

Box-Mueller变换

从最高回答通过链接(两倍快?)

by u / yoyoyoyosef Random Gaussian Variables

    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;
    }

答案 8 :(得分:-1)

我知道这篇文章有点旧,但我想分享我昨天创建的一个小项目。 我认为更简单的方法是使用C ++ 11并在托管C ++中创建.dll。 它有一个link来源和一个包含已编译的dll的zip。

我制作的代码:

// 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;
            }
        }
    };

}