สร้างจุดสุ่มภายในวงกลม (สม่ำเสมอ)


212

ฉันต้องการที่จะสร้างจุดสุ่มสม่ำเสมอภายในวงกลมรัศมีR

ฉันรู้ว่าเพียงแค่เลือกมุมสุ่มอย่างสม่ำเสมอในช่วงเวลา [0 ... 2π) และรัศมีสุ่มอย่างสม่ำเสมอในช่วงเวลา (0 ... R ) ฉันจะจบลงด้วยคะแนนที่มากขึ้นสู่จุดศูนย์กลางเนื่องจากสอง รัศมีจุดในรัศมีขนาดเล็กจะใกล้กันมากกว่าสำหรับจุดในรัศมีขนาดใหญ่

ฉันพบรายการบล็อกที่นี่ตรงนี้แต่ฉันไม่เข้าใจเหตุผลของเขา ฉันคิดว่ามันถูกต้อง แต่ฉันอยากจะเข้าใจจากที่เขาได้รับ (2 / R 2 ) × rและวิธีการที่เขาได้มาซึ่งทางออกสุดท้าย


ปรับปรุง: 7 ปีหลังจากโพสต์คำถามนี้ฉันยังไม่ได้รับคำตอบที่น่าพอใจสำหรับคำถามจริงเกี่ยวกับคณิตศาสตร์ที่อยู่เบื้องหลังอัลกอริทึมรากที่สอง ดังนั้นฉันใช้เวลาหนึ่งวันในการเขียนคำตอบด้วยตัวเอง เชื่อมโยงไปยังคำตอบของฉัน


18
ข้อเสียเปรียบของการปฏิเสธการสุ่มตัวอย่างเป็นเรื่องใหญ่จริงหรือ จำนวนครั้งที่ต้องการคาดหวังคือ 4 / π≈ 1.27 และความน่าจะเป็นที่คุณต้องการมากกว่าจำนวนครั้งที่พยายามคือ (1-π / 4) ^ k สำหรับk = 20นี่คือ≈ .00000000000004 และสำหรับ k = 50 มันอยู่ในลำดับที่ 10 ^ {- 34} คุณสามารถรับโอกาสเหล่านั้นได้ทุกวัน คุณจะทำได้ดี
ShreevatsaR

3
อันที่จริงการสุ่มตัวอย่างการปฏิเสธจะให้การรับประกันสำหรับการยกเลิก อัตราต่อรองอยู่ในระดับต่ำสุด (จะแม่นยำศูนย์) ว่าอัลกอริทึมของคุณจะไม่สิ้นสุด
Jared Nielsen

2
ในความคิดของฉันความสำคัญของข้อเสียเปรียบของการสุ่มตัวอย่างการปฏิเสธนั้นเป็นสัดส่วนกับความสะดวกในการใช้วิธีการสุ่มตัวอย่างที่หลีกเลี่ยงการปฏิเสธ ในกรณีนี้ข้อเสียเปรียบมีความสำคัญเนื่องจากการสุ่มตัวอย่างโดยไม่มีการปฏิเสธนั้นง่าย
spex

4
@spex ในทางปฏิบัติเทคนิคการปฏิเสธนั้นเร็วขึ้นเพราะจะช่วยลดความจำเป็นในการประเมินฟังก์ชั่นที่ยอดเยี่ยม
pjs

2
(ต่อ) การปฏิเสธ: 0.52 วินาทีทั้งหมดให้วิธีการที่เหมือนกันและส่วนเบี่ยงเบนมาตรฐาน (ถึง 3 sig. รูปที่) ตามที่คาดไว้การสุ่มตัวอย่างการปฏิเสธล้มเหลว 27% ของเวลา (4 / pi-1) จำเป็นต้องใช้ตัวเลขสุ่มมากกว่า btilly 27% แต่น้อยกว่า sigfpe 15% สิ่งนี้เป็นการยืนยันความคิดเห็นที่ทำโดย pjs และอื่น ๆ ว่าการสุ่มตัวอย่างการปฏิเสธอาจเป็นวิธีที่ดีที่สุดเว้นแต่ว่าค่าไถ่จะแพงมาก
Peter Davidson

คำตอบ:


189

ลองเข้าหาสิ่งนี้เช่นอาร์คิมีดีส

เราจะสร้างจุดอย่างสม่ำเสมอในรูปสามเหลี่ยม ABC ได้ที่ไหน | AB | = | BC | มาทำให้มันง่ายขึ้นด้วยการขยายเป็น ABCD รูปสี่เหลี่ยมด้านขนาน มันง่ายที่จะสร้างคะแนนอย่างสม่ำเสมอใน ABCD เราเลือกจุดสุ่ม X บน AB และ Y ใน BC และเลือก Z ดังนั้น XBYZ เป็นสี่เหลี่ยมด้านขนาน เพื่อให้ได้จุดที่เลือกอย่างสม่ำเสมอในสามเหลี่ยมเดิมเราแค่พับจุดใด ๆ ที่ปรากฏใน ADC กลับไปที่ ABC พร้อม AC

พิจารณาวงกลม ในขีด จำกัด เราสามารถคิดได้ว่ามันเป็นรูปสามเหลี่ยมหลายรูปแบบ ABC โดยมี B ที่จุดกำเนิดและ A และ C บนเส้นรอบวงซึ่งใกล้เคียงกัน เราสามารถเลือกหนึ่งในสามเหลี่ยมเหล่านี้ได้ง่ายๆโดยเลือกมุมทีต้า ดังนั้นตอนนี้เราต้องสร้างระยะทางจากศูนย์กลางโดยการเลือกจุดในเศษไม้ ABC ขยายไปยัง ABCD อีกครั้งโดยที่ D อยู่ในรัศมีสองครั้งจากจุดศูนย์กลางวงกลม

การเลือกจุดสุ่มใน ABCD นั้นทำได้ง่ายโดยใช้วิธีการข้างต้น เลือกจุดสุ่มบน AB เลือกจุดสุ่มบน BC อย่างสม่ำเสมอ กล่าวคือ เลือกคู่ของตัวเลขสุ่ม x และ y อย่างสม่ำเสมอบน [0, R] โดยให้ระยะทางจากศูนย์กลาง สามเหลี่ยมของเราคือเศษไม้บาง ๆ ดังนั้น AB และ BC จึงขนานกันโดยพื้นฐาน ดังนั้นจุด Z คือระยะทาง x + y จากจุดกำเนิด ถ้า x + y> R เราพับกลับลง

