Tạo một điểm ngẫu nhiên trong một vòng tròn (thống nhất)


212

Tôi cần phải tạo ra một điểm thống nhất ngẫu nhiên trong một vòng tròn bán kính R .

Tôi nhận ra rằng chỉ cần chọn một góc ngẫu nhiên đồng đều trong khoảng [0 ... 2π) và bán kính ngẫu nhiên đồng đều trong khoảng (0 ... R ) tôi sẽ kết thúc với nhiều điểm hơn về phía trung tâm, vì hai điểm đã cho bán kính, các điểm trong bán kính nhỏ hơn sẽ gần nhau hơn so với các điểm trong bán kính lớn hơn.

Tôi tìm thấy một mục blog về điều này ở đây nhưng tôi không hiểu lý do của anh ấy. Tôi cho rằng nó đúng, nhưng tôi thực sự muốn hiểu từ nơi anh ta nhận được (2 / R 2 ) × r và cách anh ta đưa ra giải pháp cuối cùng.


Cập nhật: 7 năm sau khi đăng câu hỏi này tôi vẫn chưa nhận được câu trả lời thỏa đáng cho câu hỏi thực tế liên quan đến toán học đằng sau thuật toán căn bậc hai. Vì vậy, tôi đã dành một ngày để viết một câu trả lời cho mình. Liên kết với câu trả lời của tôi .


18
Là nhược điểm của lấy mẫu từ chối thực sự là một vấn đề lớn? Số lần thử dự kiến ​​là 4 / π 1,27 và xác suất bạn cần nhiều hơn k lần thử là (1-π / 4) ^ k. Với k = 20 , đây là ≈ .00000000000004 và với k = 50, nó theo thứ tự 10 ^ {- 34}. Bạn có thể lấy những tỷ lệ cược đó bất cứ ngày nào; Bạn sẽ làm tốt.
ShreevatsaR

3
Trên thực tế, lấy mẫu từ chối không đảm bảo cho việc chấm dứt. Tỷ lệ cược là vô cùng thấp (chính xác là bằng không) mà thuật toán của bạn sẽ không bao giờ chấm dứt.
Jared Nielsen

2
Theo tôi, tầm quan trọng của nhược điểm của lấy mẫu từ chối tỷ lệ thuận với việc dễ dàng sử dụng phương pháp lấy mẫu để tránh sự từ chối. Trong trường hợp này, nhược điểm rất quan trọng vì việc lấy mẫu mà không từ chối là đơn giản.
spex

4
@spex Trong thực tế, kỹ thuật loại bỏ nhanh hơn vì nó tránh được sự cần thiết phải đánh giá chức năng siêu việt.
pjs

2
(tiếp) từ chối: 0,52s Tất cả đã cho các phương tiện và độ lệch chuẩn giống hệt nhau (đến 3 sig. fig). Như mong đợi, việc lấy mẫu từ chối thất bại 27% thời gian (4 / pi-1) vì vậy cần số lượng ngẫu nhiên nhiều hơn 27% so với btilly nhưng ít hơn 15% so với sigfpe. Điều này xác nhận các ý kiến ​​được đưa ra bởi pjs và những người khác rằng lấy mẫu từ chối có lẽ là cách tiếp cận tốt nhất, trừ khi các randoms rất tốn kém để tạo ra.
Peter Davidson

Câu trả lời:


189

Hãy tiếp cận điều này giống như Archimedes sẽ có.

Làm thế nào chúng ta có thể tạo một điểm đồng đều trong một tam giác ABC, trong đó | AB | = | BC |? Chúng ta hãy làm điều này dễ dàng hơn bằng cách mở rộng sang hình bình hành ABCD. Thật dễ dàng để tạo các điểm đồng đều trong ABCD. Chúng tôi thống nhất chọn một điểm X ngẫu nhiên trên AB và Y trên BC và chọn Z sao cho XBYZ là hình bình hành. Để có được một điểm được chọn đồng đều trong tam giác ban đầu, chúng ta chỉ cần gấp bất kỳ điểm nào xuất hiện trong ADC trở lại ABC dọc theo AC.

Bây giờ hãy xem xét một vòng tròn. Trong giới hạn, chúng ta có thể nghĩ về nó là vô số các tam giác isocele ABC với B ở gốc và A và C trên chu vi gần nhau. Chúng ta có thể chọn một trong những hình tam giác này bằng cách chọn một góc theta. Vì vậy, bây giờ chúng ta cần tạo một khoảng cách từ trung tâm bằng cách chọn một điểm trong cúi ABC. Một lần nữa, mở rộng đến ABCD, trong đó D bây giờ gấp đôi bán kính từ tâm vòng tròn.

