سؤال

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

ما هو جيد ، بسيطة المزيف مولد رقم خوارزمية التجميع ؟

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

المحلول

من السهل واحد هو مجرد اختيار اثنين كبيرة النسبية الأعداد a و b ثم نضع بضرب رقم عشوائي من قبل وإضافة ب.استخدام المشغل نمطية للحفاظ على انخفاض بت ك رقم عشوائي والحفاظ على القيمة الكاملة عن التكرار التالي.

هذه الخوارزمية كما هو معروف الخطية congruential مولد.

نصائح أخرى

المجلد 2 من فن برمجة الكمبيوتر لديه الكثير من المعلومات حول المزيف عدد جيل.الخوارزميات هي أظهر في المجمع, حيث يمكنك أن ترى نفسك التي هي أبسط في المجمع.

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

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

كود بسيط اختبار, لا تستخدم مع التشفير

من اختبار برامج الكمبيوتر, صفحة 138

مع 32 بت الرياضيات لا تحتاج العملية MOD 2^32

RNG = (69069*RNG + 69069) MOD 2^32

جيدا منذ أن كنت لم أر إشارة إلى حسن البالغ من العمر الخطية ردود الفعل التحول السجل أنشر بعض SSE الجوهرية على أساس C-رمز.فقط completenes.لقد كتبت هذا الشيء بضعة أشهر إلى شحذ لي SSE-المهارات مرة أخرى.

#include <emmintrin.h>

static __m128i LFSR;

void InitRandom (int Seed)
{
  LFSR = _mm_cvtsi32_si128 (Seed);
}

int GetRandom (int NumBits)
{
  __m128i seed = LFSR;
  __m128i one  = _mm_cvtsi32_si128(1);
  __m128i mask; 
  int i;

  for (i=0; i<NumBits; i++)
  {

    // generate xor of adjecting bits
    __m128i temp = _mm_xor_si128(seed, _mm_srli_epi64(seed,1));

    // generate xor of feedback bits 5,6 and 62,61
    __m128i NewBit = _mm_xor_si128( _mm_srli_epi64(temp,5),
                                    _mm_srli_epi64(temp,61));

    // Mask out single bit: 
    NewBit = _mm_and_si128 (NewBit, one);

    // Shift & insert new result bit:
    seed = _mm_or_si128 (NewBit, _mm_add_epi64 (seed,seed));
  }

  // Write back seed...
  LFSR = seed;

  // generate mask of NumBit ones.
  mask = _mm_srli_epi64 (_mm_cmpeq_epi8(seed, seed), 64-NumBits);

  // return random number:
  return _mm_cvtsi128_si32 (_mm_and_si128(seed,mask));
}

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

راجع للشغل - تسلسل هذا الرمز genreates يكرر بعد 4.61169 E+18 الأرقام.وهذا هو الكثير أكثر مما ستحصل عليه عن طريق رئيس الوزراء الأسلوب و 32 بت الحساب.إذا بسطه انها أسرع أيضا.

@jjrv
ما تصفه هو في الواقع الخطية congrential مولد.الأكثر عشوائية بت أعلى بت.للحصول على رقم من 0..N-1 تتضاعف قيمة N (32 بت 32 بت إعطاء 64 بت) واستخدام عالية 32 بت.

يجب أن لا مجرد استخدام أي عدد a (مضاعف تتقدم من القيمة الكاملة المقبل) ، أرقام الموصى بها في كانوث (الجدول 1 القسم 3.3.4 TAOCP المجلد 2 1981) هي 1812433253, 1566083941, 69069 و 1664525.

يمكنك فقط اختيار أي عدد فردي من أجل ب.(إضافة).

لماذا لا تستخدم خارجي المكتبة???أن عجلة القيادة قد اخترع بضع مئات المرات ، فلماذا نفعل ذلك مرة أخرى ؟

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

هل تحتاج إلى RNG هذا هو التشفير القوة ؟ كم من الوقت يجب أن أذهب قبل أن يكرر?هل لديك على الاطلاق, إيجابي ضمان توزيع موحد من جميع بت ؟

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

  • تبدأ مع التعسفي 4 بايت المستمر على البذور الخاصة بك.
  • حوسبة 32-بت لجنة حقوق الطفل من تلك 4 بايت.يعطيك المقبل 4 بايت
  • تغذية راجعة تلك 4 بايت في CRC32 الخوارزمية ، كما لو كانوا المرفقة.على CRC32 من 8 بايت القيمة التالية.
  • كرر طالما تريد.

هذا يأخذ القليل جدا من التعليمات البرمجية (على الرغم من أنك تحتاج إلى طاولة crc32 وظيفة) و لديه القليل جدا من الدولة ، ولكن psuedorandom دفق إخراج جدا دورة طويلة من الوقت قبل أن يكرر.كما أنها لا تتطلب SSE على المعالج.وعلى افتراض لديك CRC32 وظيفة يدوية ، تافهة لتنفيذ.

باستخدام masm615 إلى مترجم:

delay_function macro
    mov cx,0ffffh
.repeat
    push cx
    mov cx,0f00h
    .repeat
        dec  cx
        .until cx==0
    pop cx
    dec cx
    .until cx==0
endm

random_num macro
   mov  cx,64    ;assum we want to get 64 random numbers
   mov  si,0

get_num:    
   push cx
   delay_function    ;since cpu clock is fast,so we use delay_function
   mov  ah,2ch  
   int  21h
   mov  ax,dx     ;get clock 1/100 sec
   div  num       ;assume we want to get a number from 0~num-1
   mov  arry[si],ah   ;save to array you set
   inc  si
   pop  cx
   loop get_num   ;here we finish the get_random number 

كما كنت ربما يمكن أن تحاكي تحويل تسجيل مع XOR مجموع العناصر بين منفصلة بت ، والتي سوف تعطيك شبه عشوائي تسلسل الأرقام.

الخطية congruential (X = AX+C mod M) PRNG قد يكون فكرة جيدة لتعيين عن المجمع الحال كما والطلاب سوف تضطر إلى التعامل مع تحمل بت المتوسطة الفأس نتائج أكثر من 2^31 و حساب معامل.إذا كنت طالب فهي إلى حد ما واضحة لتنفيذها في المجمع و قد يكون ما المحاضر في الاعتبار.

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