सतत भारित यादृच्छिक वितरण, एक छोर से पक्षपाती


28

मैं वर्तमान में हमारे खेल के लिए एक कण प्रणाली में योगदान कर रहा हूं और कुछ उत्सर्जक आकार विकसित कर रहा हूं।

एक रेखा के साथ या एक आयताकार क्षेत्र के साथ मेरी समान यादृच्छिक वितरण ठीक काम करता है - कोई समस्या नहीं।

लेकिन अब मैं इस वितरण में 1 आयामी ढाल जैसा कुछ करना चाहूंगा। इसका मतलब उदाहरण के लिए निम्न मान उच्च मूल्यों की तुलना में अधिक सामान्य हैं।

मुझे नहीं पता कि इस समस्या के लिए उपयुक्त गणितीय शब्द क्या होंगे, इसलिए मेरे खोज कौशल इस एक के साथ बेकार हैं। मुझे कुछ ऐसा चाहिए जो कम्प्यूटेशनल रूप से सरल हो, क्योंकि कण प्रणाली को कुशल होने की आवश्यकता है।



क्या कोई भी पथरी का उल्लेख करने वाला नहीं है?
एलेक टील

जवाबों:


42

इस तस्वीर को देखिए:

वक्र मानचित्रण

यह वक्र को (यादृच्छिक) मान मैप करने की प्रक्रिया को दर्शाता है। मान लें कि आप एक समान रूप से वितरित यादृच्छिक मान X उत्पन्न करते हैं, 0 से लेकर 1 तक। इस मान को एक वक्र तक मैप करके - या, दूसरे शब्दों में, X के बजाय f (X) का उपयोग करके - आप अपने वितरण को किसी भी तरह से तिरछा कर सकते हैं। ।

इस चित्र में, पहले वक्र उच्च मूल्यों को अधिक संभावना बनाता है; दूसरा कम मूल्यों को अधिक संभावना बनाता है; और तीसरा बीच में मान क्लस्टर बनाता है। वक्र का सटीक सूत्र वास्तव में महत्वपूर्ण नहीं है, और आप की तरह चुना जा सकता है।