Chọn một điểm ngẫu nhiên trong ABCD rất dễ dàng bằng phương pháp trên. Chọn một điểm ngẫu nhiên trên AB. Thống nhất chọn một điểm ngẫu nhiên trên BC. I E. chọn một cặp số ngẫu nhiên x và y đồng nhất trên [0, R] cho khoảng cách từ tâm. Tam giác của chúng ta là một mảnh mỏng nên AB và BC về cơ bản là song song. Vì vậy, điểm Z chỉ đơn giản là một khoảng cách x + y từ gốc. Nếu x + y> R chúng ta gập xuống.

Đây là thuật toán hoàn chỉnh cho R = 1. Tôi hy vọng bạn đồng ý nó khá đơn giản. Nó sử dụng trig, nhưng bạn có thể đảm bảo thời gian thực hiện và bao nhiêu random()cuộc gọi cần, không giống như lấy mẫu từ chối.

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

Đây là trong Mathicala.

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]

nhập mô tả hình ảnh ở đây


6
@Karelzarath Tôi thích khái niệm phản trực giác về một tam giác mỏng vô hạn vẫn còn rộng hơn ở một đầu so với đầu kia :-) Nó nhận được câu trả lời đúng.
sigfpe

2
@hammar Không chắc nó khái quát tốt cho n chiều. Nhưng để 3d bạn có thể sử dụng một kết quả khác của Archimedes! Sử dụng định lý "hat-box" để tạo một điểm trên hình trụ (dễ dàng!) Và sau đó ánh xạ nó trở lại hình cầu. Điều đó đưa ra một hướng. Bây giờ sử dụng random()+random()+random()với một số nếp gấp phức tạp hơn (ví dụ: nếp gấp 6 chiều của một đường song song mỏng vô hạn đến một khối terahedron). Không tin rằng đây là một phương pháp tốt.
sigfpe

2
Tôi đã nghĩ 1 phút để tìm ra sự khác biệt giữa ngẫu nhiên () + ngẫu nhiên () và 2 * ngẫu nhiên () ... Tôi thật ngu ngốc: /
JiminP

3
@Tharwen Lưu ý làm thế nào trong một vòng tròn có nhiều điểm hơn ở bán kính 0,9-1 so với bán kính 0,0-0,1. Random () + Random () tạo ra bán kính nhiều khả năng ở khoảng 1.0 nhưng nằm trong phạm vi 0,0-2. Khi gập xuống, nhiều khả năng chúng sẽ ở khoảng 1.0 và luôn nằm trong khoảng 0,0-1. Hơn nữa, đó chính xác là tỷ lệ cần thiết trong câu đầu tiên của bình luận này. Chỉ cần giảm một nửa sẽ tạo ra nhiều số hơn xung quanh mốc 0,5 và điều đó sẽ sai.
sigfpe

2
@Tharwen Hãy thử sử dụng cả hai sơ đồ để tạo số ngẫu nhiên và xem những gì bạn nhận được. 2 * Random () cung cấp cho các số được phân phối đồng đều trong phạm vi 0 đến 2. Random () + Random () cung cấp cho bạn các số trong phạm vi 0 đến 2 nhưng sẽ (thường) sẽ có nhiều số gần 1.0 hơn gần 0.0 hoặc 2.0. Nó giống như cách cán hai con xúc xắc và tính tổng có nhiều khả năng cho 7 hơn bất kỳ con số nào khác.
sigfpe

133

Cách tạo một điểm ngẫu nhiên trong vòng tròn bán kính R :

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

(Giả sử random()cho giá trị từ 0 đến 1 đồng nhất)

Nếu bạn muốn chuyển đổi điều này sang tọa độ Descartes, bạn có thể làm

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


Tại sao sqrt(random())?

Chúng ta hãy nhìn vào toán học dẫn đến sqrt(random()). Giả sử vì đơn giản chúng ta đang làm việc với vòng tròn đơn vị, tức là R = 1.

Khoảng cách trung bình giữa các điểm phải giống nhau bất kể chúng ta nhìn từ trung tâm bao xa. Điều này có nghĩa là, ví dụ, nhìn vào chu vi của một vòng tròn có chu vi 2, chúng ta sẽ tìm thấy số điểm gấp đôi số điểm trên chu vi của một vòng tròn có chu vi 1.


                

Do chu vi của một vòng tròn (2π r ) tăng tuyến tính với r , nên theo đó số lượng điểm ngẫu nhiên sẽ tăng tuyến tính với r . Nói cách khác, hàm mật độ xác suất mong muốn (PDF) tăng trưởng tuyến tính. Vì một tệp PDF nên có diện tích bằng 1 và bán kính tối đa là 1, chúng tôi có


                

Vì vậy, chúng ta biết mật độ mong muốn của các giá trị ngẫu nhiên của chúng ta sẽ trông như thế nào. Bây giờ: Làm thế nào để chúng ta tạo ra một giá trị ngẫu nhiên như vậy khi tất cả những gì chúng ta có là một giá trị ngẫu nhiên thống nhất trong khoảng từ 0 đến 1?

