سؤال

هل هناك فئة في المكتبة القياسية لـ .NET تمنحني وظيفة إنشاء متغيرات عشوائية تتبع التوزيع الغوسي؟

هل كانت مفيدة؟

المحلول

واقتراح جاريت من استخدام صندوق مولر تحويل جيد للتوصل إلى حل سريع وقذرة. A تنفيذ بسيط:

Random rand = new Random(); //reuse this if you are generating many
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 + stdDev * randStdNormal; //random normal(mean,stdDev^2)

نصائح أخرى

ويبدو أن هذا السؤال قد انتقل على رأس جوجل لتوليد جاوس. NET، لذلك كنت احسب أن نشر إجابة.

ولقد قدمت بعض طرق الإرشاد ل. NET الطبقة عشوائية ، بما في ذلك تنفيذ صندوق مولر تحويل. منذ انهم ملحقات، طالما يتم تضمين المشروع (أو يمكنك الرجوع إلى DLL المترجمة)، لا يزال بإمكانك القيام به

var r = new Random();
var x = r.NextGaussian();

والأمل العقول لا أحد المكونات وقح.

ونموذج الرسم البياني للنتائج (يتم تضمين التطبيق التجريبي لرسم هذا):

ماث.نت يوفر هذه الوظيفة.إليك الطريقة:

double mean = 100;
double stdDev = 10;

MathNet.Numerics.Distributions.Normal normalDist = new Normal(mean, stdDev);
double randomGaussianValue=   normalDist.Sample();

يمكنك العثور على الوثائق هنا:http://numerics.mathdotnet.com/api/MathNet.Numerics.Distributions/Normal.htm

وأنا خلقت طلبا للحصول على مثل هذه الميزة على اتصال Microsoft. إذا كان هذا هو ما كنت تبحث عنه، يرجى التصويت لصالحه وزيادة وضوحه.

https://connect.microsoft. كوم / VisualStudio / تعليقات / تفاصيل / 634346 / guassian طبيعي-أرقام عشوائية التوزيع

ويتم تضمين هذه الميزة في SDK جافا. تنفيذه متاح rel="noreferrer"> وسهولة # C أو غيرها من اللغات. NET.

إذا كنت تبحث عن سرعة نقية، ثم Zigorat خوارزمية ومن المسلم به عموما باسم أسرع النهج.

وأنا لست خبيرا في هذا الموضوع على الرغم - جئت عبر الحاجة لهذا حين تنفيذ الجسيمات مرشح للحصول على بلدي RoboCup 3D محاكاة الروبوتية مكتبة كرة القدم وفوجئت عندما هذه لم تكن مدرجة في هذا الإطار.


في هذه الأثناء، وهنا مجمع لRandom أن يوفر التنفيذ الفعال لطريقة القطبي صندوق مولر:

public sealed class GaussianRandom
{
    private bool _hasDeviate;
    private double _storedDeviate;
    private readonly Random _random;

    public GaussianRandom(Random random = null)
    {
        _random = random ?? new Random();
    }

    /// <summary>
    /// Obtains normally (Gaussian) distributed random numbers, using the Box-Muller
    /// transformation.  This transformation takes two uniformly distributed deviates
    /// within the unit circle, and transforms them into two independently
    /// distributed normal deviates.
    /// </summary>
    /// <param name="mu">The mean of the distribution.  Default is zero.</param>
    /// <param name="sigma">The standard deviation of the distribution.  Default is one.</param>
    /// <returns></returns>
    public double NextGaussian(double mu = 0, double sigma = 1)
    {
        if (sigma <= 0)
            throw new ArgumentOutOfRangeException("sigma", "Must be greater than zero.");

        if (_hasDeviate)
        {
            _hasDeviate = false;
            return _storedDeviate*sigma + mu;
        }

        double v1, v2, rSquared;
        do
        {
            // two random values between -1.0 and 1.0
            v1 = 2*_random.NextDouble() - 1;
            v2 = 2*_random.NextDouble() - 1;
            rSquared = v1*v1 + v2*v2;
            // ensure within the unit circle
        } while (rSquared >= 1 || rSquared == 0);

        // calculate polar tranformation for each deviate
        var polar = Math.Sqrt(-2*Math.Log(rSquared)/rSquared);
        // store first deviate
        _storedDeviate = v2*polar;
        _hasDeviate = true;
        // return second deviate
        return v1*polar*sigma + mu;
    }
}

