C# 普通随机数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1626023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:30:50  来源:igfitidea点击:

C# Normal Random Number

c#algorithmmathstatisticsrandom

提问by J.Hendrix

I would like to create a function that accepts Double mean, Double deviationand returns a random number with a normal distribution.

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

Example: if I pass in 5.00 as the mean and 2.00 as the deviation, 68% of the time I will get a number between 3.00 and 7.00

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

My statistics is a little weak…. Anyone have an idea how I should approach this? My implementation will be C# 2.0 but feel free to answer in your language of choice as long as the math functions are standard.

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

I think thismight actually be what I am looking for. Any help converting this to code?

我认为实际上可能是我正在寻找的。任何帮助将其转换为代码?

Thanks in advance for your help.

在此先感谢您的帮助。

采纳答案by John D. Cook

See this CodeProject article: Simple Random Number Generation. The code is very short, and it generates samples from uniform, normal, and exponential distributions.

请参阅此 CodeProject 文章:简单随机数生成。代码很短,它从均匀分布、正态分布和指数分布中生成样本。

回答by Jason Punyon

You might be interested in Math.NET, specifically the Numerics package.

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

Caveat: The numerics package targets .NET 3.5. You may need to use the Iridium package if you are targeting an earlier version...

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

回答by redcalx

This library is pretty good also:

这个库也很不错:

.NET random number generators and distributions

.NET 随机数生成器和分布

回答by Martin Sherburn

Sorry I don't have any code for you but I can point you to some algorithms on Wikipedia. The algorithm you choose I guess depends on how accurate you want it and how fast it needs to be.

抱歉,我没有任何代码供您参考,但我可以为您指出Wikipedia上的一些算法。我猜你选择的算法取决于你想要它的准确度和它需要的速度。

回答by Justin R.

The MetaNumericslibrary, also .NET, will calculate a normal distribution (and just about anything else from statistics), super quickly. Have a look at the Feature's page for more details. The Codeplex page is here: http://metanumerics.codeplex.com/.

MetaNumerics库,也.NET,将计算正态分布(和几乎从统计别的),超级快。查看功能页面以获取更多详细信息。Codeplex 页面在这里:http: //metanumerics.codeplex.com/

回答by Ian W

Here is some C that returns two values (rand1 and rand2), just because the algorithm efficiently does so. It is the polar form of the Box-Muller transform.

这里有一些 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;

}

}

回答by Ace

For those referencing this question, an easy solution might be:

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

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

scale by mu and sigma as needed.
The alglib library is available at www.alglib.net

根据需要按 mu 和 sigma 进行缩放。
alglib 库可在www.alglib.net 上获得

回答by pascx64

I know this post is a little old but I would like to share a small project I created yesterday. I think the easier way is to use C++ 11 and create a .dll in Managed C++. There's a linkto the source and a zip containing the dll already compiled.

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

And the code I made :

我制作的代码:

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

}

回答by Declan Taylor

MathNet

数学网

from second top answer

从第二个最佳答案

    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 Transform

Box-Mueller 变换

from top answer via link (twice as fast?)

从最佳答案通过链接(快两倍?)

by u/yoyoyoyosef Random Gaussian Variables

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