CJam, 28 27 bayt
PP+mr_mc\ms]1.mrmqf*"(,)".\
Bu çözüm ret temelli değildir. Noktaları kutupsal koordinatlarda üretiyorum, ancak noktaların düzgün yoğunluğunu elde etmek için yarıçapların düzgün olmayan bir dağılımı ile.
Burada test edin.
açıklama
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.
Neden çalışıyor? Dar bir yarıçap r
ve (küçük) genişlik halkasını düşünün dr
. Alan yaklaşık olarak 2π*r*dr
(halka çok darsa, iç ve dış çevre neredeyse aynıdır ve eğrilik göz ardı edilebilir, böylece alan, çevrenin yan uzunluklarına ve genişliğine sahip bir dikdörtgeninki gibi işlenebilir. halka). Böylece alan yarıçapla doğrusal olarak artar. Bu, sabit bir yoğunluk elde etmek için rastgele yarıçapların doğrusal bir dağılımını istediğimiz anlamına gelir (yarıçapın iki katında, doldurulacak iki kat daha fazla alan vardır, bu yüzden orada iki kat daha fazla nokta isteriz).
0'dan 1'e doğrusal bir rastgele dağılım nasıl oluştururuz? Önce ayrık duruma bakalım. Diyelim ki, 4 değerin istenen bir dağılımına sahibiz, örneğin {0.1, 0.4, 0.2, 0.3}
( 1
4 kat daha yaygın olmak istiyoruz)0
ve iki kat daha yaygın olmak 2
istiyoruz; 3
üç kat daha yaygın olmak istiyoruz 0
):
İstenilen dağılım ile dört değerden birini nasıl seçebilirim? Bunları biriktirebilir, y ekseninde 0 ile 1 arasında rastgele rastgele bir değer seçebilir ve o noktada segmenti seçebiliriz:
Yine de bu toplama görselleştirmek için farklı bir yolu var. Bunun yerine, dağıtımın her bir değerini, o noktaya kadar olan değerlerin birikimi ile değiştirebiliriz:
Ve şimdi bu grafiğin üst satırını bir işlev olarak ele alıyoruz f(x) = y
ve bir işlev elde etmek için tersine çeviriyoruz .g(y) = f-1(y) = x
y ∈ [0,1]
:
Harika, öyleyse bunu yarıçapların doğrusal bir dağılımını oluşturmak için nasıl kullanabiliriz? İstediğimiz dağıtım bu:
İlk adım dağılımın değerlerini biriktirmektir. Ama dağıtımı bunun yerine önceki tüm değerlerin üzerinde toplayarak nedeniyle, bir integralini almak, süreklidir 0
için r
. Biz kolayca Analitik Olarak çözebilir: . Bununla birlikte, bunun normalleştirilmesini istiyoruz, yani, bunun maksimum değeri verecek şekilde bir sabitle çarpmasını istiyoruz, bu yüzden gerçekten istediğimiz şey :∫0r r dr = 1/2 r2
1
r
r2
Ve son olarak, [0,1]
tekrar analitik olarak yapabileceğimiz tek tip bir değere uygulayabileceğimiz bir fonksiyon elde etmek için bunu tersine çeviriyoruz : sadece r = √y
, neredey
rastgele değer :
Bu genellikle basit dağılımları tam olarak oluşturmak için kullanılabilecek oldukça yararlı bir tekniktir (herhangi bir dağıtım için çalışır, ancak karmaşık olanlar için son iki adımın sayısal olarak çözülmesi gerekebilir). Bununla birlikte, bu özel durumda üretim kodunda kullanmam, çünkü kare kök, sinüs ve kosinüs aşırı derecede pahalıdır: ret tabanlı bir algoritma kullanmak ortalama olarak çok daha hızlıdır, çünkü sadece toplama ve çarpmaya ihtiyaç duyar.