Math.NET إيريديوم يدعي أيضا لتنفيذ "غير موحدة المولدات العشوائية (عادي، بواسون، ذي الحدين، ...) ".

وهنا حل آخر سريعة وقذرة لتوليد المتغيرات العشوائية التي هي العادي توزيع . ويلفت بعض نقطة عشوائية (س، ص) ويتحقق إذا هذه النقطة تكمن تحت منحنى دالة الكثافة الاحتمالية، كرر خلاف ذلك.

والمكافأة: يمكنك توليد المتغيرات العشوائية لأي التوزيع الأخرى (مثل التوزيع الأسي أو بواسون توزيع ) فقط عن طريق استبدال دالة الكثافة.

    static Random _rand = new Random();

    public static double Draw()
    {
        while (true)
        {
            // Get random values from interval [0,1]
            var x = _rand.NextDouble(); 
            var y = _rand.NextDouble(); 

            // Is the point (x,y) under the curve of the density function?
            if (y < f(x)) 
                return x;
        }
    }

    // Normal (or gauss) distribution function
    public static double f(double x, double μ = 0.5, double σ = 0.5)
    {
        return 1d / Math.Sqrt(2 * σ * σ * Math.PI) * Math.Exp(-((x - μ) * (x - μ)) / (2 * σ * σ));
    }

هام: حدد فاصل <م> ص والمعلمات σ و <م> μ بحيث منحنى وظيفة ليست قطع على أنه من الحد الأقصى / الدنيا نقاط (على سبيل المثال عند x = الوسط). التفكير في فترات <م> س و <م> ص على شكل مربع المحيط، الذي منحنى يجب أن يصلح في.

وأود أن يتوسع @ yoyoyoyosef والجواب من خلال جعلها أسرع، والكتابة فئة مجمع. النفقات العامة تكبد قد لا يعني أسرع مرتين، ولكن أعتقد أنه يجب أن يكون <م> تقريبا أسرع مرتين. أنها ليست ذات ألوان، وإن كان.

public class Gaussian
{
     private bool _available;
     private double _nextGauss;
     private Random _rng;

     public Gaussian()
     {
         _rng = new Random();
     }

     public double RandomGauss()
     {
        if (_available)
        {
            _available = false;
            return _nextGauss;
        }

        double u1 = _rng.NextDouble();
        double u2 = _rng.NextDouble();
        double temp1 = Math.Sqrt(-2.0*Math.Log(u1));
        double temp2 = 2.0*Math.PI*u2;

        _nextGauss = temp1 * Math.Sin(temp2);
        _available = true;
        return temp1*Math.Cos(temp2);
     }

    public double RandomGauss(double mu, double sigma)
    {
        return mu + sigma*RandomGauss();
    }

    public double RandomGauss(double sigma)
    {
        return sigma*RandomGauss();
    }
}

والتوسع في الإجابة درو نواكس، وإذا كنت تحتاج إلى أداء أفضل من صندوق مولر (حوالي 50-75٪ أسرع)، كولن الخضراء والمشتركة لتنفيذ الخوارزمية الزقورة في C #، والتي يمكنك أن تجد هنا:

http://heliosphan.org/zigguratalgorithm/zigguratalgorithm.html

وزقورة يستخدم جدول البحث للتعامل مع القيم التي تقع بعيدا بما فيه الكفاية من المنحنى، التي كانت ستقبل بسرعة أو رفضها. حوالي 2.5٪ من الوقت، عليها أن تفعل المزيد من العمليات الحسابية لتحديد أي جانب من منحنى عدد غير.

