सीजेएम, 28 27 बाइट्स
PP+mr_mc\ms]1.mrmqf*"(,)".\
यह समाधान अस्वीकृति-आधारित नहीं है। मैं ध्रुवीय निर्देशांक में अंक उत्पन्न कर रहा हूं, लेकिन अंकों के एक समान घनत्व को प्राप्त करने के लिए रडार के गैर-समान वितरण के साथ।
इसका परीक्षण यहां करें।
व्याख्या
PP+ e# Push 2π.
mr_ e# Get a random float between 0 and 2π, make a copy.
mc\ e# Take the cosine of one copy and swap with the other.
ms] e# Take the sine of the other copy and wrap them in an array.
e# This gives us a uniform point on the unit circle.
1.mr e# Get a random float between 0 and 1.
mq e# Take the square root. This is the random radius.
f* e# Multiply x and y by this radius.
"(,)".\ e# Put the resulting numbers in the required format.
यह काम क्यों करता है? त्रिज्या r
और (छोटी) चौड़ाई की एक संकीर्ण वार्षिकी पर विचार करें dr
। क्षेत्र लगभग है2π*r*dr
(यदि एनलस संकरा है, तो आंतरिक और बाहरी परिधि लगभग समान है, और वक्रता को नजरअंदाज किया जा सकता है, जैसे कि क्षेत्र को परिधि की लंबाई और चौड़ाई के साथ एक आयत के रूप में माना जा सकता है वलय)। तो क्षेत्र त्रिज्या के साथ रैखिक रूप से बढ़ता है। इसका मतलब यह है कि हम एक यादृच्छिक घनत्व का एक रैखिक वितरण भी चाहते हैं, ताकि एक निरंतर घनत्व प्राप्त करने के लिए (त्रिज्या के दोगुने पर, भरने के लिए दोगुना क्षेत्र है, इसलिए हम वहां दो बार अधिक से अधिक अंक चाहते हैं)।
हम 0 से 1 तक एक रैखिक यादृच्छिक वितरण कैसे उत्पन्न करते हैं? आइए पहले असतत मामले को देखें। कहते हैं, हमारे पास 4 मूल्यों का वांछित वितरण है, जैसे {0.1, 0.4, 0.2, 0.3}
(जैसे हम चाहते 1
हैं कि 4 गुना सामान्य हो 0
, और दो बार जितना आम हो 2
; हम 3
तीन बार उतना ही सामान्य चाहते हैं 0
):
वांछित वितरण के साथ चार मूल्यों में से एक को कैसे चुन सकते हैं? हम उन्हें ढेर कर सकते हैं, y- अक्ष पर 0 और 1 के बीच समान रूप से यादृच्छिक मूल्य चुन सकते हैं और उस बिंदु पर खंड चुन सकते हैं:
हालांकि इस पिक की कल्पना करने का एक अलग तरीका है। हम इसके स्थान पर मानों के संचय के साथ वितरण के प्रत्येक मूल्य को बदल सकते हैं:
और अब हम इस चार्ट की शीर्ष रेखा को एक फ़ंक्शन के रूप में मानते हैं और एक फ़ंक्शन f(x) = y
प्राप्त करने के लिए इसे उल्टा करते हैं , जिसे हम समान रूप से यादृच्छिक रूप से लागू कर सकते हैं :g(y) = f-1(y) = x
y ∈ [0,1]
कूल, इसलिए रेडी के एक रैखिक वितरण को उत्पन्न करने के लिए इसका उपयोग कैसे किया जा सकता है? यह वह वितरण है जो हम चाहते हैं:
पहला कदम वितरण के मूल्यों को संचित करना है। लेकिन वितरण जारी है, इसलिए पिछले सभी मूल्यों पर संक्षेप के बजाय, हम से एक अभिन्न अंग लेते 0
हैं r
। हम आसानी से उस विश्लेषणात्मक हल कर सकते हैं :। हालाँकि, हम चाहते हैं कि इसे सामान्यीकृत किया जाए, अर्थात इसे एक स्थिर से गुणा करने के लिए यह अधिकतम मूल्य देता है , इसलिए हम वास्तव में जो चाहते हैं वह है :∫0r r dr = 1/2 r2
1
r
r2
और अंत में, हम इसे एक फ़ंक्शन प्राप्त करने के लिए उलटा करते हैं [0,1]
, जिसमें हम एक समान मूल्य पर लागू कर सकते हैं , जिसे हम फिर से विश्लेषणात्मक रूप से कर सकते हैं: यह सिर्फ है r = √y
, जहां y
यादृच्छिक मूल्य है:
यह एक काफी उपयोगी तकनीक है जिसका उपयोग अक्सर साधारण वितरण को सटीक रूप से उत्पन्न करने के लिए किया जा सकता है (यह किसी भी वितरण के लिए काम करता है, लेकिन जटिल लोगों के लिए अंतिम दो चरणों को संख्यात्मक रूप से हल करना पड़ सकता है)। हालाँकि, मैं उत्पादन कोड में इस विशेष मामले में इसका उपयोग नहीं करूंगा, क्योंकि वर्गमूल, साइन और कोसाइन निषेधात्मक रूप से महंगे हैं: एक अस्वीकृति-आधारित एल्गोरिथ्म का उपयोग औसतन बहुत तेज़ी से होता है, क्योंकि इसमें केवल जोड़ और गुणा की आवश्यकता होती है।