นี่คืออัลกอริทึมที่สมบูรณ์สำหรับ R = 1 ฉันหวังว่าคุณจะเห็นด้วยมันค่อนข้างง่าย มันใช้ตรีโกณมิติ แต่คุณสามารถรับประกันได้ว่าจะใช้เวลานานเท่าใดและต้องใช้การrandom()โทรเท่าไหร่

t = 2*pi*random()
u = random()+random()
r = if u>1 then 2-u else u
[r*cos(t), r*sin(t)]

นี่มันอยู่ใน Mathematica

f[] := Block[{u, t, r},
  u = Random[] + Random[];
  t = Random[] 2 Pi;
  r = If[u > 1, 2 - u, u];
  {r Cos[t], r Sin[t]}
]

ListPlot[Table[f[], {10000}], AspectRatio -> Automatic]

ป้อนคำอธิบายรูปภาพที่นี่


6
@ Karelzarath ฉันชอบความคิดที่แยบยลของรูปสามเหลี่ยมบาง ๆ ที่ยังคงกว้างกว่าปลายด้านอื่น :-) มันได้รับคำตอบที่ถูกต้อง
sigfpe

2
@hammar ไม่แน่ใจว่ามันพูดได้ดีกับขนาดทั่วไป แต่สำหรับ 3d คุณสามารถใช้ผลลัพธ์อื่นโดย Archimedes! ใช้ทฤษฎีบท "กล่องหมวก" เพื่อสร้างจุดบนทรงกระบอก (ง่าย!) แล้วแมปกลับไปยังทรงกลม ที่ให้ทิศทาง ตอนนี้ใช้random()+random()+random()กับการพับที่ซับซ้อนมากขึ้น (เช่นการพับแบบ 6 ทิศทางแบบขนานที่มีขนาดบางเป็นอินเทอร์เนท) ไม่เชื่อว่านี่เป็นวิธีการที่ดี
sigfpe

2
ฉันคิดว่า 1 นาทีเพื่อหาความแตกต่างระหว่าง random () + random () และ 2 * random () ... ฉันโง่มาก: /
JiminP

3
@ Tharwen สังเกตว่าวงกลมมีจุดเพิ่มเติมที่รัศมี 0.9-1.0 ได้อย่างไรที่รัศมี 0.0-0.1 random () + random () สร้าง radii มากกว่าที่ประมาณ 1.0 แต่อยู่ในช่วง 0.0-2.0 เมื่อพับลงพวกเขามีแนวโน้มที่จะอยู่ที่ประมาณ 1.0 และมักจะอยู่ในช่วง 0.0-1.0 ยิ่งไปกว่านั้นมันเป็นสัดส่วนที่จำเป็นในประโยคแรกของความคิดเห็นนี้ เพียงแค่ลดลงครึ่งหนึ่งจะสร้างตัวเลขเพิ่มขึ้นประมาณ 0.5 และนั่นอาจจะผิด
sigfpe

2
@ ธาร์เวนลองใช้ทั้งสองแบบเพื่อสร้างตัวเลขสุ่มและดูว่าคุณได้อะไร 2 * random () ให้ตัวเลขที่กระจายอย่างสม่ำเสมอในช่วง 0 ถึง 2 random () + random () ให้ตัวเลขในช่วง 0 ถึง 2 แต่จะมี (โดยปกติ) เป็นตัวเลขมากกว่า 1.0 ใกล้ 0.0 หรือ 2.0 มันเหมือนกับว่าการทอยลูกเต๋าสองครั้งและการสรุปมีแนวโน้มที่จะให้ 7 มากกว่าหมายเลขอื่น ๆ
sigfpe

133

วิธีสร้างจุดสุ่มภายในวงกลมรัศมีR :

r = R * sqrt(random())
theta = random() * 2 * PI

(สมมติว่าrandom()ให้ค่าระหว่าง 0 และ 1 เหมือนกัน)

หากคุณต้องการแปลงเป็นพิกัดคาร์ทีเซียนคุณสามารถทำได้

x = centerX + r * cos(theta)
y = centerY + r * sin(theta)


ทำไมsqrt(random())?

ดู Let 's sqrt(random())คณิตศาสตร์ที่นำไปสู่ สมมติว่าความเรียบง่ายที่เราทำงานกับวงกลมหน่วยคือR = 1

ระยะทางเฉลี่ยระหว่างจุดควรเท่ากันโดยไม่คำนึงว่าไกลแค่ไหนจากจุดศูนย์กลางที่เรามอง นี่หมายถึงตัวอย่างเช่นเมื่อมองไปที่เส้นรอบวงของวงกลมที่มีเส้นรอบวง 2 เราควรหาจุดสองเท่าตามจำนวนจุดบนปริมณฑลของวงกลมที่มีเส้นรอบวง 1


                

ตั้งแต่เส้นรอบวงของวงกลม (2π R ) เติบโตขึ้นเป็นเส้นตรงกับRมันตามที่จำนวนของจุดสุ่มจะเติบโตเป็นเส้นตรงกับR กล่าวอีกนัยหนึ่งฟังก์ชันความหนาแน่นของความน่าจะเป็นที่ต้องการ(PDF) จะเพิ่มขึ้นเป็นเส้นตรง เนื่องจาก PDF ควรมีพื้นที่เท่ากับ 1 และรัศมีสูงสุดคือ 1 เราจึงมี


                

ดังนั้นเราจึงรู้ว่าความหนาแน่นที่ต้องการของค่าสุ่มของเราควรเป็นอย่างไร ตอนนี้: เราจะสร้างค่าสุ่มได้อย่างไรเมื่อทั้งหมดที่เรามีคือค่าสุ่มที่สม่ำเสมอระหว่าง 0 ถึง 1

เราใช้เคล็ดลับที่เรียกว่าการสุ่มตัวอย่างการแปลงผกผัน

  1. จาก PDF ให้สร้างฟังก์ชันการแจกแจงสะสม (CDF)
  2. สะท้อนสิ่งนี้ตามy = x
  3. ใช้ฟังก์ชันผลลัพธ์กับค่าสม่ำเสมอระหว่าง 0 ถึง 1

ฟังดูซับซ้อนไหม? ให้ฉันแทรก blockquote ด้วยเพลงเล็ก ๆ ที่สื่อถึงสัญชาตญาณ:

สมมติว่าเราต้องการสร้างจุดสุ่มด้วยการแจกแจงต่อไปนี้:

                

นั่นคือ

  • 1/5 ของคะแนนเท่ากันระหว่าง 1 และ 2 และ
  • 4/5 ของคะแนนอย่างสม่ำเสมอระหว่าง 2 และ 3

