سؤال

أنا مهتم في وظيفة rand(x, y, seed) أن يعود (الزائفة) أرقام عشوائية استنادا إلى الحجج, مع الخصائص التالية:

  1. القيمة التي تم إرجاعها يجب أن تعتمد على 3 من الحجج ، لا تعتمد على كمية مرات rand كان يسمى حتى الآن.على سبيل المثال ، على افتراض أن هذه الدعوات في هذا النظام:

    rand(0, 0, 123) = 1
    rand(0, 1, 123) = 2
    rand(0, 2, 123) = 3
    

    ثم يدعو rand مع نفس الحجج ، ولكن بترتيب مختلف ، يجب أن نحصل على نفس القيم.على سبيل المثال:

    rand(0, 1, 123) = 2
    rand(0, 2, 123) = 3
    rand(0, 0, 123) = 1
    
  2. وظيفة يجب أن يكون المعتادة خصائص جيدة (الكريم, أنا حقا لا تحتاج إلى أي شيء يتوهم جدا) من اللوائح:فترة كبيرة, توزيع موحد.... الخالعودة الاعداد الصحيحه الايجابية التي تناسب في توقيع الباحث على ما يرام.أيضا يمكن أن تذهب أعلى من ذلك إذا كنت تريد.

  3. تفترض هذه الأرقام سوف تستخدم في توليد مصفوفة.ثم تغيير البذور ينبغي أن تكفل إنشاء مصفوفة تبدو بشكل مختلف ممكن من المصفوفات التي تم إنشاؤها بواسطة بذور أخرى.هذا يجب أن يحدث على أكبر عدد من البذور ممكن:أنا لا أريد المصفوفات تكرار.

إذا كان ذلك يساعد ، البذور سوف يكون دائما unix timestamp في ميلي ثانية (يمكن أن يكون في ثوان أيضا إذا كان ذلك يجعل من الأسهل بطريقة أو بأخرى).كل الحجج التي يمكن أن تصل إلى 32 بت رجات ، ولكن تعمل مع 64 بت القيم داخل الدالة ليست مشكلة.

ما وظيفة يمكنني استخدام هذا ؟

ما فكرت:

بيرلين الضوضاء يبدو أن تفعل بعض ما أريد, ولكن ليس لدي أي فكرة عن كيفية مناسبة هو حقا كما PRNG ، وخاصة التوزيع الحكيم.أنا أيضا غير متأكد من مدى كفاءة هو منذ (x, y) المعلمات سوف تكون عشوائية ولا أستطيع precompute ذلك لجميع من لهم.

أنا أيضا بحثت في الدالة التالية:

p = 1400328593
rand(x, y, seed) = (x * x * seed + y * seed * seed + seed * x * y + seed) mod p
                 = (seed * (x * x + y * seed + x * y + 1)) mod p

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

تحديث:

هنا هو الإخراج من Ent بالنسبة الدالة أعلاه ، time(NULL) في C كما في البذور والقيم الناتجة عن (x, y) in {0 ... 999} x {0 ... 999}:

الكون = 3.312850 بت في البايت.

الأمثل ضغط من شأنه أن يقلل من حجم هذا 9207076 بايت الملف من قبل 58 في المئة.

مربع كاي توزيع 9207076 العينات 229710872.43 ، بشكل عشوائي من شأنه أن يتجاوز هذه القيمة أقل من 0.01 في المئة من الأوقات.

المتوسط الحسابي قيمة البيانات بايت 52.3354 (127.5 = عشوائي).مونتي كارلو قيمة Pi هو 4.000000000 (خطأ 27.32 في المئة).المسلسل معامل الارتباط هو 0.036131 (تماما غير مترابطة = 0.0).

هل هذا جيد بما فيه الكفاية في الممارسة العملية (في نظرية الاختبارات المذكورة أعلاه تشير إلى أن هذا ليس جيد على الإطلاق) ، أو هل هناك شيء معروف أنه يجب أن تستخدم ؟

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

المحلول

يبدو أنك تريد تجزئة الوظيفة.اختيار آمنة مثل SHA1 إذا لم يكن غير فعالة ، حيث انها مضمونة أن يكون حسن توزيع الخصائص ؛ وإلا, يمكنك استخدام مشترك وظيفة تجزئة مثل FNV.ببساطة استخدام البذور الإحداثيات كإدخال بيانات التجزئة مثل قيمة عشوائية.

نصائح أخرى

يمكنك محاولة استخدام بلوم بلوم شب.وقد الخاصية التي يمكنك حساب n قيمته قيمة سلسلة مباشرة ، وهو ما يبدو تبعا للموقف الخاص بك.يستغرق ثلاث معلمات, p, q, و x0.p و q هي رئيس الوزراء x0 هو relateively رئيس الوزراء إلى كل من p و q.حتى حججك x و y يمكن استخدامها للعثور على x عنه و y يستحق يعبي, ثم أنها سوف تكون مناسبة p و q ، ومن ثم يمكن استخدام المعلمة الثالثة لإيجاد مناسبة قيمة x0.هذا هو قليلا مملة ، بلوم بلوم شب بطيء لأنه هو التشفير RNG, ولكن إذا كنت حقا لا تتطلب السرعة ثم أنها سوف تعمل و لن يكون من الصعب جدا لتنفيذ.

طريقة أخرى للقيام بذلك سيكون لاتخاذ مثل RNG CMWC وملء أنا أخذ موقف مولد مع شيء مثل x + y^أنا + البذور^(2), تشغيل مولد قليلا (ربما عدد من المرات يساوي عدد القيم المخازن) ، ثم سحب قيمة من ذلك.

إذا كنت ترغب في استخدام CMWC يمكنك أن تبحث في التنفيذ يجب على جيثب هنا, والقيم بناء مولد المعروف فترات هنا.

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