سؤال

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

إليك الرمز الخاص بي:

public double GetRandomVal()
{
   int z = Convert.ToInt32(GenRandomNumber() * (vals.Length));
   return vals[z];
}

شكرا

تحديث

بفضل جميع أولئك الذين أجابوا، لكنني متقيد لاستخدام تطبيق رقم عشوائي موريسيت Netwister مزود به طريقة Rand.nextDouble ()

تحديث 2.

التفكير في هذا الأمر أكثر، كل ما أحتاج إليه هو GEN رقم عشوائي بين 0 و array.length-1 ثم استخدم ذلك إلى الفهرس بشكل عشوائي في الصفيف. وبعد طول Vals 2 ^ 20 = 1048576، لذا توليد INT عشوائي كافية. لاحظت أن MersenNetWister الخاص بي لديه طريقة:

public int Next(int maxValue)

إذا اتصلت به مثل Vals [rand.next (vals.length-1) يجب أن تفعل ذلك بشكل صحيح؟ أرى أيضا MersenNetwister لديه منشئ:

public MersenneTwister(int[] init)

لست متأكدا من ذلك من أجل، هل يمكنني استخدام هذا لإعداد الأرقام العشوائية المقبولة التي أقدم مجموعة من 0 إلى vals.length؟

FYI Vals هي مجموعة مزدوجة من الطول 1048576 تقسيم منحنى التوزيع الطبيعي. أنا أستخدم هذه الآلية بشكل أساسي لإنشاء أرقام موزعة بشكل طبيعي بأسرع وقت ممكن، تستخدم محاكاة مونت كارلو مليارات أرقام عشوائية موزعة عادة كل يوم لذلك كل بت يساعد قليلا.

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

المحلول

حاول استخدام عدد صحيح عشوائي بدلا من ذلك:

Random random = new Random();
int randomNumber = random.Next(0, vals.Length);
return vals[randomNumber];

نصائح أخرى

عودة فالس [rng.next (vals.length)]؛

حيث RNG هو

RNG عشوائي = جديد عشوائي ()؛

أعتقد أن لديك أبسط الأكثر مباشرة تم تحديدها بالفعل.

ولكن إذا كنت تبحث عن مكاسب أداء في خوارزمية الفهرسة العشوائية الخاصة بك، فقد تكون قادرا على "الكراك"يتم تشفير IEEE 754 المزدوج إلى الأسهم والكسر - واستخدام الكسر modulo حجم الصفيف كوسيط عشوائي.

من غير المرجح أن تكون هذه التقنية آمنة شفطية - لذلك إذا كان هذا هو الاعتبار - لا تفعل ذلك.

أيضا، هذا النهج لا اجعل الرمز أكثر وضوحا - أود أن ألتصق بتنفيذك الأصلي ما لم يكن هناك تعظيم الأداء هو الاعتبار. جانبا، فإن أبطأ جزء من هذه المعالجة هو الأرجح جيل مرين الإعصار من أرقام عشوائية.

إليك الرمز:

[StructLayout(LayoutKind.Explicit)] // used create a union of Long and Double
public struct IEEE754
{
    private const ulong SIGN_BITS     = 0x8000000000000000;
    private const ulong EXPONENT_BITS = 0x7FF0000000000000;
    private const ulong FRACTION_BITS = 0x000FFFFFFFFFFFFF;

    private const int SIGN_OFFSET     = 63;
    private const int EXPONENT_OFFSET = 52;

    // [FieldOffset] attribute is .NET's way of defining how to explicitly
    // layout the fields of a structure - we're using it to overlay the
    // double and long into a single bit-space ... effectively a C# 'union'
    [FieldOffset( 0 )] private double DoubleValue;
    [FieldOffset( 0 )] private ulong LongValue;

    public IEEE754(double val)
    {
        DoubleValue = val;
    }
    // properties that retrieve the various pieces of an IEEE754 double
    public long Fraction { get { return (long)(LongValue & FRACTION_BITS); } }
    public long Exponent { get { return (long)((LongValue & EXPONENT_BITS) >> EXPONENT_OFFSET); } }
    public long Sign     { get { return (long)((LongValue & SIGN_BITS) >> SIGN_OFFSET); } }

    public void Set( double val ) { DoubleValue = val; }
}

public static void TestFunction()
{
    var array = Enumerable.Range( 1, 10000 ).ToArray();   // test array...

    // however you access your random generator would go here...
    var rand = new YourRandomNumberGenerator();

    // crack the double using the special union structure we created...
    var dul = new IEEE754( rand.GenRandomNumber() );

    // use the factional value modulo the array length as a random index...
    var randomValue = array[dul.Fraction % array.Length];
}

هل فكرت في استخدام الفئة العشوائية .NET؟

سأستخدم random.next (int32), ، والتي ترجع قيمة أقل من المدخلات> = صفر. اجتياز طول صفيفك كإدخال، وحصلت على فهرس صالح عشوائي.

كما لاحظ أشخاص آخرون بالفعل، لدى System.random الزائد التالي الذي سيفعل ما تسأل إليه بالفعل.

كما لمعلقك حول Convert.ToInt32 وبديل أكثر كفاءة، يمكنك إلقاء نظرة مباشرة double إلى int:

double d = 1.5;
int i = (int)d;
private static readonly Random _random = new Random();

public double GetRandomVal()
{
    int z = _random.Next(vals.Length);
    return vals[z];
}

إذا لم تكن قيدا لاستخدام وظيفتك العشوائية، فاستخدم Random صف دراسي.

public Double GetRandomValue(Double[] values)
{
    return values[new Random().Next(values.Length)];
}

آخر أود فقط استخدام يلقي لأنه يعطي السلوك الصحيح - التقريب نحو الصفر بدلا من أقرب عدد صحيح Convert.ToInt32() هل.

public Double GetRandomValue(Double[] values)
{
    return values[(Int32)(GetNextRandomNumber() * values.Length)];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top