उदाहरण के लिए, पहला वक्र वर्गमूल की तरह थोड़ा सा दिखता है, और दूसरा - वर्ग की तरह। तीसरा एक घन जैसा है, केवल अनुवादित है। यदि आप वर्गमूल को बहुत धीमा मानते हैं, तो पहला वक्र भी f (X) = 1- ((1-X) ^ 2 - वर्ग का व्युत्क्रम जैसा दिखता है। या हाइपरबोले: f (X) = 2X / (1 + X)।

चौथे वक्र शो के रूप में, आप बस एक प्री-कम्यूटेड लुकअप टेबल का उपयोग कर सकते हैं। एक वक्र के रूप में बदसूरत दिखता है, लेकिन शायद एक कण प्रणाली के लिए पर्याप्त अच्छा होगा।

यह सामान्य तकनीक बहुत ही सरल और शक्तिशाली है। आपको जो भी वितरण की आवश्यकता है, बस एक वक्र मानचित्रण की कल्पना करें, और आप कुछ ही समय में एक सूत्र तैयार करेंगे। या, यदि आपके इंजन में एक संपादक है, तो वक्र के लिए एक दृश्य संपादक बनाएं!


आपके बहुत गहन और समझने योग्य स्पष्टीकरण के लिए आपका बहुत-बहुत धन्यवाद। अन्य सभी पोस्ट बहुत उपयोगी थे, लेकिन मैं वास्तव में आपकी पोस्ट को सबसे आसान और सबसे तेज़ समझ सकता था। यह बाहर छड़ी ई.पू. यह वास्तव में चीजों को समझने के मेरे तरीके के लिए जगह मारा। और जिन पहलुओं की आप व्याख्या कर रहे हैं वे वही हैं जो मैं देख रहा था (या भटक रहा था)! यह मुझे भविष्य में बहुत सारे मामलों में इसका उपयोग करने में सक्षम करेगा। फिर thx !!! btw, मैं उनमें से अपने कुछ घटता के साथ खेला और यह आकर्षण की तरह काम करता है।
didito

5
FYI करें: इन्हें मात्रात्मक कार्य कहा जाता है: en.wikipedia.org/wiki/Quantile_function
नील जी

8

एक लंबी व्याख्या:

यदि आपके पास वांछित संभावना वितरण है जैसे कि ग्रेडिएंट @ डिडिटो ने पूछा, तो आप एक फ़ंक्शन के रूप में वर्णन कर सकते हैं। मान लें कि आप एक त्रिकोणीय वितरण चाहते हैं, जहां 0 पर संभावना 0.0 है, और आप 0 से 1. एक यादृच्छिक संख्या चुनना चाहते हैं। हम इसे y = x के रूप में लिख सकते हैं।

अगला कदम इस फ़ंक्शन के अभिन्न की गणना करना है। इस स्थिति में, यह । 0 से 1 तक मूल्यांकन किया, वह to है। यह समझ में आता है - यह एक त्रिकोण है जिसका आधार 1 और ऊंचाई 1 है, इसलिए इसका क्षेत्रफल a है।x=1x2

फिर आप 0 से क्षेत्र (हमारे उदाहरण में point) तक एक यादृच्छिक बिंदु समान रूप से उठाते हैं। चलो इस z को बुलाओ। (हम संचयी वितरण से समान रूप से उठा रहे हैं ।)

अगला कदम पीछे की ओर जाना है, यह जानने के लिए कि x का मान क्या है (हम इसे x corresp कहेंगे) z के एक क्षेत्र से मेल खाता है। हम तलाश कर रहे हैं , जिसका मूल्यांकन 0 से x x तक है, जो z के बराबर है। जब आप के लिए हल , आप प्राप्त ।x=1x21x̂2=zx̂=2z

इस उदाहरण में, आप 0 से example तक z चुनते हैं और फिर वांछित यादृच्छिक संख्या । सरलीकृत, आप इसे रूप में लिख सकते हैं - बिल्कुल वही जो ईसेवी ने अनुशंसित किया था।2zrand(0,1)


अपने मूल्यवान इनपुट के लिए thx। मैं हमेशा सुनना पसंद करता हूं कि कुशल लोग समस्याओं को कैसे हल करते हैं। लेकिन मैं अभी भी मेरे सिर लपेटो करने के आसपास यह ईमानदार होने की जरूरत है ...
didito

यह कमाल का है। मैंने हमेशा sqrt(random())अपना पूरा जीवन बनाया लेकिन मैं इसके लिए पूरी तरह से तैयार हूं। एक यादृच्छिक संख्या को एक वक्र से टाई करने की कोशिश कर रहा है, और यह काम किया। अब जब कि मैं थोड़ा और अधिक कुशल गणितज्ञ हूं, यह जानना कि यह क्यों काम करता है बहुत मूल्यवान है!
गुस्तावो मैकिएल सेप

5

आप शायद एक घातीय प्रणाली का उपयोग करके आप जो चाहते हैं, उसके करीब एक सन्निकटन प्राप्त करेंगे।

X को 1- (rnd ^ value) जैसे कुछ के आधार पर बनाएं (मान लें कि rnd 0 और 1 के बीच है) और आपको जो आप उपयोग करते हैं उसके आधार पर बाएं से दाएं तिरछा करने के कुछ अलग व्यवहार मिलेंगे। एक उच्च मूल्य आपको अधिक तिरछा वितरण मिलेगा

व्यवहार में कुछ मोटे विचार प्राप्त करने के लिए आप एक ऑनलाइन रेखांकन उपकरण का उपयोग कर सकते हैं अलग समीकरण आपको उन्हें रखने से पहले देंगे, या आप सीधे अपने कण प्रणाली में समीकरणों के साथ बेला कर सकते हैं, यह निर्भर करता है कि आपके स्वाद के लिए कौन सी शैली अधिक है।

संपादित करें

एक कण प्रणाली की तरह कुछ के लिए जहां प्रति कण CPU समय बहुत महत्वपूर्ण है, Math.Pow (या भाषा समतुल्य) का उपयोग करके सीधे प्रदर्शन में कमी हो सकती है। यदि अधिक प्रदर्शन वांछित है, और मूल्य रन-टाइम में नहीं बदला जा रहा है, तो x ^ 2 के बजाय x * x जैसे समकक्ष फ़ंक्शन पर स्विच करने पर विचार करें।

(आंशिक विस्तारक एक मुद्दे का अधिक हो सकता है, लेकिन एक मजबूत गणित पृष्ठभूमि के साथ मैं शायद एक सन्निकटन समारोह बनाने के लिए एक अच्छा तरीका के साथ आ सकता है)


1
एक रेखांकन कार्यक्रम का उपयोग करने के बजाय, आप केवल बीटा वितरण की साजिश कर सकते हैं क्योंकि यह एक विशेष मामला है। दिए गए के लिए value, यह बीटा (मान, 1) है।
नील जी

धन्यवाद। मैं कुछ रेखांकन की कोशिश की और मुझे लगता है कि यह मुझे जहाँ मैं चाहता हूँ मिल सकता है।
didito

"बीटा वितरण" के साथ टिप के लिए @ नील जी धन्यवाद - यह दिलचस्प और उपयोगी लगता है ... मैं उस विषय पर कुछ शोध करूँगा
रात 11:37

3

आप जिस शब्द की तलाश कर रहे हैं Weighted Random Numbers, वह है , अधिकांश एल्गोरिदम मैंने उपयोग किए जाने वाले ट्रिगर कार्यों को देखा है, लेकिन मुझे लगता है कि मैंने एक तरीका निकाला है जो कुशल होगा:

यादृच्छिक फ़ंक्शन के लिए एक गुणक मान रखने वाली तालिका / सरणी / सूची (जो भी) बनाएं। इसे हाथ से या प्रोग्राम से भरें ...

randMulti= {.1,.1,.1,.1,.1,.1,.2,.2,.3,.3,.9,1,1,1,} 

... तो randomएक बेतरतीब ढंग से चुने गए randMultiऔर अंत में वितरण के अधिकतम मूल्य से गुणा करें ...

weightedRandom = math.random()*randMulti[Math.random(randMulti.length)]*maxValue

मुझे विश्वास है कि यह उपयोग करने की तुलना में बहुत तेज होगा sqrt, या अन्य अधिक कम्प्यूटेशनल रूप से जटिल कार्य करेगा, और अधिक कस्टम ग्रुपिंग पैटर्न के लिए अनुमति देगा।


2
यदि आप मेमोरी को त्याग सकते हैं, तो 100 पूर्व-गणना वाले मूल्यों की एक तालिका तेजी से (और थोड़ा अधिक सटीक) होगी। मुझे संदेह है कि उपयोगकर्ता पूर्ण और पूर्व-संकलित संस्करणों के बीच अंतर करने में सक्षम होगा।
डैनियल ब्लेज़ेक

@ डैनियल यह तेजी से होगा, लेकिन 100 यादृच्छिक मूल्यों के साथ, दोहराए जाने वाले पैटर्न को देखना बहुत आसान है।
अटैकिंगहोबो

सिर्फ इसलिए कि एक दोहराव पैटर्न प्रतीत होता है इसका मतलब यह नहीं है कि यह यादृच्छिक नहीं है। यादृच्छिकता का सार इसकी अप्रत्याशितता है, जिसका शाब्दिक अर्थ है कि जितना कोई भविष्यवाणी नहीं कर सकता है कि एक पैटर्न नहीं होगा, एक यह भी भविष्यवाणी नहीं कर सकता है कि कोई भी हो सकता है (कम से कम थोड़े समय के लिए)। आपको कुछ परीक्षण करने होंगे, लेकिन यदि आप अलग-अलग बीजों का उपयोग करके कई परीक्षणों के साथ पैटर्न पाते हैं, तो छद्म यादृच्छिक संख्या उत्पन्न करने के लिए आपके एल्गोरिदम की समीक्षा करने की आवश्यकता हो सकती है।
रैंडोल्फ रिचर्डसन

@AttackingHobo उस चाल के लिए thx। मुझे LUT का उपयोग पसंद है। और सूत्र समझने में काफी आसान है। मैं इस तरह से पहले नहीं सोचा था। पेड़ों के लिए लकड़ी नहीं देख ... :) मुझे भी लगता है कि दोहराए जाने वाले पैटर्न से बचा जाना चाहिए लेकिन शायद इस मामले में वैसे भी मान्यता प्राप्त नहीं होगी। फिर भी, सभी मूल्यों को पूर्वनिर्मित करने से दृश्य अनुभव को नुकसान होगा। वैसे भी, मुझे याद दिलाने के लिए कि यह यादृच्छिकता के विषय पर विचार करने का एक कारक है ...
didito