CDF คือเวอร์ชั่นสะสมของ PDF สังหรณ์ใจ: ในขณะที่รูปแบบไฟล์ PDF ( x ) อธิบายจำนวนของค่าสุ่มที่ x , CDF ( x ) อธิบายจำนวนของค่าสุ่มน้อยกว่า x

ในกรณีนี้ CDF จะมีลักษณะดังนี้:

                

เพื่อดูว่ามันมีประโยชน์อย่างไรลองจินตนาการว่าเรายิงกระสุนจากซ้ายไปขวาที่ความสูงเท่ากัน เมื่อกระสุนพุ่งเข้าแถวพวกเขาก็ตกลงไปที่พื้น:

                

ดูว่าความหนาแน่นของกระสุนบนพื้นดินสอดคล้องกับการกระจายตัวที่เราต้องการได้อย่างไร! เราเกือบจะถึงแล้ว!

ปัญหาคือว่าสำหรับฟังก์ชั่นนี้Yแกนเป็นเอาท์พุทและxแกนคือการป้อนข้อมูล เราทำได้แค่ "กระสุนยิงจากพื้นดินขึ้นไป"! เราต้องการฟังก์ชันอินเวอร์ส!

นี่คือเหตุผลที่เราสะท้อนสิ่งทั้งหมด xกลายเป็นyและyกลายเป็นx :

                

เราเรียกสิ่งนี้CDF -1 เพื่อรับค่าตามการแจกแจงที่ต้องการเราใช้ CDF -1 (สุ่ม ())

... เพื่อกลับไปสร้างค่ารัศมีสุ่มที่รูปแบบไฟล์ PDF ของเราเท่ากับ 2 x

ขั้นตอนที่ 1: สร้าง CDF:

เนื่องจากเรากำลังทำงานกับ reals CDF จึงแสดงเป็นส่วนหนึ่งของ PDF

CDF ( x ) = ∫ 2 x = x 2

ขั้นตอนที่ 2: จำลอง CDF ตามy = x :

ในทางคณิตศาสตร์สิ่งนี้ทำให้เดือดร้อนเพื่อแลกเปลี่ยนxและyและแก้หาy :

CDF :      y = x 2
สลับ:    x = y 2
แก้ปัญหา:    y = √ x
CDF -1 :   y = √ x

ขั้นตอนที่ 3: ใช้ฟังก์ชันผลลัพธ์กับค่าสม่ำเสมอระหว่าง 0 ถึง 1

CDF -1 (สุ่ม ()) = √random ()

อะไรคือสิ่งที่เรากำหนดไว้ว่าจะได้รับ :-)


อัลกอริทึมนี้สามารถใช้ในการสร้างจุดบนวงแหวนได้อย่างมีประสิทธิภาพ
Ivan Kovtun

บนแหวน? ชอบรัศมีที่กำหนดหรือไม่? ไม่แน่ใจว่าฉันเข้าใจคำถามของคุณหรือไม่ แต่ถ้าคุณมีรัศมีคงที่คุณต้องสุ่มมุม
aioobe

2
ฉันพยายามใช้คำว่า "Ring" ง่ายกว่าแทน Annulus - ขอบเขตที่ล้อมรอบด้วยวงกลมสองวง ในกรณีนี้การปฏิเสธอัลกอริธึมจะไม่มีประสิทธิภาพและอัลกอริธึมบนสุดแรกยากที่จะพูดคุย และมุมตัวเรือนที่มีรัศมีหนึ่งตัวก็ถูกปกคลุมด้วยอัลกอริทึมของคุณ เราสร้างรัศมีเป็น sqrt (สุ่ม (min_radius ^ 2, max_radius ^ 2)) เสมอแม้ว่า min_radius == max_radius
Ivan Kovtun

1
ดี! เมื่อคุณพูดอย่างชัดเจนrandom(min_radius², max_radius²)คุณหมายถึงบางสิ่งที่เทียบเท่าได้random() * (max_radius² - min_radius²) + min_radius²ซึ่งrandom()ส่งกลับค่าสม่ำเสมอระหว่าง 0 ถึง 1 หรือไม่
aioobe

ใช่นั่นคือสิ่งที่ฉันหมายถึง: radius = sqrt (random () * (max_radius² - min_radius²) + min_radius²)
Ivan Kovtun

27

นี่เป็นวิธีแก้ปัญหาที่ง่ายและรวดเร็ว

เลือกสองตัวเลขสุ่มในช่วง (0, 1) คือและa bถ้าb < aสลับพวกเขา (b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b))จุดคุณคือ

คุณสามารถคิดถึงวิธีนี้ได้ดังนี้ หากคุณเอาวงกลมตัดออกแล้วยืดออกคุณจะได้สามเหลี่ยมมุมฉาก สเกลที่สามเหลี่ยมลงและคุณจะต้องเป็นรูปสามเหลี่ยมจาก(0, 0)ที่จะ(1, 0)ไปและกลับมาอีกครั้งเพื่อ(1, 1) (0, 0)การเปลี่ยนแปลงทั้งหมดเหล่านี้เปลี่ยนความหนาแน่นอย่างสม่ำเสมอ สิ่งที่คุณทำคือเลือกจุดสุ่มในรูปสามเหลี่ยมและกลับกระบวนการเพื่อให้ได้จุดในวงกลม


ด้วยเหตุผลบางอย่างนี้ทำให้ฉันมีการกระจายที่สม่ำเสมอมากกว่าคำตอบที่ยอมรับแม้ว่าฉันจะต้องแบ่งพิกัดด้วยรัศมีมิฉะนั้นมันจะอยู่ในวงกลมของ R ^ 2
Greg Zaal

3
ขอบคุณนี่คือรหัสของคุณใน Java อาจมีบางคนพบว่ามีประโยชน์: float random1 = MathUtils.random (); float random2 = MathUtils.random (); float randomXPoint = random2 * รัศมีMathUtils.cos (MathUtils.PI2 * random1 / random2); float randomYPoint = random2 * radius MathUtils.sin (MathUtils.PI2 * random1 / random2);
Tony Ceralva

ดีมาก! ฉันชอบความคิดของความน่าจะเป็นที่มากขึ้นสำหรับการรวมจุดเข้าด้วยกันดังนั้นถ้าเราไม่สลับเมื่อb < aเราสามารถทำสิ่งนี้ได้! เช่นใน javascript jsfiddle.net/b0sb5ogL/1
Guilherme

ฉันคิดว่าทางออกของคุณไม่ดี มันไม่ได้ให้ผลลัพธ์ที่สม่ำเสมอ ตรวจสอบภาพหน้าจอนี้prntscr.com/fizxgc
bolec_kolec