Chúng tôi sử dụng một mẹo gọi là lấy mẫu biến đổi nghịch đảo

  1. Từ PDF, tạo chức năng phân phối tích lũy (CDF)
  2. Phản chiếu cái này dọc theo y = x
  3. Áp dụng hàm kết quả cho giá trị đồng nhất trong khoảng từ 0 đến 1.

Nghe có vẻ phức tạp? Hãy để tôi chèn một blockquote với một bản nhạc phụ nhỏ truyền tải trực giác:

Giả sử chúng ta muốn tạo một điểm ngẫu nhiên với phân phối sau:

                

Đó là

  • 1/5 số điểm thống nhất giữa 1 và 2, và
  • 4/5 điểm thống nhất giữa 2 và 3.

CDF, như tên cho thấy, phiên bản tích lũy của PDF. Theo trực giác: Trong khi PDF ( x ) mô tả số lượng giá trị ngẫu nhiên tại x , CDF ( x ) mô tả số lượng giá trị ngẫu nhiên nhỏ hơn x .

Trong trường hợp này, CDF sẽ trông như sau:

                

Để xem điều này hữu ích như thế nào, hãy tưởng tượng rằng chúng ta bắn đạn từ trái sang phải ở độ cao phân bố đồng đều. Khi những viên đạn bắn trúng đường, chúng rơi xuống đất:

                

Xem làm thế nào mật độ của viên đạn trên mặt đất tương ứng với phân phối mong muốn của chúng tôi! Chúng ta gần đến rồi!

Vấn đề là đối với chức năng này, trục yđầu ra và trục xđầu vào . Chúng ta chỉ có thể "bắn đạn từ mặt đất lên"! Chúng ta cần hàm nghịch đảo!

Đây là lý do tại sao chúng ta phản ánh toàn bộ sự việc; x trở thành yy trở thành x :

                

Chúng tôi gọi đây là CDF -1 . Để có được các giá trị theo phân phối mong muốn, chúng tôi sử dụng CDF -1 (ngẫu nhiên ()).

Vì vậy, quay lại để tạo các giá trị bán kính ngẫu nhiên trong đó PDF của chúng tôi bằng 2 x .

Bước 1: Tạo CDF:

Vì chúng tôi đang làm việc với thực tế, CDF được thể hiện dưới dạng tích phân của PDF.

CDF ( x ) = ∫ 2 x = x 2

Bước 2: Phản chiếu CDF dọc theo y = x :

Về mặt toán học, điều này có nghĩa là thay đổi xy và giải cho y :

CDF :      y = x 2
Hoán đổi:    x = y 2
Giải:    y = √ x
CDF -1 :   y = √ x

Bước 3: Áp dụng hàm kết quả cho giá trị đồng nhất trong khoảng từ 0 đến 1

CDF -1 (ngẫu nhiên ()) = √random ()

Đó là những gì chúng tôi đặt ra để rút ra :-)


Thuật toán này có thể được sử dụng để tạo điểm hiệu quả trên vòng.
Ivan Kovtun

Trên chiếc nhẫn? Giống như với bán kính cố định? Không chắc chắn nếu tôi hiểu câu hỏi của bạn, nhưng nếu bạn có bán kính cố định, bạn chỉ cần chọn ngẫu nhiên góc.
aioobe

2
Tôi đã cố gắng sử dụng từ đơn giản hơn "Ring" thay vì Annulus - khu vực giới hạn bởi hai vòng tròn đồng tâm. Trong trường hợp này, thuật toán loại bỏ trở nên không hiệu quả và thuật toán hàng đầu đầu tiên rất khó để khái quát. Và trường hợp góc với một bán kính cũng được bao phủ với thuật toán của bạn. Chúng tôi luôn tạo bán kính dưới dạng sqrt (ngẫu nhiên (min_radius ^ 2, max_radius ^ 2)) ngay cả khi min_radius == max_radius.
Ivan Kovtun

1
Ồ, thật tuyệt! Để rõ ràng, khi bạn nói random(min_radius², max_radius²), bạn có nghĩa là một cái gì đó tương đương random() * (max_radius² - min_radius²) + min_radius², nơi random()trả về một giá trị thống nhất giữa 0 và 1?
aioobe

vâng, đó chính xác là những gì tôi muốn nói: radius = sqrt (Random () * (max_radius² - min_radius²) + min_radius²).
Ivan Kovtun

27

Đây là một giải pháp nhanh chóng và đơn giản.

Chọn hai số ngẫu nhiên trong phạm vi (0, 1), cụ thể là ab. Nếu b < a, trao đổi chúng. Quan điểm của bạn là (b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b)).