والتوسع في الخروج منNoakes و @إجابات Hameer، ولقد نفذت أيضا فئة "التمويه"، ولكن لتبسيط مساحة الذاكرة، وأنا جعلت من الأطفال من فئة عشوائية بحيث يمكنك أيضا استدعاء الأساسي التالي ()، NextDouble ()، وغيرها من الطبقة جاوس وكذلك دون الحاجة إلى إنشاء كائن عشوائي إضافية للتعامل مع ذلك. أنا أيضا القضاء على _available، و_nextgauss خصائص الطبقة العالمية، كما لم أكن أراهم ضروريا، ما دامت هذه الفئة يستند سبيل المثال، ينبغي أن يكون الخيط آمنة، إذا كنت تعطي كل خيط الكائن جاوس الخاص بها. كما أنني انتقلت كافة المتغيرات وقت التشغيل المخصصة من وظيفة وجعلهم خصائص الطبقة، وهذا سوف يقلل من عدد المكالمات لإدارة الذاكرة منذ 4 الزوجي يجب نظريا لم يتم اجتثاث المخصصة حتى يتم تدمير الكائن.

public class Gaussian : Random
{

    private double u1;
    private double u2;
    private double temp1;
    private double temp2;

    public Gaussian(int seed):base(seed)
    {
    }

    public Gaussian() : base()
    {
    }

    /// <summary>
    /// Obtains normally (Gaussian) distrubuted random numbers, using the Box-Muller
    /// transformation.  This transformation takes two uniformly distributed deviates
    /// within the unit circle, and transforms them into two independently distributed normal deviates.
    /// </summary>
    /// <param name="mu">The mean of the distribution.  Default is zero</param>
    /// <param name="sigma">The standard deviation of the distribution.  Default is one.</param>
    /// <returns></returns>

    public double RandomGauss(double mu = 0, double sigma = 1)
    {
        if (sigma <= 0)
            throw new ArgumentOutOfRangeException("sigma", "Must be greater than zero.");

        u1 = base.NextDouble();
        u2 = base.NextDouble();
        temp1 = Math.Sqrt(-2 * Math.Log(u1));
        temp2 = 2 * Math.PI * u2;

        return mu + sigma*(temp1 * Math.Cos(temp2));
    }
}

هل يمكن أن تحاول Infer.NET. انها ليست مرخصة التجارية بعد بالرغم من ذلك. هنا هناك href="http://research.microsoft.com/en-us/um/cambridge/projects/infernet/"

وهي عبارة عن إطار احتمالي ل. NET تطوير أبحاث مايكروسوفت بلدي. لديهم أنواع الصافي لتوزيع برنولي، بيتا، غاما، التمويه، بواسون، وربما بعض أكثر غادرت بها.

ويمكن أن تنجز ما تريد. شكرا.

وهذا هو بلدي بسيط صندوق مولر تنفيذ وحي. يمكنك زيادة دقة لتناسب احتياجاتك. ورغم أن هذا يعمل كبيرة بالنسبة لي، وهذا هو نطاق تقريب محدود، لذلك نضع في اعتبارنا لا تعمل ذيول ومحدود، ولكن بالتأكيد يمكنك توسيعها حسب الحاجة.

    //
    // by Dan
    // islandTraderFX
    // copyright 2015
    // Siesta Key, FL
    //    
// 0.0  3231 ********************************
// 0.1  1981 *******************
// 0.2  1411 **************
// 0.3  1048 **********
// 0.4  810 ********
// 0.5  573 *****
// 0.6  464 ****
// 0.7  262 **
// 0.8  161 *
// 0.9  59 
//Total: 10000

double g()
{
   double res = 1000000;
   return random.Next(0, (int)(res * random.NextDouble()) + 1) / res;
}

public static class RandomProvider
{
   public static int seed = Environment.TickCount;

   private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
       new Random(Interlocked.Increment(ref seed))
   );

   public static Random GetThreadRandom()
   {
       return randomWrapper.Value;
   }
} 

وأنا لا أعتقد أن هناك. وأنا آمل حقا ليس هناك، باعتبارها الإطار هو بالفعل منتفخة بما فيه الكفاية، دون مثل هذه الوظائف المتخصصة ملئه أكثر من ذلك.

ونلقي نظرة على http://www.extremeoptimization.com/Statistics /UsersGuide/ContinuousDistributions/NormalDistribution.aspx و HTTP: //www.vbforums كوم / showthread.php؟ ر = 488959 للحصول على الثلث الحلول الحزب. NET بالرغم من ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top