مولد الأرقام العشوائية التي تنتج توزيع قانون السلطة؟

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

  •  06-09-2019
  •  | 
  •  

سؤال

أنا أكتب بعض الاختبارات للحصول على تطبيق Linux Linux C ++. أود إنشاء مجموعة من الأعداد الصحيحة مع توزيع قوانين كهرباء / ذيل طويل. وهذا يعني، أحصل على بعض الأرقام في كثير من الأحيان ولكن معظمهم بشكل غير منتظم نسبيا.

من الناحية المثالية، سيكون هناك بعض المعادلات السحرية التي يمكنني استخدامها مع RAND () أو واحدة من الوظائف العشوائية Stdlib. إذا لم يكن كذلك، فإن جزء سهل الاستخدام من C / C ++ سيكون رائعا.

شكرا!

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

المحلول

هذه الصفحة في Wolfram Mathworld يناقش كيفية الحصول على توزيع قانون السلطة من توزيع موحد (وهو ما يوفره معظم مولدات الأرقام العشوائية).

الإجابة القصيرة (الاشتقاق في الرابط أعلاه):

x = [(x1^(n+1) - x0^(n+1))*y + x0^(n+1)]^(1/(n+1))

أين Y. هو متغير موحد، ن هي قوة التوزيع، X0. و X1. تحديد نطاق التوزيع، و عاشر هو قوانين الطاقة الخاصة بك توزع المتغير.

نصائح أخرى

إذا كنت تعرف التوزيع الذي تريده (تسمى وظيفة توزيع الاحتمالات (PDF)) ولديه تطبيعه بشكل صحيح، فيمكنك دمجه للحصول على وظيفة التوزيع التراكمي (CDF)، ثم عكس CDF (إن أمكن) للحصول على التحول الحاجة من الزي الرسمي [0,1] التوزيع على ما تريد الخاص بك.

لذلك تبدأ بتحديد التوزيع الذي تريده.

P = F(x)

(ل X في [0،1]) ثم دمجها لإعطاء

C(y) = \int_0^y F(x) dx

إذا كان هذا يمكن قلبك تحصل عليه

y = F^{-1}(C)

لذلك ندعو rand() وقم بتوصيل النتيجة C في السطر الأخير واستخدام y.

تسمى هذه النتيجة نظرية أخذ العينات الأساسية. هذا هو متاعب بسبب متطلبات التطبيع والحاجة إلى قلب التحليلية.

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

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


ينتقل الحقيقي هنا هو بهذه البساطة x^-n التوزيعات غير صالحة للحياة على النطاق [0,1], ، لذلك لا يمكنك استخدام نظرية أخذ العينات. جرب (x + 1) ^ - n بدلا من ذلك ...

لا أستطيع التعليق على الرياضيات المطلوبة لإنتاج توزيع قانون السلطة (الوظائف الأخرى لها اقتراحات) ولكن أود أن أقترح عليك تعرف نفسك على مرافق رقم عشوائي TR1 C ++ Library <random>. وبعد هذه توفر وظيفة أكثر من std::rand و std::srand. وبعد يحدد النظام الجديد واجهة برمجة تطبيقات وحدات للمولدات والمحركات والتوزيعات وتزويد مجموعة من المسبقة.

الإعدادات المسبقة التوزيع المضمنة هي:

  • uniform_int
  • bernoulli_distribution
  • geometric_distribution
  • poisson_distribution
  • binomial_distribution
  • uniform_real
  • exponential_distribution
  • normal_distribution
  • gamma_distribution

عند تحديد توزيع قانون الطاقة الخاص بك، يجب أن تكون قادرا على توصيله بالمولدات والمحركات الموجودة. الكتاب ملحقات مكتبة C ++ القياسية بقلم بيت بيكر لديه فصل رائع <random>.

هنا مقال حول كيفية إنشاء توزيعات أخرى (مع أمثلة Cauchy، Chi-Squared، Student T و Snedecor F)

أردت فقط إجراء محاكاة فعلية كتكمل للإجابة المقبولة (بحق). على الرغم من أنه في ص، فإن الكود بسيط للغاية ليكون (pseudo) -pseudo-code.

فرق واحد صغير بين Wolfram Mathworld Formula. في الإجابة المقبولة وغيرها، ربما أكثر شيوعا، المعادلات هي حقيقة أن قانون السلطة للأسف n (والذي يشير عادة باسم ألفا) لا يحمل علامة سلبية صريحة. لذلك يجب أن تكون قيمة ألفا المختارة سلبية، وعادة ما بين 2 و 3.

x0 و x1 الوقوف على الحدود السفلية والعليا للتوزيع.

حتى هنا هو عليه:

x1 = 5           # Maximum value
x0 = 0.1         # It can't be zero; otherwise X^0^(neg) is 1/0.
alpha = -2.5     # It has to be negative.
y = runif(1e5)   # Number of samples
x = ((x1^(alpha+1) - x0^(alpha+1))*y + x0^(alpha+1))^(1/(alpha+1))
hist(x, prob = T, breaks=40, ylim=c(0,10), xlim=c(0,1.2), border=F, 
col="yellowgreen", main="Power law density")
lines(density(x), col="chocolate", lwd=1)
lines(density(x, adjust=2), lty="dotted", col="darkblue", lwd=2)

enter image description here

أو رسمها في مقياس لوغاريتمي:

h = hist(x, prob=T, breaks=40, plot=F)
     plot(h$count, log="xy", type='l', lwd=1, lend=2, 
     xlab="", ylab="", main="Density in logarithmic scale")

enter image description here

هنا هو ملخص البيانات:

> summary(x)
   Min.   1st Qu.  Median    Mean   3rd Qu.    Max. 
  0.1000  0.1208  0.1584    0.2590  0.2511   4.9388 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top