Bạn có thể nghĩ về giải pháp này như sau. Nếu bạn lấy vòng tròn, cắt nó, sau đó duỗi thẳng ra, bạn sẽ có một hình tam giác vuông. Quy mô mà tam giác xuống, và bạn muốn có một hình tam giác từ (0, 0)để (1, 0)đến (1, 1)và ngược lại để (0, 0). Tất cả các biến đổi này thay đổi mật độ đồng đều. Những gì bạn đã làm là thống nhất chọn một điểm ngẫu nhiên trong tam giác và đảo ngược quá trình để có được một điểm trong vòng tròn.


Điều này, vì một số lý do, mang lại cho tôi phân phối đồng đều hơn nhiều so với câu trả lời được chấp nhận, mặc dù tôi cần phải chia tọa độ cho bán kính, nếu không thì nó nằm trong một vòng tròn R ^ 2
Greg Zaal

3
Cảm ơn, đây là mã của bạn trong Java, có thể ai đó sẽ thấy nó hữu ích: float Random1 = MathUtils.random (); float ngẫu nhiên2 = MathUtils.random (); float RandomXPoint = Random2 * radius MathUtils.cos (MathUtils.PI2 * Random1 / Random2); float RandomYPoint = Random2 * radius MathUtils.sin (MathUtils.PI2 * Random1 / Random2);
Tony Ceralva

rất tốt! Tôi thích ý tưởng về xác suất tập trung hơn vào các điểm, vì vậy nếu chúng ta không trao đổi khi b < achúng ta có thể đạt được điều này! ví dụ: trong javascript jsfiddle.net/b0sb5ogL/1
Guilherme

Tôi nghĩ rằng giải pháp của bạn là xấu. Nó không cho kết quả đồng đều. Kiểm tra ảnh chụp màn hình này prntscr.com/fizxgc
bolec_kolec

4
Bạn có thể giải thích thêm một chút về cách cắt vòng tròn và làm thẳng nó ra không?
kec

21

Lưu ý mật độ điểm tỷ lệ với bình phương nghịch đảo của bán kính, do đó thay vì chọn rtừ [0, r_max], chọn từ [0, r_max^2], sau đó tính tọa độ của bạn là:

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

Điều này sẽ cung cấp cho bạn phân phối điểm thống nhất trên một đĩa.

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


12

Hãy suy nghĩ về nó theo cách này. Nếu bạn có một hình chữ nhật trong đó một trục là bán kính và một trục là góc và bạn lấy các điểm bên trong hình chữ nhật này gần bán kính 0. Tất cả sẽ rơi rất gần với điểm gốc (nằm sát nhau trên vòng tròn.) Tuy nhiên, các điểm gần bán kính R, tất cả các điểm này sẽ nằm gần rìa của vòng tròn (nghĩa là cách xa nhau).

Điều này có thể cung cấp cho bạn một số ý tưởng về lý do tại sao bạn nhận được hành vi này.

Yếu tố xuất phát từ liên kết đó cho bạn biết diện tích tương ứng trong hình chữ nhật cần được điều chỉnh để không phụ thuộc vào bán kính một khi nó được ánh xạ vào vòng tròn.

Chỉnh sửa: Vì vậy, những gì anh ấy viết trong liên kết bạn chia sẻ là: "Điều đó đủ dễ thực hiện bằng cách tính toán nghịch đảo của phân phối tích lũy và chúng tôi nhận được cho r:".

Tiền đề cơ bản ở đây là bạn có thể tạo một biến có phân phối mong muốn từ đồng phục bằng cách ánh xạ đồng phục theo hàm nghịch đảo của hàm phân phối tích lũy của hàm mật độ xác suất mong muốn. Tại sao? Chỉ cần cho nó bây giờ, nhưng đây là một thực tế.

Đây là một số giải thích trực quan của tôi về toán học. Hàm mật độ f (r) đối với r phải tỷ lệ với chính r. Hiểu thực tế này là một phần của bất kỳ cuốn sách tính toán cơ bản. Xem các phần về các yếu tố khu vực cực. Một số áp phích khác đã đề cập đến điều này.

Vì vậy, chúng tôi sẽ gọi nó là f (r) = C * r;

Điều này hóa ra là hầu hết các công việc. Bây giờ, vì f (r) phải là mật độ xác suất, bạn có thể dễ dàng thấy rằng bằng cách tích hợp f (r) trong khoảng (0, R), bạn sẽ có được C = 2 / R ^ 2 (đây là bài tập cho người đọc .)

Do đó, f (r) = 2 * r / R ^ 2

OK, đó là cách bạn có được công thức trong liên kết.