4
คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับวิธีตัดวงกลมและยืดมันออกได้อีกเล็กน้อยได้ไหม?
kec

21

สังเกตความหนาแน่นของจุดเป็นสัดส่วนกับจตุรัสผกผันของรัศมีดังนั้นแทนที่จะเลือกrจาก[0, r_max]เลือกจาก[0, r_max^2]นั้นคำนวณพิกัดของคุณเป็น:

x = sqrt(r) * cos(angle)
y = sqrt(r) * sin(angle)

สิ่งนี้จะทำให้คุณมีการกระจายจุดที่สม่ำเสมอบนดิสก์

http://mathworld.wolfram.com/DiskPointPicking.html


12

คิดแบบนี้ หากคุณมีสี่เหลี่ยมผืนผ้าโดยที่แกนหนึ่งมีรัศมีและหนึ่งเป็นมุมและคุณใช้จุดภายในสี่เหลี่ยมนี้ที่มีรัศมีใกล้ 0 ทั้งหมดนี้จะตกใกล้กับจุดกำเนิด (ซึ่งอยู่ติดกันบนวงกลม) อย่างไรก็ตาม จุดที่อยู่ใกล้กับรัศมี R สิ่งเหล่านี้จะตกใกล้ขอบของวงกลม (นั่นคือห่างกันมาก)

นี่อาจทำให้คุณเข้าใจว่าทำไมคุณถึงมีพฤติกรรมนี้

ปัจจัยที่มาจากลิงก์นั้นจะบอกคุณว่าต้องปรับพื้นที่ที่สอดคล้องในสี่เหลี่ยมเท่าไรให้ไม่ขึ้นอยู่กับรัศมีเมื่อแมปไปที่วงกลม

แก้ไข: ดังนั้นสิ่งที่เขาเขียนในลิงค์ที่คุณแชร์คือ "นั่นง่ายพอที่จะทำโดยการคำนวณค่าผกผันของการแจกแจงสะสมและเราได้ r:"

สถานที่ตั้งพื้นฐานอยู่ที่นี่ที่คุณสามารถสร้างตัวแปรที่มีการกระจายที่ต้องการจากชุดโดยการทำแผนที่ชุดโดยฟังก์ชันผกผันของฟังก์ชันการกระจายสะสมของฟังก์ชั่นความหนาแน่นของความน่าจะเป็นที่ต้องการ ทำไม? เพียงแค่รับมันตอนนี้ แต่นี่เป็นความจริง

นี่คือคำอธิบายง่ายๆของฉันเกี่ยวกับคณิตศาสตร์ ฟังก์ชันความหนาแน่น f (r) เทียบกับ r ต้องเป็นสัดส่วนกับ r เอง การเข้าใจความจริงข้อนี้เป็นส่วนหนึ่งของหนังสือแคลคูลัสเบื้องต้น ดูส่วนต่างๆในองค์ประกอบพื้นที่ขั้วโลก ผู้โพสต์คนอื่นพูดถึงเรื่องนี้

ดังนั้นเราจะเรียกมันว่า f (r) = C * r;

สิ่งนี้กลายเป็นงานส่วนใหญ่ ตอนนี้เนื่องจาก f (r) ควรเป็นความหนาแน่นของความน่าจะเป็นคุณสามารถเห็นได้อย่างง่ายดายโดยการรวม f (r) ในช่วงเวลา (0, R) คุณจะได้รับ C = 2 / R ^ 2 (นี่คือแบบฝึกหัดสำหรับผู้อ่าน .)

ดังนั้น f (r) = 2 * r / R ^ 2

ตกลงนั่นคือวิธีที่คุณจะได้สูตรในลิงค์

จากนั้นส่วนสุดท้ายจะมาจากตัวแปรสุ่มที่เหมือนกันใน (0,1) คุณต้องแมปด้วยฟังก์ชันผกผันของฟังก์ชันการแจกแจงสะสมจากความหนาแน่นที่ต้องการ f (r) เพื่อให้เข้าใจว่าทำไมในกรณีนี้คุณต้องค้นหาข้อความความน่าจะเป็นขั้นสูงอย่าง Papoulis ซึ่งอาจเป็นไปได้ (หรือรับด้วยตนเอง)

การรวม f (r) คุณจะได้รับ F (r) = r ^ 2 / R ^ 2

ในการค้นหาฟังก์ชันผกผันของสิ่งนี้คุณต้องตั้งค่า u = r ^ 2 / R ^ 2 แล้วแก้หา r ซึ่งให้ r = R * sqrt (u)

ทั้งหมดนี้ก็สมเหตุสมผลเช่นกัน u = 0 ควรแมปไปที่ r = 0 นอกจากนี้ u = 1 shoudl แผนที่ไปยัง r = R นอกจากนี้ยังไปตามฟังก์ชั่นรากที่สองซึ่งสมเหตุสมผลและจับคู่กับลิงก์


10

เหตุผลที่การแก้ปัญหาแบบไร้เดียงสาไม่ทำงานก็เพราะมันให้ความหนาแน่นของความน่าจะเป็นที่สูงขึ้นไปยังจุดที่อยู่ใกล้กับศูนย์กลางของวงกลม กล่าวอีกนัยหนึ่งวงกลมที่มีรัศมี r / 2 มีความน่าจะเป็น r / 2 ของการเลือกจุดในวงกลม แต่มีพื้นที่ (จำนวนคะแนน) pi * r ^ 2/4

ดังนั้นเราจึงต้องการความหนาแน่นของความน่าจะเป็นรัศมีที่มีคุณสมบัติดังต่อไปนี้:

ความน่าจะเป็นของการเลือกรัศมีที่เล็กกว่าหรือเท่ากับ r ที่กำหนดต้องเป็นสัดส่วนกับพื้นที่ของวงกลมที่มีรัศมี r (เพราะเราต้องการให้มีการกระจายอย่างสม่ำเสมอในจุดและพื้นที่ขนาดใหญ่หมายถึงจุดมากขึ้น)

กล่าวอีกนัยหนึ่งเราต้องการความน่าจะเป็นในการเลือกรัศมีระหว่าง [0, r] เท่ากับส่วนแบ่งของพื้นที่โดยรวมของวงกลม พื้นที่วงกลมทั้งหมดคือ pi * R ^ 2 และพื้นที่ของวงกลมที่มีรัศมี r คือ pi * r ^ 2 ดังนั้นเราต้องการความน่าจะเป็นในการเลือกรัศมีระหว่าง [0, r] เป็น (pi * r ^ 2) / (pi * R ^ 2) = r ^ 2 / R ^ 2

คณิตศาสตร์มาแล้ว:

ความน่าจะเป็นของการเลือกรัศมีระหว่าง [0, r] คืออินทิกรัลของ p (r) dr จาก 0 ถึง r (นั่นเป็นเพียงเพราะเราเพิ่มความน่าจะเป็นทั้งหมดของรัศมีที่เล็กลง) ดังนั้นเราต้องการอินทิกรัล (p (r) dr) = r ^ 2 / R ^ 2 เราสามารถเห็นได้อย่างชัดเจนว่า R ^ 2 เป็นค่าคงที่ดังนั้นสิ่งที่เราต้องทำคือหาว่า p (r) เมื่อรวมเข้าด้วยกันจะทำให้เรามีลักษณะคล้าย r ^ 2 คำตอบนั้นชัดเจน r * คงที่ อินทิกรัล (r * ค่าคงที่ dr) = ค่าคงที่ r ^ 2/2 * สิ่งนี้จะต้องเท่ากับ r ^ 2 / R ^ 2 ดังนั้นคงที่ = 2 / R ^ 2 ดังนั้นคุณมีการแจกแจงความน่าจะเป็น p (r) = r * 2 / R ^ 2

หมายเหตุ:อีกวิธีที่ใช้งานง่ายกว่าที่คิดเกี่ยวกับปัญหาคือการจินตนาการว่าคุณพยายามให้รัศมีความหนาแน่นของความเป็นไปได้แต่ละรัศมีเท่ากับสัดส่วนของจำนวนคะแนนที่มีในเส้นรอบวง ดังนั้นวงกลมที่มีรัศมี r จะมี 2 * pi * r "คะแนน" ที่เส้นรอบวงของมัน จำนวนคะแนนทั้งหมดคือ pi * R ^ 2 ดังนั้นคุณควรให้ความน่าจะเป็นวงกลม ra เท่ากับ (2 * pi * r) / (pi * R ^ 2) = 2 * r / R ^ 2 นี่ง่ายกว่าที่จะเข้าใจและเข้าใจง่ายกว่า แต่ก็ไม่ได้เป็นเสียงทางคณิตศาสตร์


9

ให้ρ (รัศมี) และφ (azimuth) เป็นสองตัวแปรสุ่มที่สอดคล้องกับพิกัดเชิงขั้วของจุดโดยพลการภายในวงกลม หากคะแนนกระจายอย่างสม่ำเสมอฟังก์ชันการแจกแจงของρและφคืออะไร?

สำหรับ r: 0 <r <R ความน่าจะเป็นของพิกัดรัศมีρนั้นน้อยกว่า r คือ

P [ρ <r] = P [จุดอยู่ภายในวงกลมรัศมี r] = S1 / S0 = (r / R) 2

โดยที่ S1 และ S0 เป็นพื้นที่ของวงกลมรัศมี r และ R ตามลำดับ ดังนั้น CDF สามารถได้รับเป็น:

          0          if r<=0
  CDF =   (r/R)**2   if 0 < r <= R
          1          if r > R

และ PDF:

PDF = d/dr(CDF) = 2 * (r/R**2) (0 < r <= R).

โปรดทราบว่าสำหรับ R = 1 ตัวแปรสุ่ม sqrt (X) โดยที่ X เป็นชุดที่ [0, 1) มี CDF ที่แน่นอนนี้ (เนื่องจาก P [sqrt (X) <y] = P [x <y ** 2] = y * * 2 สำหรับ 0 <y <= 1)

การแจกแจงของφมีความสม่ำเสมอตั้งแต่ 0 ถึง 2 * π ตอนนี้คุณสามารถสร้างพิกัดเชิงขั้วสุ่มและแปลงเป็นคาร์ทีเซียนโดยใช้สมการตรีโกณมิติ:

x = ρ * cos(φ)
y = ρ * sin(φ)

ไม่สามารถต้านทานการโพสต์โค้ดไพ ธ อนสำหรับ R = 1

from matplotlib import pyplot as plt
import numpy as np

rho = np.sqrt(np.random.uniform(0, 1, 5000))
phi = np.random.uniform(0, 2*np.pi, 5000)

x = rho * np.cos(phi)
y = rho * np.sin(phi)

plt.scatter(x, y, s = 4)

คุณจะได้รับ

ป้อนคำอธิบายรูปภาพที่นี่


7

มันขึ้นอยู่กับสิ่งที่คุณหมายถึงโดย 'สุ่มอย่างสม่ำเสมอ' นี่เป็นจุดที่ลึกซึ้งและคุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในหน้าวิกิที่นี่: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29ซึ่งปัญหาเดียวกันทำให้การตีความที่แตกต่างกันของ 'การสุ่มแบบสุ่ม' ให้ คำตอบที่แตกต่างกัน!

ขึ้นอยู่กับวิธีที่คุณเลือกคะแนนการกระจายอาจแตกต่างกันแม้ว่าพวกเขาจะสุ่มอย่างสม่ำเสมอในบางแง่มุม

ดูเหมือนว่ารายการบล็อกพยายามที่จะทำให้มันสุ่มอย่างสม่ำเสมอในแง่ต่อไปนี้: ถ้าคุณใช้วงกลมย่อยของวงกลมด้วยศูนย์กลางเดียวกันความน่าจะเป็นที่จุดตกอยู่ในพื้นที่นั้นจะเป็นสัดส่วนกับพื้นที่ของ ศาสนา. ฉันเชื่อว่ากำลังพยายามที่จะทำตามการตีความมาตรฐานตอนนี้ของ 'การสุ่มแบบสม่ำเสมอ' สำหรับภูมิภาค 2D ที่มีพื้นที่ที่กำหนดไว้ : ความน่าจะเป็นของจุดที่ตกลงในภูมิภาคใด ๆ


5
หรือมากกว่าน่าจะเป็นที่จุดตกอยู่ในความใด ๆในภูมิภาคโดยพลการเป็นสัดส่วนกับพื้นที่ของภูมิภาค - สมมติว่าภูมิภาคนี้มีพื้นที่
ShreevatsaR

@Shree: ถูกต้องซึ่งเป็นสิ่งที่ฉันตั้งใจจะสื่อถึงคำพูดของฉันในวงเล็บ ฉันจะทำให้ชัดเจนยิ่งขึ้นขอบคุณ btw เกี่ยวกับบล็อกไม่มีข้อพิสูจน์ที่แท้จริงว่าพื้นที่ตามอำเภอใจให้ความน่าจะเป็นสัดส่วนดังนั้นฉันเลือกที่จะพูดอย่างนั้น

6

นี่คือรหัส Python ของฉันเพื่อสร้างnumจุดสุ่มจากวงกลมรัศมีrad:

import matplotlib.pyplot as plt
import numpy as np
rad = 10
num = 1000

t = np.random.uniform(0.0, 2.0*np.pi, num)
r = rad * np.sqrt(np.random.uniform(0.0, 1.0, num))
x = r * np.cos(t)
y = r * np.sin(t)

plt.plot(x, y, "ro", ms=1)
plt.axis([-15, 15, -15, 15])
plt.show()

1
ทำไมไม่เพียงr = np.sqrt(np.random.uniform(0.0, rad**2, num))?

4

ผมคิดว่าในกรณีนี้ใช้พิกัดขั้วโลกเป็นวิธีการที่ซับซ้อนปัญหาก็จะง่ายขึ้นมากหากคุณเลือกจุดสุ่มเป็นตารางที่มีความยาวด้านของ 2R แล้วเลือกจุดดังกล่าวว่า(x,y)x^2+y^2<=R^2


คุณหมายถึง x ^ 2 + y ^ 2 <= R ^ 2 ฉันคิดว่า
sigfpe

1
นี่คือการสุ่มตัวอย่างการปฏิเสธ ไม่เป็นไร แต่หมายความว่าเวลาคำนวณแตกต่างกันบ้างซึ่งอาจเป็นปัญหา
Steve Bennett

สี่เหลี่ยมทั้งหมดมี 4 ด้าน
xaxxon

อัลกอริทึมนี้มีประสิทธิภาพมากกว่าที่ทุกอย่างที่เกี่ยวข้องกับการคำนวณรากที่สองหรือการคำนวณบาป มันปฏิเสธน้อยกว่า 21.5% ของตาราง
Ivan Kovtun

3

โซลูชันใน Java และตัวอย่างการแจกจ่าย (2,000 คะแนน)

public void getRandomPointInCircle() {
    double t = 2 * Math.PI * Math.random();
    double r = Math.sqrt(Math.random());
    double x = r * Math.cos(t);
    double y = r * Math.sin(t);
    System.out.println(x);
    System.out.println(y);
}

การกระจาย 2,000 คะแนน

อ้างอิงจากโซลูชัน previus https://stackoverflow.com/a/5838055/5224246จาก @sigfpe


2

ก่อนอื่นเราสร้าง cdf [x] ซึ่งก็คือ

ความน่าจะเป็นที่จุดหนึ่งนั้นน้อยกว่าระยะทาง x จากจุดศูนย์กลางของวงกลม สมมติว่าวงกลมมีรัศมีของ R

เห็นได้ชัดว่าถ้า x เป็นศูนย์ดังนั้น cdf [0] = 0

เห็นได้ชัดว่าถ้า x คือ R ดังนั้น cdf [R] = 1

เห็นได้ชัดว่าถ้า x = r ดังนั้น cdf [r] = (Pi r ^ 2) / (Pi R ^ 2)

นี่เป็นเพราะ "พื้นที่เล็ก ๆ " ในวงกลมมีความน่าจะเป็นเหมือนกันในการเลือกดังนั้นความน่าจะเป็นจะเป็นสัดส่วนกับพื้นที่ที่เป็นปัญหา และพื้นที่ที่กำหนดระยะทาง x จากจุดศูนย์กลางของวงกลมคือ Pi r ^ 2

ดังนั้น cdf [x] = x ^ 2 / R ^ 2 เพราะ Pi ยกเลิกซึ่งกันและกัน

เรามี cdf [x] = x ^ 2 / R ^ 2 โดยที่ x ไปจาก 0 ถึง R

เราจึงแก้หา x

R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]

ตอนนี้เราสามารถแทนที่ cdf ด้วยตัวเลขสุ่มจาก 0 ถึง 1

x = R Sqrt[ RandomReal[{0,1}] ]

ในที่สุด

r = R Sqrt[  RandomReal[{0,1}] ];
theta = 360 deg * RandomReal[{0,1}];
{r,theta}

เราได้พิกัดเชิงขั้ว {0.601168 R, 311.915 องศา}


1

มีความสัมพันธ์เชิงเส้นตรงระหว่างรัศมีและจำนวนจุดที่ "ใกล้" รัศมีว่าเป็นเขาจึงจำเป็นต้องใช้การกระจายรัศมีที่ยังทำให้จำนวนของจุดข้อมูลที่อยู่ใกล้รัศมีสัดส่วนกับrr


1

ฉันใช้วิธีนี้ครั้งเดียว: วิธีนี้อาจไม่ได้เพิ่มประสิทธิภาพทั้งหมด (เช่นใช้อาร์เรย์ของจุดเพื่อใช้ไม่ได้กับวงกลมใหญ่) แต่ให้การกระจายแบบสุ่มเพียงพอ คุณสามารถข้ามการสร้างเมทริกซ์และวาดโดยตรงหากคุณต้องการ วิธีการคือการสุ่มทุกจุดในสี่เหลี่ยมที่อยู่ภายในวงกลม

bool[,] getMatrix(System.Drawing.Rectangle r) {
    bool[,] matrix = new bool[r.Width, r.Height];
    return matrix;
}

void fillMatrix(ref bool[,] matrix, Vector center) {
    double radius = center.X;
    Random r = new Random();
    for (int y = 0; y < matrix.GetLength(0); y++) {
        for (int x = 0; x < matrix.GetLength(1); x++)
        {
            double distance = (center - new Vector(x, y)).Length;
            if (distance < radius) {
                matrix[x, y] = r.NextDouble() > 0.5;
            }
        }
    }

}

private void drawMatrix(Vector centerPoint, double radius, bool[,] matrix) {
    var g = this.CreateGraphics();

    Bitmap pixel = new Bitmap(1,1);
    pixel.SetPixel(0, 0, Color.Black);

    for (int y = 0; y < matrix.GetLength(0); y++)
    {
        for (int x = 0; x < matrix.GetLength(1); x++)
        {
            if (matrix[x, y]) {
                g.DrawImage(pixel, new PointF((float)(centerPoint.X - radius + x), (float)(centerPoint.Y - radius + y)));
            }
        }
    }

    g.Dispose();
}

private void button1_Click(object sender, EventArgs e)
{
    System.Drawing.Rectangle r = new System.Drawing.Rectangle(100,100,200,200);
    double radius = r.Width / 2;
    Vector center = new Vector(r.Left + radius, r.Top + radius);
    Vector normalizedCenter = new Vector(radius, radius);
    bool[,] matrix = getMatrix(r);
    fillMatrix(ref matrix, normalizedCenter);
    drawMatrix(center, radius, matrix);
}

ป้อนคำอธิบายรูปภาพที่นี่