भारित "रैंडम नंबर" शब्द लाने के लिए भी धन्यवाद!
didito

2

मुझे लगता है कि आप जो पूछते हैं वह एक वर्गाकार रूट फ़ंक्शन का उपयोग करके प्राप्त किया गया वितरण है।

[position] = sqrt(rand(0, 1))

यह एकल आयाम क्षेत्र में एक वितरण देगा [0, 1]जहां किसी स्थिति के लिए संभावना उस स्थिति के बराबर होती है, अर्थात "त्रिकोणीय वितरण"।

वैकल्पिक स्क्वेररूट-मुक्त पीढ़ी:

[position] = 1-abs(rand(0, 1)-rand(0, 1))

इष्टतम कार्यान्वयन में एक वर्गमूल केवल कुछ गुणन है और बिना किसी शाखा के योग है। (देखें: http://en.wikipedia.org/wiki/Fast_inverse_square_root ) प्लेटफ़ॉर्म और रैंडम जेनरेटर के आधार पर इन दोनों में से कौन सा कार्य तेज़ हो सकता है। उदाहरण के लिए एक x86 प्लेटफ़ॉर्म पर यह यादृच्छिक जनरेटर में केवल कुछ अप्रत्याशित शाखाओं को ले जाएगा ताकि दूसरी विधि धीमी हो सके।


एक स्थिति की संभावना स्थिति के बराबर नहीं होगी (यह गणितीय रूप से असंभव है - तुच्छ रूप से, फ़ंक्शन के डोमेन और श्रेणी में 0.50 और 0.51 दोनों शामिल हैं), और न ही यह एक त्रिकोणीय वितरण है। ( en.wikipedia.org/wiki/Triangular_distribution )

1
जबकि sqrt कुछ दिलचस्प पैटर्न देता है, कण प्रणालियों को आमतौर पर प्रति कण बहुत सीपीयू प्रकाश की आवश्यकता होती है, इसलिए मैं जहां संभव हो वहां वर्गमूल (जो कि कम्प्यूटेशनल रूप से धीमा है) से बचने की सलाह देगा। आप कभी-कभी उन्हें केवल पूर्व-कंप्यूटिंग के साथ दूर कर सकते हैं, लेकिन यह आपके कणों को समय के साथ ध्यान देने योग्य संरक्षक बना सकता है।
लूनिन

1
@ जोए रेसेचिग, क्या आपने पढ़ा है कि विकिपीडिया लेख स्वयं, एक = 0, b = 1, c = 1 पीढ़ी के सूत्र में भरता है और आपको मेरी पोस्ट में सूत्र मिलता है।
आआआआआआआआआआआ आआआआ

3
@ लुनिन, जब आप अपने उत्तर में एक प्रतिपादक मिला है तो आप वर्गमूल के बारे में शिकायत क्यों कर रहे हैं?
आआआआआआआआआ आआआआआ

1
@ लुनिन: प्रदर्शन सिद्धांत एक बहुत उपेक्षित क्षेत्र है, बहुत से लोग सोचते हैं कि वे जानते हैं कि लगभग 30 साल पहले कहां सही था जब एएलयू बड़े महंगे और धीमे थे। यहां तक ​​कि प्रतिपादक फ़ंक्शन जो आपने अभी तक काफी धीमी अंकगणितीय फ़ंक्शन के रूप में खोजा है, शायद ही कभी एक अत्यधिक महत्वपूर्ण प्रदर्शन पापी है। ब्रांचिंग (एक इफ स्टेटमेंट का उपयोग करके) और कैश मिस (वर्तमान में कैश में रहने वाले डेटा का एक टुकड़ा पढ़ना) आमतौर पर सबसे अधिक प्रदर्शन की लागत होती है।
आआआआआआआआआआ आआआआ

1

बस एक बीटा वितरण का उपयोग करें:

  • बीटा (1,1) फ्लैट है
  • बीटा (1,2) एक रैखिक ढाल है
  • बीटा (1,3) द्विघात है

आदि।

दो आकार मापदंडों को पूर्णांक नहीं होना चाहिए।


आपकी मदद के लिए thx जैसा कि ऊपर कहा गया है, बीटा वितरण दिलचस्प लगता है। लेकिन मैं अभी तक विकिपीडिया पृष्ठ की सामग्री की समझ नहीं बना सकता। या एक सूत्र / कोड। खैर, मेरे पास अभी और समय नहीं है कि आगे की जांच करूं: सी देखें कि बूस्ट में बीटा डिस्ट्रीब्यूशन के लिए कोड है, लेकिन यह ओवरकिल होगा। ठीक है, मुझे लगता है कि मुझे पहले इसके माध्यम से जाने की जरूरत है और फिर अपना सरलीकृत संस्करण लिखना होगा।
रात 11:07

1
@ डिडिटो: यह इतना कठिन नहीं है। आप बस अपने uniform_generator()कॉल को बदलें gsl_ran_beta(rng, a, b)। यहां देखें: gnu.org/software/gsl/manual/html_node/…
नील जी

संकेत के लिए thx। मैं जीएसएल का उपयोग नहीं करता (वास्तव में इसके बारे में पहले नहीं सुना है), लेकिन अच्छी कॉल। मैं स्रोत की जाँच करेगा!
प्रातः

@ डिडिटो: उस मामले में, मैं लुनिन के समाधान के साथ जाऊंगा। सौभाग्य।
नील जी

0

और भी सरल, अपने यादृच्छिक जनरेटर की गति के आधार पर, आप केवल दो मान उत्पन्न कर सकते हैं और उन्हें औसत कर सकते हैं।

या, और भी अधिक सरल, जहां एक्स, रिग का परिणाम है, पहला double y = double(1/x);, पहला x = y*[maximum return value of rng];। यह संख्याओं को कम संख्या तक तेजी से बढ़ाएगा।

केंद्र के करीब मान प्राप्त करने की संभावना बढ़ाने के लिए अधिक मूल्य उत्पन्न और औसत करें।

बेशक यह केवल मानक घंटी घटता वितरण या उसके "संस्करणों" के लिए काम करता है, लेकिन एक तेज जनरेटर के साथ, यह sqrt जैसे विभिन्न गणित कार्यों का उपयोग करने से तेज और सरल हो सकता है।

आप पासा घंटी घटता के लिए इस पर सभी प्रकार के अनुसंधान पा सकते हैं। वास्तव में, Anydice.com एक अच्छी साइट है जो रोलिंग पासा के विभिन्न तरीकों के लिए रेखांकन उत्पन्न करती है। यद्यपि आप RNG का उपयोग कर रहे हैं, लेकिन आधार वही है, जैसा कि परिणाम हैं। इसलिए वितरण को देखने से पहले उसे कोडिंग करने के लिए यह एक अच्छा स्थान है।

* इसके अलावा, आप धुरी पर परिणाम वितरण को अक्ष के साथ जोड़ सकते हैं और औसत परिणाम को घटा सकते हैं और फिर अक्ष को जोड़ सकते हैं। उदाहरण के लिए, आप चाहते हैं कि कम मान अधिक सामान्य हों, और आपको यह कहना चाहिए कि आप चाहते हैं कि आपका न्यूनतम मूल्य 35 हो और 35 आपका अधिकतम मूल्य हो, 20 की श्रेणी हो। इसलिए आप 20 मानों की श्रेणी के साथ दो मान उत्पन्न और औसत करते हैं दो बार जो आप चाहते हैं), जो 20 पर केंद्रित एक बेल्चुरवे देगा (हम रेंज को 20 से 40 तक स्थानांतरित करने के लिए अंत में पांच घटाते हैं, 15 से 35 तक)। उत्पन्न संख्या X और Y को लें।

अंतिम संख्या,

z =(x+y)/2;// average them
If (z<20){z = (20-z)+20;}// fold if below axis
return z-5;// return value adjusted to desired range

यदि शून्य आपका न्यूनतम है, तो और भी बेहतर, इसके बजाय ऐसा करें,

z= (x+y)/2;
If (z<20){z = 20-z;}
else {z = z - 20;}
return z;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.