Sau đó, phần cuối cùng sẽ đi từ biến ngẫu nhiên thống nhất u trong (0,1), bạn phải ánh xạ theo hàm nghịch đảo của hàm phân phối tích lũy từ mật độ mong muốn f (r) này. Để hiểu lý do tại sao đây là trường hợp bạn cần tìm một văn bản xác suất nâng cao như Papoulis có thể (hoặc tự mình lấy nó.)

Tích hợp f (r) bạn nhận được F (r) = r ^ 2 / R ^ 2

Để tìm hàm nghịch đảo của hàm này, bạn đặt u = r ^ 2 / R ^ 2 và sau đó giải cho r, cung cấp cho bạn r = R * sqrt (u)

Điều này hoàn toàn có ý nghĩa theo trực giác, u = 0 nên ánh xạ tới r = 0. Ngoài ra, u = 1 shoudl ánh xạ tới r = R. Ngoài ra, nó đi theo hàm căn bậc hai, có ý nghĩa và khớp với liên kết.


10

Lý do tại sao giải pháp ngây thơ không hoạt động là vì nó mang lại mật độ xác suất cao hơn cho các điểm gần trung tâm vòng tròn. Nói cách khác, vòng tròn có bán kính r / 2 có xác suất r / 2 nhận được một điểm được chọn trong đó, nhưng nó có diện tích (số điểm) pi * r ^ 2/4.

Do đó, chúng tôi muốn mật độ xác suất bán kính có thuộc tính sau:

Xác suất chọn bán kính nhỏ hơn hoặc bằng r cho trước phải tỷ lệ với diện tích hình tròn có bán kính r. (bởi vì chúng tôi muốn có sự phân phối đồng đều trên các điểm và các khu vực lớn hơn có nghĩa là nhiều điểm hơn)

Nói cách khác, chúng tôi muốn xác suất chọn bán kính trong khoảng [0, r] bằng với tỷ lệ của nó trong tổng diện tích của vòng tròn. Tổng diện tích hình tròn là pi * R ^ 2 và diện tích hình tròn có bán kính r là pi * r ^ 2. Do đó, chúng tôi muốn xác suất chọn bán kính trong khoảng [0, r] là (pi * r ^ 2) / (pi * R ^ 2) = r ^ 2 / R ^ 2.

Bây giờ đến toán học:

Xác suất chọn bán kính trong khoảng [0, r] là tích phân của p (r) dr từ 0 đến r (đó chỉ là do chúng ta thêm tất cả các xác suất của bán kính nhỏ hơn). Do đó, chúng tôi muốn tích phân (p (r) dr) = r ^ 2 / R ^ 2. Chúng ta có thể thấy rõ R ^ 2 là một hằng số, vì vậy tất cả những gì chúng ta cần làm là tìm ra p (r) nào, khi được tích hợp sẽ cung cấp cho chúng ta một cái gì đó như r ^ 2. Câu trả lời rõ ràng là r * không đổi. tích phân (r * hằng dr) = r ^ 2/2 * hằng số. Điều này phải bằng r ^ 2 / R ^ 2, do đó không đổi = 2 / R ^ 2. Do đó, bạn có phân phối xác suất p (r) = r * 2 / R ^ 2

Lưu ý: Một cách trực quan hơn để suy nghĩ về vấn đề là tưởng tượng rằng bạn đang cố gắng cung cấp cho mỗi vòng tròn bán kính mật độ xác suất bằng với tỷ lệ số điểm mà nó có trên chu vi của nó. Do đó, một vòng tròn có bán kính r sẽ có 2 * pi * r "điểm" trên chu vi của nó. Tổng số điểm là pi * R ^ 2. Do đó, bạn nên đưa ra xác suất ra vòng tròn bằng (2 * pi * r) / (pi * R ^ 2) = 2 * r / R ^ 2. Điều này dễ hiểu hơn nhiều và trực quan hơn, nhưng nó không hoàn toàn giống như âm thanh toán học.


9

Đặt (bán kính) và (góc phương vị) là hai biến ngẫu nhiên tương ứng với tọa độ cực của một điểm tùy ý bên trong đường tròn. Nếu các điểm được phân bố đồng đều thì hàm phân phối của và φ là gì?

Với bất kỳ r: 0 <r <R xác suất tọa độ bán kính nhỏ hơn r là

P [ρ <r] = P [điểm nằm trong vòng tròn bán kính r] = S1 / S0 = (r / R) 2

Trong đó S1 và S0 lần lượt là các diện tích hình tròn bán kính r và R. Vì vậy, CDF có thể được đưa ra là:

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

Và PDF:

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

Lưu ý rằng với R = 1 biến ngẫu nhiên sqrt (X) trong đó X đồng nhất trên [0, 1) có CDF chính xác này (vì P [sqrt (X) <y] = P [x <y ** 2] = y * * 2 cho 0 <y <= 1).