3
การแจกแจงจะไม่ "สุ่มเพียงพอ" พวกเขาเป็นแบบสุ่มหรือไม่สำหรับคำจำกัดความที่กำหนดแบบสุ่ม คำตอบของคุณคือเอียง: คุณไม่ได้แสดงความคิดเห็นรหัสของคุณหรืออธิบายวิธีที่คุณมาถึงมัน คำตอบเอียงยากที่จะติดตามและยากที่จะเชื่อใจ
Richard

1

องค์ประกอบพื้นที่ในวงกลมคือ dA = rdr * dphi ปัจจัยพิเศษนั้นทำลายความคิดของคุณในการเลือก ar และพีแบบสุ่ม ขณะที่ phi กระจายแบบแบน r ไม่เป็น แต่เป็นแบบ 1 / r (เช่นคุณมีแนวโน้มที่จะชนกับขอบเขตมากกว่า "ดวงตาของวัว")

ดังนั้นในการสร้างจุดกระจายอย่างเท่าเทียมกันทั่ววงกลมเลือกพีจากการกระจายแบนและ r จากการกระจาย 1 / r

หรือใช้วิธีการ Monte Carlo ที่เสนอโดย Mehrdad

แก้ไข

ในการเลือกสุ่ม r แบนใน 1 / r คุณสามารถเลือกสุ่ม x จากช่วง [1 / R, อนันต์] และคำนวณ r = 1 / x r ถูกกระจายแล้วแบนใน 1 / r

ในการคำนวณ phi สุ่มเลือกสุ่ม x จากช่วงเวลา [0, 1] และคำนวณ phi = 2 * pi * x


ฉันจะเลือกrจาก"การกระจาย 1 / r" ได้อย่างไร?
aioobe

0

ฉันไม่รู้ว่าคำถามนี้ยังคงเปิดอยู่เพื่อหาทางออกใหม่พร้อมคำตอบทั้งหมดที่ได้รับไปแล้ว แต่ฉันก็ต้องเจอกับคำถามเดียวกันทั้งหมดด้วยตัวเอง ฉันพยายาม "หาเหตุผล" กับตัวเองเพื่อหาทางออกและฉันพบ มันอาจเป็นสิ่งเดียวกับที่บางคนแนะนำไว้แล้ว แต่นี่คือ:

เพื่อให้องค์ประกอบสองอย่างของพื้นผิววงกลมเท่ากันสมมติว่ามี dr เท่ากันเราต้องมี dtheta1 / dtheta2 = r2 / r1 การเขียนความน่าจะเป็นขององค์ประกอบนั้นเป็น P (r, theta) = P {r1 <r <r1 + dr, theta1 <theta <theta + dtheta1} = f (r, theta) * dr * dtheta1 และการตั้งค่าทั้งสอง ความน่าจะเป็น (สำหรับ r1 และ r2) เท่ากันเรามาถึง (สมมติว่า r และ theta เป็นอิสระ) f (r1) / r1 = f (r2) / r2 = ค่าคงที่ซึ่งให้ f (r) = c * r และส่วนที่เหลือกำหนดค่าคงที่ c ดังนี้จากเงื่อนไขใน f (r) เป็น PDF


วิธีการเริ่มต้นที่น่าสนใจด้วย dtheta1 / dtheta2 = r2 / r1 คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับวิธีการที่คุณใช้กับสมการนั้นได้หรือไม่?
aioobe

ดังที่คนอื่น ๆ ได้กล่าวถึง (เช่นhonk ) องค์ประกอบที่แตกต่างของพื้นผิวของวงกลมจะได้รับเป็น r dr dtheta ดังนั้นหากเราถือว่า r1 = r2 ดังนั้นเราจะมี dr1 * dtheta1 = dr2 * dtheta2 และส่วนที่เหลือตามมา .
arsaKasra

0

ทางออกโปรแกรมเมอร์:

  • สร้างบิตแมป (เมทริกซ์ของค่าบูลีน) มันอาจมีขนาดใหญ่เท่าที่คุณต้องการ
  • วาดวงกลมในแผนที่บิตนั้น
  • สร้างตารางการค้นหาของคะแนนของวงกลม
  • เลือกดัชนีแบบสุ่มในตารางการค้นหานี้
const int RADIUS = 64;
const int MATRIX_SIZE = RADIUS * 2;

bool matrix[MATRIX_SIZE][MATRIX_SIZE] = {0};

struct Point { int x; int y; };

Point lookupTable[MATRIX_SIZE * MATRIX_SIZE];

void init()
{
  int numberOfOnBits = 0;

  for (int x = 0 ; x < MATRIX_SIZE ; ++x)
  {
    for (int y = 0 ; y < MATRIX_SIZE ; ++y)
    {
      if (x * x + y * y < RADIUS * RADIUS) 
      {
        matrix[x][y] = true;

        loopUpTable[numberOfOnBits].x = x;
        loopUpTable[numberOfOnBits].y = y;

        ++numberOfOnBits;

      } // if
    } // for
  } // for
} // ()

Point choose()
{
  int randomIndex = randomInt(numberOfBits);

  return loopUpTable[randomIndex];
} // ()

บิตแมปจำเป็นสำหรับคำอธิบายของตรรกะเท่านั้น นี่คือรหัสที่ไม่มีบิตแมป:

const int RADIUS = 64;
const int MATRIX_SIZE = RADIUS * 2;

struct Point { int x; int y; };

Point lookupTable[MATRIX_SIZE * MATRIX_SIZE];

void init()
{
  int numberOfOnBits = 0;

  for (int x = 0 ; x < MATRIX_SIZE ; ++x)
  {
    for (int y = 0 ; y < MATRIX_SIZE ; ++y)
    {
      if (x * x + y * y < RADIUS * RADIUS) 
      {
        loopUpTable[numberOfOnBits].x = x;
        loopUpTable[numberOfOnBits].y = y;

        ++numberOfOnBits;
      } // if
    } // for
  } // for
} // ()

Point choose()
{
  int randomIndex = randomInt(numberOfBits);

  return loopUpTable[randomIndex];
} // ()

0

ฉันยังไม่แน่ใจเกี่ยวกับ '(2 / R2) × r' ที่แน่นอน แต่สิ่งที่เห็นได้ชัดคือจำนวนคะแนนที่ต้องใช้ในการกระจายของหน่วยที่กำหนด 'dr' เช่นการเพิ่มขึ้นของ r จะเป็นสัดส่วนกับ r2 และไม่ใช่ r

