Como gerar um ponto aleatório dentro de um círculo de raio R :
r = R * sqrt(random())
theta = random() * 2 * PI
(Assumindo que random()
fornece um valor entre 0 e 1 uniformemente)
Se você deseja converter isso em coordenadas cartesianas, pode fazer
x = centerX + r * cos(theta)
y = centerY + r * sin(theta)
Por que sqrt(random())
?
Vamos olhar para a matemática que leva até sqrt(random())
. Suponha, por simplicidade, que estamos trabalhando com o círculo unitário, ou seja, R = 1.
A distância média entre os pontos deve ser a mesma, independentemente da distância do centro que olhamos. Isso significa, por exemplo, que, olhando o perímetro de um círculo com circunferência 2, deveríamos encontrar o dobro de pontos que o número de pontos no perímetro de um círculo com circunferência 1.
Como a circunferência de um círculo (2π r ) cresce linearmente com r , segue-se que o número de pontos aleatórios deve crescer linearmente com r . Em outras palavras, a função de densidade de probabilidade desejada (PDF) cresce linearmente. Como um PDF deve ter uma área igual a 1 e o raio máximo é 1, temos
Portanto, sabemos como deve ser a densidade desejada de nossos valores aleatórios. Agora: como geramos um valor tão aleatório quando tudo o que temos é um valor aleatório uniforme entre 0 e 1?
Usamos um truque chamado amostragem por transformação inversa
- No PDF, crie a função de distribuição cumulativa (CDF)
- Espelhe isso ao longo de y = x
- Aplique a função resultante a um valor uniforme entre 0 e 1.
Parece complicado? Deixe-me inserir uma citação em bloco com uma pequena faixa lateral que transmite a intuição:
Suponha que desejamos gerar um ponto aleatório com a seguinte distribuição:
Isso é
- 1/5 dos pontos uniformemente entre 1 e 2, e
- 4/5 dos pontos uniformemente entre 2 e 3.
O CDF é, como o nome sugere, a versão cumulativa do PDF. Intuitivamente: Enquanto o PDF ( x ) descreve o número de valores aleatórios em x , o CDF ( x ) descreve o número de valores aleatórios menores que x .
Nesse caso, o CDF seria semelhante a:
Para ver como isso é útil, imagine que atiramos em balas da esquerda para a direita em alturas uniformemente distribuídas. Quando as balas atingem a linha, caem no chão:
Veja como a densidade das balas no chão corresponde à nossa distribuição desejada! Estamos quase lá!
O problema é que, para esta função, o eixo y é a saída e o eixo x é a entrada . Só podemos "disparar balas do chão para cima"! Precisamos da função inversa!
É por isso que espelhamos a coisa toda; x se torna y e Y torna-se x :
Chamamos isso de CDF -1 . Para obter valores de acordo com a distribuição desejada, usamos CDF -1 (random ()).
… Então, voltemos a gerar valores aleatórios de raio em que nosso PDF é igual a 2 x .
Etapa 1: criar o CDF:
como trabalhamos com reais, o CDF é expresso como a integral do PDF.
CDF ( x ) = x 2 x = x 2
Etapa 2: espelhe o CDF ao longo de y = x :
Matematicamente isso se resume a trocar x e y e resolvendo para y :
CDF : y = x 2
Troca: x = y 2
Resolva: y = √ x
CDF -1 : y = √ x
Etapa 3: aplique a função resultante a um valor uniforme entre 0 e 1
CDF -1 (aleatório ()) = aleatório ()
Qual é o que nos propusemos a derivar :-)