Phân bố rõ ràng là đồng nhất từ ​​0 đến 2 * π. Bây giờ bạn có thể tạo tọa độ cực ngẫu nhiên và chuyển đổi chúng sang Cartesian bằng các phương trình lượng giác:

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

Không thể cưỡng lại việc đăng mã python cho 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)

Bạn sẽ nhận được

nhập mô tả hình ảnh ở đây


7

Nó thực sự phụ thuộc vào ý của bạn là 'ngẫu nhiên thống nhất'. Đây là một điểm tinh tế và bạn có thể đọc thêm về nó trên trang wiki tại đây: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29 , trong đó cùng một vấn đề, đưa ra những cách hiểu khác nhau cho 'ngẫu nhiên thống nhất' câu trả lời khác nhau!

Tùy thuộc vào cách bạn chọn điểm, phân phối có thể khác nhau, mặc dù chúng là ngẫu nhiên thống nhất theo một nghĩa nào đó.

Có vẻ như mục blog đang cố gắng làm cho nó ngẫu nhiên đồng nhất theo nghĩa sau: Nếu bạn lấy một vòng tròn phụ của vòng tròn, có cùng tâm, thì xác suất điểm rơi trong khu vực đó tỷ lệ thuận với diện tích của vùng miền. Điều đó, tôi tin rằng, đang cố gắng tuân theo cách giải thích hiện tại là 'ngẫu nhiên thống nhất' cho các khu vực 2D với các khu vực được xác định trên đó : xác suất điểm rơi ở bất kỳ khu vực nào (với khu vực được xác định rõ) tỷ lệ thuận với khu vực của khu vực đó.


5
Hay đúng hơn, xác suất điểm rơi vào bất kỳ khu vực tùy ý nào tỷ lệ thuận với khu vực của khu vực - giả sử rằng khu vực đó có một khu vực .
ShreevatsaR

@Shree: Đúng, đó là những gì tôi muốn ám chỉ bởi tuyên bố của tôi trong ngoặc đơn. Tôi sẽ làm cho nó rõ ràng hơn, cảm ơn. btw, về blog, không có bằng chứng thực tế nào cho thấy các khu vực tùy ý đưa ra xác suất tỷ lệ, do đó tôi đã chọn cách diễn đạt nó theo cách đó.

6

Đây là mã Python của tôi để tạo numcác điểm ngẫu nhiên từ một vòng tròn bán kính 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
Tại sao không chỉ r = np.sqrt(np.random.uniform(0.0, rad**2, num))?

4

Tôi nghĩ rằng trong trường hợp này, sử dụng tọa độ cực là một cách làm phức tạp vấn đề, sẽ dễ dàng hơn nhiều nếu bạn chọn các điểm ngẫu nhiên vào một hình vuông có cạnh dài 2R và sau đó chọn các điểm (x,y)sao cho x^2+y^2<=R^2.


Ý bạn là x ^ 2 + y ^ 2 <= R ^ 2 tôi nghĩ vậy.
sigfpe

1
Đây là mẫu từ chối. Không sao, nhưng điều đó có nghĩa là thời gian tính toán thay đổi phần nào, đó có thể là một vấn đề.
Steve Bennett

Tất cả các hình vuông là 4 mặt.
xaxxon

Thuật toán này hiệu quả hơn bất cứ thứ gì liên quan đến căn bậc hai hoặc tính toán sin / cos. Nó từ chối ít hơn 21,5% điểm của hình vuông.
Ivan Kovtun

3

Giải pháp trong Java và ví dụ phân phối (2000 điểm)

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);
}

Phân phối 2000 điểm

dựa trên giải pháp thịnh hành https://stackoverflow.com/a/5838055/5224246 từ @sigfpe


2

Đầu tiên chúng ta tạo một cdf [x]

Xác suất để một điểm nhỏ hơn khoảng cách x từ tâm của đường tròn. Giả sử đường tròn có bán kính là R.

rõ ràng nếu x bằng 0 thì cdf [0] = 0

rõ ràng nếu x là R thì cdf [R] = 1

rõ ràng nếu x = r thì cdf [r] = (Pi r ^ 2) / (Pi R ^ 2)

Điều này là do mỗi "khu vực nhỏ" trên vòng tròn có cùng xác suất được chọn, do đó xác suất tỷ lệ thuận với khu vực được đề cập. Và khu vực được cho một khoảng cách x từ tâm của vòng tròn là Pi r ^ 2

vì vậy cdf [x] = x ^ 2 / R ^ 2 vì Pi hủy nhau

chúng ta có cdf [x] = x ^ 2 / R ^ 2 trong đó x đi từ 0 đến R

Vì vậy, chúng tôi giải quyết cho x

R^2 cdf[x] = x^2

x = R Sqrt[ cdf[x] ]

Bây giờ chúng ta có thể thay thế cdf bằng một số ngẫu nhiên từ 0 đến 1

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