ตรวจสอบวิธีนี้ ... จำนวนคะแนนที่บางมุมทีต้าและระหว่าง r (0.1r ถึง 0.2r) นั่นคือเศษส่วนของ r และจำนวนคะแนนระหว่าง r (0.6r ถึง 0.7r) จะเท่ากันถ้าคุณใช้รุ่นมาตรฐาน เนื่องจากความแตกต่างเป็นเพียง 0.1r ระหว่างสองช่วงเวลา แต่เนื่องจากพื้นที่ที่ครอบคลุมระหว่างคะแนน (0.6r ถึง 0.7r) จะมีขนาดใหญ่กว่าพื้นที่ที่ครอบคลุมระหว่าง 0.1r ถึง 0.2r จำนวนคะแนนที่เท่ากันจะเว้นระยะห่างในพื้นที่ขนาดใหญ่ฉันคิดว่าคุณรู้แล้วดังนั้นฟังก์ชัน ในการสร้างจุดสุ่มจะต้องไม่เชิงเส้น แต่เป็นกำลังสอง (เนื่องจากจำนวนจุดที่ต้องกระจายในหน่วยที่กำหนด 'dr' คือการเพิ่มใน r จะเป็นสัดส่วนกับ r2 และไม่ใช่ r) ดังนั้นในกรณีนี้มันจะตรงกันข้ามกับ กำลังสองเนื่องจากเดลต้าเรามี (0


คุณเป็นคนแรกในการอ้างอิงทฤษฎีบทพีทาโกรัสที่นี่ ฉันจะรักถ้าคุณสามารถขยายนี้ด้วยตัวเลขหรือสองสนับสนุนคำอธิบายของคุณ ฉันมีช่วงเวลาที่ยากลำบากดังต่อไปนี้ :-(
aioobe

@aioobe ฉันพยายามที่จะใช้คำตอบใหม่ฉันสามารถเพิ่มไดอะแกรมหากคุณต้องการ :)
cheesefest

ฉันเข้าใจว่าทำไมฉันไม่สามารถกระจายมันเป็นเส้นตรง สิ่งที่ฉันไม่เข้าใจที่นี่คือการเชื่อมต่อกับพีธากอรัสหรือบาป / คอส ไดอะแกรมอาจช่วยฉันได้ที่นี่
aioobe

Pythagoras เป็นความผิดพลาดของฉันโปรดลืมเกี่ยวกับมัน แต่หวังว่าคุณจะเข้าใจธรรมชาติของสมการกำลังสองฟังก์ชันที่แน่นอน (2 / R2) × r ต้องมีการพิสูจน์และฉันไม่สามารถหาข้อพิสูจน์สำหรับเรื่องนี้ได้
cheesefest

0

ช่างเป็นปัญหาที่สนุก
เหตุผลของความน่าจะเป็นของจุดที่ถูกเลือกลดลงเนื่องจากระยะทางจากจุดกำเนิดของแกนเพิ่มขึ้นมีการอธิบายหลายครั้งข้างต้น เราคำนึงถึงสิ่งนั้นด้วยการหยั่งรากของ U [0,1] นี่คือวิธีแก้ปัญหาทั่วไปสำหรับค่าบวกใน Python 3

import numpy
import math
import matplotlib.pyplot as plt

def sq_point_in_circle(r):
    """
    Generate a random point in an r radius circle 
    centered around the start of the axis
    """

    t = 2*math.pi*numpy.random.uniform()
    R = (numpy.random.uniform(0,1) ** 0.5) * r

    return(R*math.cos(t), R*math.sin(t))

R = 200 # Radius
N = 1000 # Samples

points = numpy.array([sq_point_in_circle(R) for i in range(N)])
plt.scatter(points[:, 0], points[:,1])

ป้อนคำอธิบายรูปภาพที่นี่


0

คุณยังสามารถใช้สัญชาตญาณของคุณ

พื้นที่ของวงกลมคือ pi*r^2

สำหรับ r=1

piนี้ทำให้เรามีพื้นที่ ขอให้เราสมมติว่าเรามีฟังก์ชั่นบางอย่างfที่จะกระจายN=10จุดภายในวงกลมอย่างสม่ำเสมอ อัตราส่วนนี่คือ10 / pi

ตอนนี้เราเพิ่มพื้นที่และจำนวนจุดเป็นสองเท่า

สำหรับr=2และN=20

นี้จะช่วยให้พื้นที่4piและอัตราการใช้อยู่ในขณะนี้หรือ20/4pi 10/2piอัตราส่วนจะเล็กลงNเรื่อย ๆรัศมีที่ใหญ่กว่าก็คือเนื่องจากการเติบโตของมันนั้นเป็นกำลังสองและเครื่องชั่งเชิงเส้น

ในการแก้ไขปัญหานี้เราสามารถพูดได้

x = r^2
sqrt(x) = r

หากคุณต้องการสร้างเวกเตอร์ในพิกัดเชิงขั้วเช่นนี้

length = random_0_1();
angle = random_0_2pi();

คะแนนเพิ่มเติมจะลงจอดรอบจุดศูนย์กลาง

length = sqrt(random_0_1());
angle = random_0_2pi();

length ไม่ได้กระจายอย่างสม่ำเสมออีกต่อไป แต่เวกเตอร์จะถูกกระจายอย่างสม่ำเสมอ


-1

1) เลือก X สุ่มระหว่าง -1 ถึง 1

var X:Number = Math.random() * 2 - 1;

2) ใช้สูตรวงกลมคำนวณค่าสูงสุดและต่ำสุดของ Y เนื่องจาก X และรัศมีเป็น 1:

var YMin:Number = -Math.sqrt(1 - X * X);
var YMax:Number = Math.sqrt(1 - X * X);

3) เลือก Y แบบสุ่มระหว่างสุดขั้วเหล่านี้:

var Y:Number = Math.random() * (YMax - YMin) + YMin;

4) รวมค่าที่ตั้งและรัศมีของคุณในค่าสุดท้าย:

var finalX:Number = X * radius + pos.x;
var finalY:Number = Y * radois + pos.y;

2
ไม่เหมือนกัน - ความน่าจะเป็นสำหรับ [-1, 0] นั้นสูงกว่า [0, 0] มากเนื่องจาก p ([- 1, Y]) = p ([0, Y]) และมีเพียงหนึ่งเดียว ตัวเลือกสำหรับ [-1, Y] และตัวเลือกมากมายสำหรับ [0, Y]
Amadan

วิธีการแก้ปัญหานี้ช่วยชี้ไปทางด้านซ้ายและด้านขวาของวงกลม คะแนนที่ใกล้ x ถึงศูนย์จะแสดงไม่ถึง ไม่มีการกระจายเครื่องแบบเลย
Dawood ibn Kareem
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.