C# 普通随机数 [重复]

Posted

技术标签:

【中文标题】C# 普通随机数 [重复]【英文标题】:C# Normal Random Number [duplicate] 【发布时间】:2010-12-10 04:58:45 【问题描述】:

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

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

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

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

提前感谢您的帮助。

【问题讨论】:

感谢迄今为止发帖的所有人。你为我指明了正确的方向。我没有意识到这是一项如此复杂的任务。我很确定有人会立刻吐出 4 班轮。 ***.com/questions/218060/random-gaussian-variables 使用MedallionRandom包,你可以用mean + (random.NextGaussian() * deviation)做到这一点 【参考方案1】:

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

【讨论】:

+1 我想这可能正是我想要的!谢谢。 谢谢,完美。不会太长,完全按照我的意愿去做。 很简单,效果很好。干得好!【参考方案2】:

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

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

【讨论】:

现在正在查看mathdotnet.com/doc/IridiumFeatures.ashx 的功能...不太确定我想要哪个功能。也许是连续概率分布之一?今晚我可能只需要下载源代码并倾注代码。 您想使用 MathNet.Numerics.Distributions,并执行类似的操作,这将从平均值为 5.0 和 sigma 0.68 的 Normal 中提取:var mu = 5.00;变量 sigma = 0.68; var normal = new NormalDistribution(mu, sigma); var draw = normal.NextDouble();【参考方案3】:

这是一些返回两个值(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;

【讨论】:

如果您将变量命名为“u”、“v”等以外的名称会很有帮助,例如,mean 和 sigma 非常有用。 变量 u、v、z 和 s 用于保持与 Box-Muller 变换中使用的常用数学符号的一致性。 作为一名导师,我可以证明,如果将惯用的数学符号本身标记得更具描述性,对大多数人都会有所帮助。【参考方案4】:

这个库也不错:

.NET random number generators and distributions

【讨论】:

+1 这看起来很有希望。谢谢【参考方案5】:

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

【讨论】:

+1 这看起来也不错。如何创建“均匀分布在 (0, 1] 上的两个独立随机数 U 和 V”?对不起...我告诉过你我的统计数据很弱。 在 C# 中,您将使用“随机”类 (msdn.microsoft.com/en-us/library/system.random.aspx)。具体来说,NextDouble 方法返回一个在 0 到 1 范围内均匀分布的数字。均匀分布只是意味着您有相同的机会获得该范围内的任何数字,对任何特定数字都没有偏见。【参考方案6】:

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

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

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

【讨论】:

【参考方案7】:

MetaNumerics 库,也是 .NET,将超级快速地计算正态分布(以及来自统计数据的任何其他内容)。查看功能页面了解更多详细信息。 Codeplex 页面在这里:http://metanumerics.codeplex.com/。

【讨论】:

【参考方案8】:

数学网

来自第二个最佳答案

    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 变换

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

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

【讨论】:

【参考方案9】:

我知道这篇文章有点老了,但我想分享我昨天创建的一个小项目。 我认为更简单的方法是使用 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;
            
        
    ;


【讨论】:

以上是关于C# 普通随机数 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C# 如何生成不重复的1-100随机数。

在 C# 中生成随机数 [重复]

.net 下用C#产生一个永不重复10位随机数

2d 数组随机数(10 行,6 列)不重复到文件 C#

随机数在数组c#中只有一次[重复]

C# Random 生成不重复随机数