Saya perlu untuk menghasilkan titik seragam acak dalam lingkaran radius R .
Saya menyadari bahwa dengan hanya mengambil sudut acak seragam dalam interval [0 ... 2π), dan jari-jari acak seragam dalam interval (0 ... R ) saya akan berakhir dengan lebih banyak poin ke arah tengah, karena untuk dua diberikan jari-jari, titik-titik dalam radius yang lebih kecil akan lebih dekat satu sama lain daripada untuk titik-titik dalam radius yang lebih besar.
Saya menemukan entri blog di sini di sini tapi saya tidak mengerti alasannya. Saya kira itu benar, tetapi saya benar-benar ingin memahami dari mana ia mendapat (2 / R 2 ) × r dan bagaimana ia mendapatkan solusi akhir.
Pembaruan: 7 tahun setelah memposting pertanyaan ini saya masih belum menerima jawaban yang memuaskan atas pertanyaan aktual mengenai matematika di balik algoritma akar kuadrat. Jadi saya menghabiskan satu hari menulis jawaban sendiri. Tautan ke jawaban saya .
sumber
Jawaban:
Mari kita mendekati ini seperti Archimedes.
Bagaimana kita dapat menghasilkan titik secara seragam dalam segitiga ABC, di mana | AB | = | BC |? Mari kita buat ini lebih mudah dengan memperluas ke AB genjang. Mudah untuk menghasilkan poin secara seragam di ABCD. Kami secara seragam memilih titik acak X pada AB dan Y pada BC dan memilih Z sedemikian rupa sehingga XBYZ adalah genjang. Untuk mendapatkan titik yang dipilih secara seragam dalam segitiga asli kami hanya melipat poin yang muncul di ADC kembali ke ABC sepanjang AC.
Sekarang perhatikan sebuah lingkaran. Dalam batas tersebut kita dapat menganggapnya sebagai tak terhingga banyaknya segitiga isoceles ABC dengan B pada titik asal dan A dan C pada lingkar yang semakin dekat satu sama lain. Kita dapat memilih salah satu dari segitiga ini hanya dengan memilih sudut theta. Jadi kita sekarang perlu membuat jarak dari pusat dengan memilih titik di sliver ABC. Sekali lagi, perpanjang ke ABCD, di mana D sekarang dua kali radius dari pusat lingkaran.
Memilih titik acak dalam ABCD mudah menggunakan metode di atas. Pilih titik acak pada AB. Pilih titik acak pada BC secara seragam. Yaitu. pilih sepasang angka acak x dan y secara seragam pada [0, R] yang memberi jarak dari pusat. Segitiga kami adalah sepotong tipis sehingga AB dan BC pada dasarnya paralel. Jadi titik Z hanyalah jarak x + y dari titik asal. Jika x + y> R kita lipat kembali.
Inilah algoritma lengkap untuk R = 1. Saya harap Anda setuju itu sangat sederhana. Ini menggunakan trigonometri, tetapi Anda dapat memberikan jaminan pada berapa lama, dan berapa banyak
random()
panggilan yang dibutuhkan, tidak seperti sampel penolakan.Ini dia di Mathematica.
sumber
random()+random()+random()
dengan lipatan yang lebih kompleks (mis. Lipatan paralel 6-arah yang sangat tipis diipip ke terahedron). Tidak yakin ini adalah metode yang baik.Cara menghasilkan titik acak dalam lingkaran jari-jari R :
(Dengan asumsi
random()
memberikan nilai antara 0 dan 1 secara seragam)Jika Anda ingin mengonversikan ini ke koordinat Cartesian, Anda dapat melakukannya
Mengapa
sqrt(random())
?Mari kita lihat matematika yang mengarah ke
sqrt(random())
. Asumsikan untuk kesederhanaan bahwa kita sedang bekerja dengan lingkaran unit, yaitu R = 1.Jarak rata-rata antara titik harus sama terlepas dari seberapa jauh dari pusat yang kita lihat. Ini berarti misalnya, bahwa dengan melihat keliling lingkaran dengan keliling 2 kita harus menemukan dua kali lebih banyak poin daripada jumlah poin pada keliling lingkaran dengan keliling 1.
Karena keliling lingkaran (2π r ) tumbuh linier dengan r , maka jumlah titik acak harus tumbuh linier dengan r . Dengan kata lain, fungsi probabilitas kerapatan yang diinginkan (PDF) tumbuh secara linear. Karena PDF harus memiliki luas sama dengan 1 dan radius maksimum adalah 1, kami punya
Jadi kita tahu bagaimana kepadatan yang diinginkan dari nilai acak kita akan terlihat. Sekarang: Bagaimana kita menghasilkan nilai acak seperti itu ketika semua yang kita miliki adalah nilai acak seragam antara 0 dan 1?
Kami menggunakan trik yang disebut sampling transformasi terbalik
Kedengarannya rumit? Biarkan saya menyisipkan blockquote dengan trek samping kecil yang menyampaikan intuisi:
... jadi, kembali untuk menghasilkan nilai radius acak di mana PDF kami sama dengan 2 x .
Langkah 1: Buat CDF:
Karena kami bekerja dengan real, CDF diekspresikan sebagai bagian integral dari PDF.
CDF ( x ) = ∫ 2 x = x 2
Langkah 2: Mirror CDF sepanjang y = x :
Secara matematis ini bermuara pada bertukar x dan y dan memecahkan untuk y :
CDF : y = x 2
Tukar: x = y 2
Selesaikan: y = √ x
CDF -1 : y = √ x
Langkah 3: Terapkan fungsi yang dihasilkan ke nilai yang seragam antara 0 dan 1
CDF -1 (acak ()) = andomrandom ()
Apa yang ingin kami peroleh :-)
sumber
random(min_radius², max_radius²)
, apakah Anda bermaksud sesuatu yang setara denganrandom() * (max_radius² - min_radius²) + min_radius²
, di manarandom()
mengembalikan nilai yang seragam antara 0 dan 1?Inilah solusi cepat dan sederhana.
Pilih dua angka acak dalam rentang (0, 1), yaitu
a
danb
. Jikab < a
, tukar mereka. Maksud Anda adalah(b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b))
.Anda dapat memikirkan solusi ini sebagai berikut. Jika Anda mengambil lingkaran, memotongnya, lalu meluruskannya, Anda akan mendapatkan segitiga siku-siku. Skala yang segitiga bawah, dan Anda akan memiliki segitiga dari
(0, 0)
ke(1, 0)
ke(1, 1)
dan kembali lagi ke(0, 0)
. Semua transformasi ini mengubah kerapatan secara seragam. Apa yang telah Anda lakukan adalah memilih titik acak dalam segitiga secara terbalik dan membalikkan proses untuk mendapatkan titik di lingkaran.sumber
b < a
kita bisa mencapai ini! misalnya dalam javascript jsfiddle.net/b0sb5ogL/1Perhatikan kerapatan titik secara proporsional dengan kuadrat terbalik dari jari-jari, maka alih-alih memilih
r
dari[0, r_max]
, memilih dari[0, r_max^2]
, lalu hitung koordinat Anda sebagai:Ini akan memberi Anda distribusi titik yang seragam pada disk.
http://mathworld.wolfram.com/DiskPointPicking.html
sumber
Pikirkan seperti ini. Jika Anda memiliki persegi panjang di mana satu sumbu adalah jari-jari dan satu adalah sudut, dan Anda mengambil titik-titik di dalam persegi panjang ini yang berada di dekat jari-jari 0. Ini semua akan jatuh sangat dekat dengan titik asal (yang berdekatan bersama pada lingkaran.) Namun, titik dekat radius R, ini semua akan jatuh di dekat tepi lingkaran (yaitu, berjauhan satu sama lain.)
Ini mungkin memberi Anda ide mengapa Anda mendapatkan perilaku ini.
Faktor yang diturunkan pada tautan itu memberi tahu Anda berapa banyak area yang sesuai dalam persegi panjang perlu disesuaikan agar tidak bergantung pada jari-jari begitu dipetakan ke lingkaran.
Sunting: Jadi yang ia tulis di tautan yang Anda bagikan adalah, "Itu cukup mudah dilakukan dengan menghitung kebalikan dari distribusi kumulatif, dan kami mendapatkan untuk r:".
Premis dasar di sini bahwa Anda dapat membuat variabel dengan distribusi yang diinginkan dari seragam dengan memetakan seragam dengan fungsi terbalik dari fungsi distribusi kumulatif fungsi kepadatan probabilitas yang diinginkan. Mengapa? Terima saja untuk saat ini, tetapi ini adalah fakta.
Ini penjelasan intuitif saya tentang matematika. Fungsi kepadatan f (r) sehubungan dengan r harus proporsional dengan r itu sendiri. Memahami fakta ini adalah bagian dari buku-buku kalkulus dasar. Lihat bagian tentang elemen area kutub. Beberapa poster lain menyebutkan ini.
Jadi kita akan menyebutnya f (r) = C * r;
Ini ternyata sebagian besar pekerjaan. Sekarang, karena f (r) harus menjadi densitas probabilitas, Anda dapat dengan mudah melihat bahwa dengan mengintegrasikan f (r) pada interval (0, R) Anda mendapatkan C = 2 / R ^ 2 (ini adalah latihan untuk pembaca .)
Dengan demikian, f (r) = 2 * r / R ^ 2
OK, jadi begitulah cara Anda mendapatkan rumus di tautan.
Kemudian, bagian terakhir diambil dari variabel acak seragam u dalam (0,1) Anda harus memetakan dengan fungsi kebalikan dari fungsi distribusi kumulatif dari kerapatan yang diinginkan ini f (r). Untuk memahami mengapa hal ini terjadi, Anda mungkin perlu menemukan teks probabilitas lanjutan seperti Papoulis (atau menurunkannya sendiri.)
Mengintegrasikan f (r) Anda mendapatkan F (r) = r ^ 2 / R ^ 2
Untuk menemukan fungsi kebalikan dari ini, Anda mengatur u = r ^ 2 / R ^ 2 dan kemudian menyelesaikan untuk r, yang memberi Anda r = R * sqrt (u)
Ini benar-benar masuk akal juga, u = 0 harus dipetakan ke r = 0. Juga, u = 1 peta shoudl ke r = R. Juga, ia pergi dengan fungsi akar kuadrat, yang masuk akal dan cocok dengan tautan.
sumber
Alasan mengapa solusi naif tidak berhasil adalah karena memberikan kepadatan probabilitas yang lebih tinggi ke titik yang lebih dekat ke pusat lingkaran. Dengan kata lain lingkaran yang memiliki jari-jari r / 2 memiliki probabilitas r / 2 untuk mendapatkan titik yang dipilih di dalamnya, tetapi memiliki luas (jumlah titik) pi * r ^ 2/4.
Karena itu kami ingin kepadatan probabilitas radius memiliki properti berikut:
Probabilitas memilih radius yang lebih kecil atau sama dengan r yang diberikan harus sebanding dengan luas lingkaran dengan jari-jari r. (karena kami ingin memiliki distribusi yang seragam pada titik dan area yang lebih luas berarti lebih banyak titik)
Dengan kata lain kami ingin probabilitas memilih jari-jari antara [0, r] sama dengan bagiannya dari keseluruhan area lingkaran. Luas lingkaran total adalah pi * R ^ 2, dan luas lingkaran dengan jari-jari r adalah pi * r ^ 2. Dengan demikian kami ingin probabilitas memilih jari-jari antara [0, r] menjadi (pi * r ^ 2) / (pi * R ^ 2) = r ^ 2 / R ^ 2.
Sekarang matematikanya:
Probabilitas memilih jari-jari antara [0, r] adalah bagian integral dari p (r) dr dari 0 hingga r (itu hanya karena kita menambahkan semua probabilitas dari jari-jari yang lebih kecil). Jadi kita ingin integral (p (r) dr) = r ^ 2 / R ^ 2. Kita dapat dengan jelas melihat bahwa R ^ 2 adalah konstanta, jadi yang perlu kita lakukan adalah mencari tahu p (r) mana, ketika terintegrasi akan memberi kita sesuatu seperti r ^ 2. Jawabannya jelas r * konstan. integral (r * konstan dr) = r ^ 2/2 * konstan. Ini harus sama dengan r ^ 2 / R ^ 2, oleh karena itu konstan = 2 / R ^ 2. Dengan demikian Anda memiliki distribusi probabilitas p (r) = r * 2 / R ^ 2
Catatan: Cara lain yang lebih intuitif untuk memikirkan masalah adalah membayangkan bahwa Anda mencoba memberikan setiap lingkaran dengan kepadatan probabilitas yang sama dengan proporsi jumlah titik yang ada pada kelilingnya. Dengan demikian lingkaran yang memiliki jari-jari r akan memiliki 2 * pi * r "titik" pada kelilingnya. Jumlah total poin adalah pi * R ^ 2. Dengan demikian Anda harus memberi lingkaran ra probabilitas sama dengan (2 * pi * r) / (pi * R ^ 2) = 2 * r / R ^ 2. Ini jauh lebih mudah untuk dipahami dan lebih intuitif, tetapi tidak cukup baik secara matematis.
sumber
Misalkan ρ (jari-jari) dan φ (azimuth) adalah dua variabel acak yang berhubungan dengan koordinat polar dari titik acak di dalam lingkaran. Jika poin-poinnya terdistribusi secara merata, apa fungsi disribusi ρ dan φ?
Untuk setiap r: 0 <r <R probabilitas koordinat jari-jari ρ menjadi kurang dari r adalah
P [ρ <r] = P [titik berada dalam lingkaran jari-jari r] = S1 / S0 = (r / R) 2
Di mana S1 dan S0 adalah area lingkaran jari-jari r dan R masing-masing. Jadi CDF dapat diberikan sebagai:
Dan PDF:
Perhatikan bahwa untuk R = 1 variabel acak sqrt (X) di mana X seragam pada [0, 1) memiliki CDF yang tepat ini (karena P [sqrt (X) <y] = P [x <y ** 2] = y * * 2 untuk 0 <y <= 1).
Distribusi φ jelas seragam dari 0 hingga 2 * π. Sekarang Anda dapat membuat koordinat kutub acak dan mengonversinya ke Cartesian menggunakan persamaan trigonometri:
Tidak dapat menolak memposting kode python untuk R = 1.
Kamu akan mendapatkan
sumber
Itu benar-benar tergantung pada apa yang Anda maksud dengan 'acak seragam'. Ini adalah hal yang halus dan Anda dapat membacanya lebih lanjut di halaman wiki di sini: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29 , di mana masalah yang sama, memberikan interpretasi yang berbeda untuk pemberian 'seragam seragam' jawaban berbeda!
Bergantung pada bagaimana Anda memilih poin, distribusinya dapat bervariasi, meskipun mereka secara acak acak dalam beberapa hal.
Sepertinya entri blog sedang mencoba membuatnya acak secara acak dalam arti berikut: Jika Anda mengambil sub-lingkaran dari lingkaran, dengan pusat yang sama, maka kemungkinan bahwa titik jatuh di wilayah itu sebanding dengan luas wilayah. wilayah. Itu, saya percaya, sedang mencoba untuk mengikuti interpretasi standar sekarang 'acak seragam' untuk daerah 2D dengan daerah yang ditentukan pada mereka : probabilitas titik jatuh di wilayah mana pun (dengan luas yang didefinisikan dengan baik) sebanding dengan luas wilayah itu.
sumber
Ini kode Python saya untuk menghasilkan
num
titik acak dari lingkaran jari-jarirad
:sumber
r = np.sqrt(np.random.uniform(0.0, rad**2, num))
?Saya pikir dalam hal ini menggunakan koordinat kutub adalah cara untuk mempersulit masalah, akan jauh lebih mudah jika Anda memilih titik acak ke dalam persegi dengan sisi panjang 2R dan kemudian memilih titik
(x,y)
sedemikian rupax^2+y^2<=R^2
.sumber
Solusi di Jawa dan contoh distribusi (2000 poin)
berdasarkan solusi previus https://stackoverflow.com/a/5838055/5224246 dari @sigfpe
sumber
Pertama kita menghasilkan cdf [x]
Probabilitas suatu titik kurang dari jarak x dari pusat lingkaran. Asumsikan lingkaran memiliki jari-jari R.
jelas jika x adalah nol maka cdf [0] = 0
jelas jika x adalah R maka cdf [R] = 1
jelas jika x = r maka cdf [r] = (Pi r ^ 2) / (Pi R ^ 2)
Ini karena setiap "area kecil" pada lingkaran memiliki probabilitas yang sama untuk dipilih, Jadi probabilitasnya proporsional dengan area yang dimaksud. Dan area yang diberi jarak x dari pusat lingkaran adalah Pi ^ 2
jadi cdf [x] = x ^ 2 / R ^ 2 karena Pi membatalkan satu sama lain
kami memiliki cdf [x] = x ^ 2 / R ^ 2 di mana x pergi dari 0 ke R
Jadi kita pecahkan untuk x
Kami sekarang dapat mengganti cdf dengan angka acak dari 0 hingga 1
Akhirnya
kita mendapatkan koordinat kutub {0,601168 R, 311,915 deg}
sumber
Ada hubungan linier antara jari-jari dan jumlah titik "dekat" jari-jari itu, sehingga ia perlu menggunakan distribusi jari-jari yang juga membuat jumlah titik data di dekat jari-jari
r
sebanding denganr
.sumber
Saya pernah menggunakan metode ini: Ini mungkin benar-benar tidak dioptimalkan (yaitu menggunakan array titik sehingga tidak dapat digunakan untuk lingkaran besar) tetapi memberikan distribusi acak yang cukup. Anda dapat melewati pembuatan matriks dan menggambar langsung jika Anda mau. Metode ini untuk mengacak semua titik dalam persegi panjang yang berada di dalam lingkaran.
sumber
Elemen area dalam lingkaran adalah dA = rdr * dphi. Faktor ekstra itu menghancurkan ide Anda untuk secara acak memilih ar dan phi. Sementara phi didistribusikan rata, r tidak, tetapi datar dalam 1 / r (yaitu Anda lebih mungkin mengenai batas daripada "mata banteng").
Jadi untuk menghasilkan poin yang terdistribusi secara merata pada lingkaran, pilih phi dari distribusi datar dan r dari distribusi 1 / r.
Atau gunakan metode Monte Carlo yang diusulkan oleh Mehrdad.
EDIT
Untuk memilih flat r acak dalam 1 / r Anda bisa memilih x acak dari interval [1 / R, infinity] dan menghitung r = 1 / x. r kemudian didistribusikan flat dalam 1 / r.
Untuk menghitung phi acak, pilih x acak dari interval [0, 1] dan hitung phi = 2 * pi * x.
sumber
Saya tidak tahu apakah pertanyaan ini masih terbuka untuk solusi baru dengan semua jawaban yang sudah diberikan, tetapi saya sendiri juga menghadapi pertanyaan yang sama. Saya mencoba "beralasan" dengan diri saya sendiri untuk sebuah solusi, dan saya menemukannya. Mungkin hal yang sama dengan beberapa yang telah disarankan di sini, tetapi bagaimanapun ini adalah:
agar dua elemen permukaan lingkaran menjadi sama, dengan asumsi sama dengan dr, kita harus memiliki dtheta1 / dtheta2 = r2 / r1. Menulis ekspresi probabilitas untuk elemen tersebut sebagai P (r, theta) = P {r1 <r <r1 + dr, theta1 <theta <theta + dtheta1} = f (r, theta) * dr * dtheta1, dan mengatur keduanya probabilitas (untuk r1 dan r2) sama, kita sampai pada (dengan asumsi r dan theta independen) f (r1) / r1 = f (r2) / r2 = konstan, yang menghasilkan f (r) = c * r. Dan sisanya, menentukan konstanta c mengikuti dari kondisi pada f (r) menjadi PDF.
sumber
Solusi programmer:
Bitmap hanya diperlukan untuk penjelasan logika. Ini adalah kode tanpa bitmap:
sumber
Saya masih tidak yakin tentang tepat '(2 / R2) × r' tetapi yang jelas adalah jumlah poin yang diperlukan untuk didistribusikan di unit 'dr' yang diberikan yaitu peningkatan r akan sebanding dengan r2 dan bukan r.
periksa dengan cara ini ... jumlah titik pada beberapa sudut theta dan antara r (0,1r hingga 0,2r) yaitu fraksi dari r dan jumlah titik antara r (0,6r hingga 0,7r) akan sama jika Anda menggunakan pembangkitan standar, karena perbedaannya hanya 0,1r antara dua interval. tetapi karena area yang dicakup antara titik (0,6r hingga 0,7r) akan jauh lebih besar daripada area yang dicakup antara 0,1r hingga 0,2r, jumlah poin yang sama akan jarang ditempatkan di area yang lebih besar, ini saya anggap Anda sudah tahu, Jadi fungsinya untuk menghasilkan titik acak tidak boleh linear tetapi kuadrat, (karena jumlah titik yang diperlukan untuk didistribusikan di unit 'dr' yaitu peningkatan r akan sebanding dengan r2 dan bukan r), jadi dalam hal ini akan kebalikan dari kuadrat, karena delta yang kita miliki (0.
sumber
Masalah yang menyenangkan.
Dasar pemikiran dari probabilitas suatu titik yang dipilih menurun ketika jarak dari asalnya meningkat dijelaskan beberapa kali di atas. Kami memperhitungkannya dengan mengambil akar U [0,1]. Inilah solusi umum untuk r positif di Python 3.
sumber
Anda juga bisa menggunakan intuisi Anda.
Luas lingkaran adalah
pi*r^2
Untuk
r=1
Ini memberi kita area
pi
. Mari kita asumsikan bahwa kita memiliki semacam fungsif
yang secara seragam akan mendistrubusikanN=10
titik-titik di dalam lingkaran. Rasio di sini adalah10 / pi
Sekarang kita menggandakan luas dan jumlah poin
Untuk
r=2
danN=20
Ini memberi area
4pi
dan rasionya sekarang20/4pi
atau10/2pi
. Rasio akan semakin kecil dan semakin kecil pula radiusnya, karena pertumbuhannya kuadratik danN
skala linear.Untuk memperbaikinya kita bisa katakan
Jika Anda akan menghasilkan vektor dalam koordinat polar seperti ini
Lebih banyak poin akan mendarat di sekitar pusat.
length
tidak terdistribusi secara merata lagi, tetapi vektor sekarang akan terdistribusi secara seragam.sumber
1) Pilih X acak antara -1 dan 1.
2) Menggunakan rumus lingkaran, hitung nilai maksimum dan minimum Y mengingat X dan jari-jari 1:
3) Pilih Y acak antara yang ekstrem:
4) Masukkan nilai lokasi dan radius Anda dalam nilai akhir:
sumber