Cuối cùng

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

chúng ta có tọa độ cực {0,601168 R, 311,915 độ}


1

Có một mối quan hệ tuyến tính giữa bán kính và số điểm "gần" bán kính đó, vì vậy anh ta cần sử dụng phân phối bán kính cũng làm cho số lượng điểm dữ liệu gần bán kính rtỷ lệ thuận với r.


1

Tôi đã sử dụng một lần phương pháp này: Điều này có thể hoàn toàn không được tối ưu hóa (nghĩa là nó sử dụng một mảng điểm để nó không thể sử dụng cho các vòng tròn lớn) nhưng cung cấp phân phối ngẫu nhiên đủ. Bạn có thể bỏ qua việc tạo ma trận và vẽ trực tiếp nếu bạn muốn. Phương pháp là chọn ngẫu nhiên tất cả các điểm trong một hình chữ nhật nằm trong vòng tròn.

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);
}

nhập mô tả hình ảnh ở đây


3
Phân phối không "đủ ngẫu nhiên". Chúng có hoặc không ngẫu nhiên cho một định nghĩa ngẫu nhiên nhất định. Câu trả lời của bạn là xiên: bạn không bình luận mã của bạn cũng như giải thích cách bạn đến với nó. Câu trả lời xiên rất khó theo dõi và khó tin tưởng hơn.
Richard

1

Phần tử diện tích trong một vòng tròn là dA = rdr * dphi. Yếu tố phụ r đó đã phá hủy ý tưởng của bạn để chọn ngẫu nhiên ar và phi. Trong khi phi được phân phối phẳng, r thì không, nhưng phẳng trong 1 / r (tức là bạn có nhiều khả năng chạm vào ranh giới hơn là "mắt của con bò").

Vì vậy, để tạo các điểm phân bố đều trên vòng tròn, chọn phi từ phân phối phẳng và r từ phân phối 1 / r.

Hoặc sử dụng phương pháp Monte Carlo do Mehrdad đề xuất.

BIÊN TẬP

Để chọn một căn hộ r ngẫu nhiên trong 1 / r, bạn có thể chọn một x ngẫu nhiên từ khoảng [1 / R, vô cùng] và tính r = 1 / x. r sau đó được phân phối phẳng trong 1 / r.

Để tính một phi ngẫu nhiên, chọn một x ngẫu nhiên từ khoảng [0, 1] và tính phi = 2 * pi * x.


Làm thế nào chính xác để tôi chọn một r từ "phân phối 1 / r" ?
aioobe

0

Tôi không biết liệu câu hỏi này có còn mở cho một giải pháp mới với tất cả câu trả lời đã được đưa ra hay không, nhưng bản thân tôi đã phải đối mặt với chính xác câu hỏi đó. Tôi đã cố gắng "lý luận" với bản thân mình cho một giải pháp, và tôi đã tìm thấy một giải pháp. Nó có thể giống như một số người đã đề xuất ở đây, nhưng dù sao thì đây là:

để hai phần tử của bề mặt hình tròn bằng nhau, giả sử dr bằng nhau, chúng ta phải có dtheta1 / dtheta2 = r2 / r1. Viết biểu thức xác suất của phần tử đó là P (r, theta) = P {r1 <r <r1 + dr, theta1 <theta <theta + dtheta1} = f (r, theta) * dr * dtheta1 và đặt hai xác suất (cho r1 và r2) bằng nhau, chúng ta đến (giả sử r và theta là độc lập) f (r1) / r1 = f (r2) / r2 = hằng số, cho f (r) = c * r. Và phần còn lại, xác định hằng số c xuất phát từ điều kiện trên f (r) là PDF.


Cách tiếp cận thú vị để bắt đầu với dtheta1 / dtheta2 = r2 / r1. Bạn có thể giải thích về cách bạn đưa ra phương trình đó không?
aioobe

Như những người khác đã đề cập (ví dụ: honk), một phần tử vi phân của bề mặt của một vòng tròn được đưa ra là r dr dtheta, vì vậy nếu chúng ta giả sử r1 = r2, thì chúng ta sẽ có dr1 * dtheta1 = dr2 * dtheta2 và phần còn lại theo sau .
arsaKasra

0

Một giải pháp lập trình:

  • Tạo một bản đồ bit (một ma trận các giá trị boolean). Nó có thể lớn như bạn muốn.
  • Vẽ một vòng tròn trong bản đồ bit đó.
  • Tạo một bảng tra cứu các điểm của vòng tròn.
  • Chọn một chỉ số ngẫu nhiên trong bảng tra cứu này.
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];
} // ()

Bitmap chỉ cần thiết cho việc giải thích logic. Đây là mã không có bitmap:

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

