هل هناك شيء مثل مولد رقم عشوائي مستمر يمكن الوصول إليه بشكل عشوائي؟ (ويفضل مفتوح المصدر)

StackOverflow https://stackoverflow.com/questions/3019169

  •  26-09-2019
  •  | 
  •  

سؤال

أولاً ، هل هناك شيء مثل مولد الأرقام العشوائية العشوائية ، حيث لا يمكنك فقط إنشاء أرقام عشوائية بشكل متتابع لأننا جميعًا ، على افتراض أن Rand100 () يولد دائمًا قيمة من 0-100:

for (int i=0;i<5;i++)
   print rand100()

output: 
14
75
36
22
67

ولكن أيضا الوصول عشوائيا أي قيمة عشوائية مثل:

Rand100 (0) سوف يخرج 14 طالما لم تغير البذور

Rand100 (3) سوف يخرج دائمًا 22

Rand100 (4) سوف يخرج دائمًا 67

وهلم جرا...

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

هل هناك مولد أرقام عشوائية وصول عشوائي للبذور ، ويفضل أن يكون مفتوح المصدر؟ أم أن هناك مصطلحًا أفضل لهذا يمكنني الحصول على مزيد من المعلومات؟

إذا لم يكن الأمر كذلك ، فسيكون الجزء 2 من سؤالي ، هل هناك أي مولد رقم عشوائي مفتوح المصدر قابل للبذور التقليدي للبذور حتى أتمكن من نقله إلى منصات/لغات متعددة مع الحفاظ على تسلسل ثابت من القيم لكل منصة لأي بذرة معينة؟

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

المحلول

ال عائلة PCG يمكن لمولدات الأرقام العشوائية PSUEDO القفز إلى الأمام والخلف في الوقت اللوغاريتمي (أي القفز إلى الأمام يتطلب رقم 1 من O (سجل (1000)) عمليات) ، والتي ربما تكون جيدة بما يكفي لاعتبار وصول عشوائي. تدعم تطبيقات C و C ++ المرجعية هذه الميزة.

يشير الجدول على الصفحة الأولى لموقع PCG إلى أن عددًا من المولدات الأخرى يمكن أن يدعم القفز ، لكنني لم أره في أي تطبيقات.

نصائح أخرى

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

بلوم بلوم شوب هو مولد أرقام الكاذبة مع البذور والوصول العشوائي إلى أي قيمة يولدها.

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

إنها ضجيج بيرلين الفصل الذي يمكن العثور عليه هنا. لست متأكدًا من مدى تعقيد هذا الحسابي بالنسبة لمولد الأرقام العشوائية التقليدية ، وهو مصدر قلق ، لأن أحد المنصات المخطط لها هو Android. وأيضًا ، فإن ضوضاء Perlin ليست هي نفسها مثل الكاذب ، ولكن من ما يمكنني قول كما مجرد ظهور العشوائية.

يسمح هذا الحل بالبذر ، ويسمح أيضًا بأخذ عينات من مجموعة عشوائية من أي نقطة ، وبعبارة أخرى ، عشوائي الوصول العشوائي.

فيما يلي مثال على مجموعة من C ++ العشوائية العادية (Rand ٪ 200) على العمود الأيسر للمقارنة ، وضوضاء Perlin (بما يعادل ٪ 200) على اليمين:

91 , 100
48 , 97
5 , 90
93 , 76
197 , 100
97 , 114
132 , 46
190 , 67
118 , 103
78 , 96
143 , 110
187 , 108
139 , 79
69 , 58
156 , 81
123 , 128
84 , 98
15 , 105
178 , 117
10 , 82
13 , 110
182 , 56
10 , 96
144 , 64
133 , 105

كلاهما تم زرعه على 0

كانت المعلمات لضوضاء بيرلين

octaves = 8
amplitude = 100 
frequency = 9999
width/height = 10000,100

كان ترتيب أخذ العينات المتسلسل لضوضاء بيرلين ببساطة

for (int i=0;i<24;i++)
    floor(Get(i,i)+100);
//amplitude 100 generates noise between -100 and 100, 
//so adding 100 generates between 0 and 200

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

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

على سبيل المثال: قل أنك تريد خلط عشوائي من الأعداد الصحيحة من 0 إلى (2^32) -1. يمكنك تحقيق ذلك باستخدام تشفير كتلة يأخذ 4 بايت إدخال ، وإرجاع 4 بايت مشفرة. للتكرار عبر السلسلة ، أولاً "تشفير" كتلة من القيمة 0 ، ثم 1 ، ثم 2 ، وما إلى ذلك ، إذا كنت تريد فقط العنصر 1 مليون في التسلسل المخلل ، فأنت فقط تشفير رقم 1،000،000.

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

بعد قول كل هذا ، يعد حل @Michaelburr أكثر ملاءمة لموقفك ، وأوصيك باستخدامه.

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

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

#define PRIME1 7001
#define PRIME2 7013
#define PRIME3 7019

static int pad1[PRIME1];
static int pad2[PRIME2];
static int pad3[PRIME3];

static void random_no_init (void)
{
  static int initialized = 0;
  int i;
  if (initialized)
    return;
  for (i = 0; i < PRIME1; i++) pad1[i] = random ();
  for (i = 0; i < PRIME2; i++) pad2[i] = random ();
  for (i = 0; i < PRIME3; i++) pad3[i] = random ();

  initialized = 1;
}

int random_no (int no)
{
   random_no_init ();
   return pad1[no % PRIME1] ^ pad2[no % PRIME2] ^ pad3[no % PRIME3];
}

توضح عينة الكود أعلاه مثالًا بسيطًا يعطي 344618953247 إدخالًا يمكن الوصول إليه بشكل عشوائي. لضمان نتائج قابلة للتكرار بين التشغيل ، يجب أن تزود مولد الأرقام العشوائية ببذور. يمكن العثور على نظام أكثر تعقيدًا مبني على نفس المبدأ مع تباين البذور استنادًا إلى اختيار الأعداد الأولية المختلفة http://git.gnome.org/browse/gegl/tree/gegl/gegl-random.c

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

الأقرب الذي يمكن أن تأتي هو أخذ بذرة ثابتة ، وتجزئة ذلك ، ثم تجزئة قيمة الفهرس ، باستخدام شيء يمزج بحماس حقًا.

أو إنشاء قائمة طويلة منها وتخزينها.

ألقِ نظرة على براءة الاختراع هذه: مولد العشوائي العشوائي العشوائيhttps://patents.google.com/patent/us4791594

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

تتمثل الفكرة في استخدام عنوان الإدخال كبتات تحكم لتدافع أرقام البذور المتعددة ، ثم XOR النتائج لإنتاج إخراج ، ثم تمريرة ثانية من التدافع باستخدام النتيجة التي تم إنشاؤها من الممر السابق.

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