سؤال

أرغب في الحصول على رقم عشوائي مثل هذا:(في C#)

Random r = new Random();
r.next (0,10)

لكن من المهم أن يكون الرقم العشوائي أكثر بالقرب من 8 ، (أو يكون عادةً كبيرًا) ، أعني إذا استخدمنا A لـ:

for (int i =0; i<...;i++)
{
  write: r.next (0,10)
}

وتكون النتيجة هكذا؛

8 7 6 9 1 0 5 3 2
2 3 8 9 7 7 6 2 3
8 8 9 7 2 8 2 8 4
3
هل كانت مفيدة؟

المحلول

وكنت في حاجة الى وظيفة التوزيع التي تأخذ رقما بين 0 و 1 وتحولها إلى رقم في النطاق الذي تريد، ويبلغ وزنها أعلى على عدد محدد. هل يمكن إنشاء مثل هذه الوظيفة مع الدوال المثلثية (الخطيئة، كوس، ...)، الأسي، أو ربما متعدد الحدود.

وUPDATE: إلقاء نظرة على هذه الصفحة للحصول على مزيد من المعلومات حول التوزيع الاحتمالي

نصائح أخرى

وتحتاج إلى الوزن النتائج. يمكنك أن تفعل ذلك مع شيء من هذا القبيل:

private int[] _distribution = new int[] { 0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9 };
Random _r = new Random();

public int GetWeightedRandom()
{
    return _distribution[_r.Next(0, _distribution.Length)];
}

إذا كنت أعرف أن نطاق بلدي صغير وثابت، فما استقاموا لكم فاستقيموا استخدام الجدول - انها تافهة لجعله فئتها الخاصة

لاكتمال، وأنا أيضا إضافة هذه الفئة في هذه الفئة تقترض من معالجة الصور ويستخدم الدالة تصحيح غاما: قيمة بين 0 و 1 رفعها إلى جاما، والتي ترجع قيمة بين 0 و 1 ولكن توزيع أكثر ل نهاية منخفضة إذا جاما <1.0 وأكثر من ذلك إلى نهاية عالية إذا جاما> 1.0.

public class GammaRandom {
    double _gamma;
    Random _r;

    public GammaRandom(double gamma) {
        if (gamma <= 0) throw new ArgumentOutOfRangeException("gamma");
        _gamma = gamma;
        _r = new Random();
    }
    public int Next(int low, int high) {
       if (high <= low) throw new ArgumentOutOfRangeException("high");
       double rand = _r.NextDouble();
       rand = math.Pow(rand, _gamma);
       return (int)((high - low) * rand) + low;
    }
}

و(من التعليقات، انتقل ص من GetWeightedRandom (). وأضاف أيضا نطاق التحقق إلى التالي ())

وOK، دعونا حقا الذهاب إلى المدينة هنا. أنا توجيه جون السكيت لهذا - انها فئة مجردة مع خاصية القالب الذي يعود تحويل وظيفة تعين مجموعة [0..1) إلى [0..1) والمقاييس الرقم العشوائي لهذا النطاق. أنا أيضا ل Reimplemented جاما من حيث أنه والخطيئة وتنفيذها كوس كذلك.

public abstract class DelegatedRandom
{
    private Random _r = new Random();
    public int Next(int low, int high)
    {
        if (high >= low)
            throw new ArgumentOutOfRangeException("high");
        double rand = _r.NextDouble();
        rand = Transform(rand);
        if (rand >= 1.0 || rand < 0) throw new Exception("internal error - expected transform to be between 0 and 1");
        return (int)((high - low) * rand) + low;
    }
    protected abstract Func<double, double> Transform { get; }
}

public class SinRandom : DelegatedRandom
{
    private static double pihalf = Math.PI / 2;
    protected override Func<double, double> Transform
    {
        get { return r => Math.Sin(r * pihalf); }
    }
}
public class CosRandom : DelegatedRandom
{
    private static double pihalf = Math.PI / 2;
    protected override Func<double, double> Transform
    {
        get { return r => Math.Cos(r * pihalf); }
    }
}
public class GammaRandom : DelegatedRandom
{
    private double _gamma;
    public GammaRandom(double gamma)
    {
        if (gamma <= 0) throw new ArgumentOutOfRangeException("gamma");
        _gamma = gamma;
    }
    protected override Func<double, double> Transform
    {
        get { return r => Math.Pow(r, _gamma); }
    }
}

وبدلا من استخدام صفيف متغير، هل يمكن أن يكون أيضا نظرة على هذا SO التي لديها وصلة ل Math.NET إيريديوم أن ينفذ غير موحدة المولدات العشوائية.

ومزايا لمجموعة البديل هي التي تحصل على نهج أكثر ديناميكية دون الحاجة إلى إعادة كتابة مجموعة في كل وقت. هل يمكن أيضا القيام ببعض الأشياء التي سيكون من المستحيل عمليا مع البديل مجموعة (كبيرة أرقام عشوائية غير موحدة).

ومع بعض نوع من الترجيح الإضافية التي يجب أن يكون ممكنا. يعتمد على كيفية تحديد "بالقرب ثمانية". وهناك طريقة بسيطة جدا للقيام بذلك هي هذه:

for (int i =0; i<...;i++)
{
    n = r.next (0,100);
    write: (n*n) / 1000
}

ووتربيع سوف تزن الأرقام في نهاية منخفضة، أي في هذه الحالة، 33٪ من الوقت ستحصل على 0، في حين ستحصل على 9 فقط حوالي 5٪ من الوقت.

وتكييفها هذه الطريقة بالطبع لتناسب حالة معينة.

ليس بالضبط ما تبحث عنه ولكن هناك طريقة بسيطة جدًا لتقريب التوزيع الطبيعي للأرقام وهي جمع عدة أجيال معًا.

من الأمثلة الكلاسيكية على هذه التقنية لعبة Dungeons and Dragons حيث يمكن تحديد قوة الشخصية من خلال رمي ثلاثة أحجار نرد ذات ستة جوانب وإضافة النتائج.وهذا يعطي نطاقًا من 3 إلى 18 مع وجود أرقام حول 10 على الأرجح.تشمل المتغيرات ما يلي:

  • رمي 4 نردات والتخلص من الأصغر.وهذا يؤدي إلى انحراف التوزيع نحو الأعداد الأعلى.
  • حساب متوسط ​​الدرجات بدلاً من إضافتها.وهذا يجعل نطاق الإخراج أسهل في الفهم.

بدلاً عن ذلك، هذا قريب جدا ...

ويبدو لي كما لو كنت تريد أرقام عشوائية ليتم ترجيح في نهاية عالية - وهذا من شأنه أن يكون تقييم عادل

هذا قد تساعدك (هو جافا، ولكن تطبيق مبادئ)

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