Tôi vẫn không chắc chắn về chính xác '(2 / R2) × r' nhưng rõ ràng là số điểm cần phân phối trong đơn vị đã cho 'dr' tức là tăng r sẽ tỷ lệ với r2 chứ không phải r.

kiểm tra theo cách này ... số điểm ở một số góc theta và giữa r (0,1r đến 0,2r) tức là tỷ lệ của r và số điểm giữa r (0,6r đến 0,7r) sẽ bằng nhau nếu bạn sử dụng thế hệ tiêu chuẩn, vì sự khác biệt chỉ là 0,1r giữa hai khoảng thời gian. nhưng vì diện tích được bao phủ giữa các điểm (0,6r đến 0,7r) sẽ lớn hơn nhiều so với diện tích nằm trong khoảng từ 0,1r đến 0,2r, nên số điểm bằng nhau sẽ được đặt cách nhau trong khu vực lớn hơn, điều này tôi giả sử bạn đã biết, vì vậy hàm này để tạo các điểm ngẫu nhiên không phải là tuyến tính mà là bậc hai, (vì số điểm cần phân phối trong đơn vị đã cho 'dr' tức là tăng r sẽ tỷ lệ với r2 chứ không phải r), vì vậy trong trường hợp này nó sẽ nghịch đảo bậc hai, vì đồng bằng ta có (0.


Bạn là người đầu tiên tham khảo định lý Pythagoras ở đây. Tôi rất thích nếu bạn có thể mở rộng điều này với một hoặc hai hình, hỗ trợ cho lời giải thích của bạn. Tôi có một thời gian khó khăn sau khi nó đứng bây giờ :-(
aioobe

@aioobe Tôi đã cố gắng viết lại câu trả lời, tôi có thể thêm sơ đồ nếu bạn cần :)
cheesefest

Tôi hiểu tại sao tôi không thể truyền bá nó một cách tuyến tính. Điều tôi không hiểu ở đây là mối liên hệ với Pythagoras hoặc với sin / cos. Có lẽ sơ đồ có thể giúp tôi ở đây.
aioobe

Pythagoras là sai lầm của tôi, xin vui lòng quên nó đi, nhưng hy vọng bạn hiểu bản chất bậc hai của hàm, chính xác (2 / R2) × r cần bằng chứng và tôi không thể đưa ra bất kỳ bằng chứng nào cho điều này
cheesefest

0

Thật là một vấn đề thú vị
Lý do xác suất của một điểm được chọn hạ xuống khi khoảng cách từ gốc tọa độ tăng được giải thích nhiều lần ở trên. Chúng tôi giải thích cho điều đó bằng cách lấy gốc của U [0,1]. Đây là một giải pháp chung cho r tích cực trong 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])

nhập mô tả hình ảnh ở đây


0

Bạn cũng có thể sử dụng trực giác của bạn.

Diện tích hình tròn là pi*r^2

Dành cho r=1

Điều này cho chúng tôi một khu vực pi. Chúng ta hãy giả sử rằng chúng ta có một số loại chức năng fsẽ thống nhất N=10các điểm trong vòng tròn. Tỷ lệ ở đây là10 / pi

Bây giờ chúng tôi nhân đôi diện tích và số điểm

Cho r=2N=20

Điều này cho một diện tích 4pivà tỷ lệ bây giờ 20/4pihoặc 10/2pi. Tỷ lệ sẽ càng ngày càng nhỏ, bán kính càng lớn, bởi vì sự tăng trưởng của nó là bậc hai và Ntỷ lệ tuyến tính.

Để khắc phục điều này chúng ta chỉ cần nói

x = r^2
sqrt(x) = r

Nếu bạn sẽ tạo một vectơ trong tọa độ cực như thế này

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

Nhiều điểm sẽ hạ cánh xung quanh trung tâm.

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

length không được phân phối đồng đều nữa, nhưng bây giờ vectơ sẽ được phân phối đồng đều.


-1

1) Chọn một X ngẫu nhiên giữa -1 và 1.

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

2) Sử dụng công thức đường tròn, tính giá trị tối đa và tối thiểu của Y cho X và bán kính 1:

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

3) Chọn một Y ngẫu nhiên giữa các thái cực đó:

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

4) Kết hợp các giá trị vị trí và bán kính của bạn trong giá trị cuối cùng:

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

2
Không đồng nhất - xác suất cho [-1, 0] cao hơn nhiều so với [0, 0], với điều kiện p ([- 1, Y]) = p ([0, Y]) và chỉ có một lựa chọn cho [-1, Y] và nhiều lựa chọn cho [0, Y].
Amadan

Giải pháp này ủng hộ các điểm về phía bên trái và bên phải của vòng tròn. Các điểm có x gần bằng 0 được thể hiện dưới mức. Không phải là một phân phối thống nhất ở tất cả.
Dawood ibn Kareem
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.