J'ai besoin de générer un point uniformément aléatoire dans un cercle de rayon R .
Je me rends compte qu'en choisissant simplement un angle uniformément aléatoire dans l'intervalle [0 ... 2π), et un rayon uniformément aléatoire dans l'intervalle (0 ... R ), je me retrouverais avec plus de points vers le centre, car pour deux donnés rayons, les points dans le plus petit rayon seront plus proches les uns des autres que pour les points dans le plus grand rayon.
J'ai trouvé une entrée de blog à ce sujet ici, mais je ne comprends pas son raisonnement. Je suppose que c'est correct, mais j'aimerais vraiment comprendre d'où il obtient (2 / R 2 ) × r et comment il dérive la solution finale.
Mise à jour: 7 ans après avoir posté cette question, je n'avais toujours pas reçu de réponse satisfaisante à la question réelle concernant les mathématiques derrière l'algorithme de racine carrée. J'ai donc passé une journée à rédiger une réponse moi-même. Lien vers ma réponse .
la source
Réponses:
Abordons cela comme l'aurait fait Archimède.
Comment générer un point uniformément dans un triangle ABC, où | AB | = | BC |? Rendons cela plus facile en s'étendant à un parallélogramme ABCD. Il est facile de générer des points uniformément dans ABCD. Nous choisissons uniformément un point aléatoire X sur AB et Y sur BC et choisissons Z tel que XBYZ est un parallélogramme. Pour obtenir un point uniformément choisi dans le triangle d'origine, il suffit de replier tous les points qui apparaissent dans ADC vers ABC le long de AC.
Considérons maintenant un cercle. À la limite, nous pouvons le considérer comme une infinité de triangles isocèles ABC avec B à l'origine et A et C sur la circonférence disparaissant les uns près des autres. Nous pouvons choisir l'un de ces triangles simplement en choisissant un angle thêta. Nous devons donc maintenant générer une distance par rapport au centre en choisissant un point dans le ruban ABC. Encore une fois, étendez-vous à ABCD, où D est maintenant deux fois le rayon du centre du cercle.
Choisir un point aléatoire dans ABCD est facile en utilisant la méthode ci-dessus. Choisissez un point aléatoire sur AB. Choisissez uniformément un point aléatoire sur la Colombie-Britannique. C'est à dire. choisir une paire de nombres aléatoires x et y uniformément sur [0, R] en donnant les distances du centre. Notre triangle est un mince ruban, donc AB et BC sont essentiellement parallèles. Le point Z est donc simplement à une distance x + y de l'origine. Si x + y> R, nous replions vers le bas.
Voici l'algorithme complet pour R = 1. J'espère que vous êtes d'accord, c'est assez simple. Il utilise trig, mais vous pouvez donner une garantie sur la durée et le nombre d'
random()
appels dont il a besoin, contrairement à l'échantillonnage de rejet.Le voici dans Mathematica.
la source
random()+random()+random()
avec un pliage plus complexe (c'est-à-dire un pli à 6 voies d'un parallélépipède infinitésimal fin vers un téraèdre). Pas convaincu cependant que c'est une bonne méthode.Comment générer un point aléatoire dans un cercle de rayon R :
(En supposant
random()
donne une valeur entre 0 et 1 uniformément)Si vous souhaitez convertir cela en coordonnées cartésiennes, vous pouvez le faire
Pourquoi
sqrt(random())
?Regardons les mathématiques qui mènent à
sqrt(random())
. Supposons pour plus de simplicité que nous travaillons avec le cercle unitaire, c'est-à-dire R = 1.La distance moyenne entre les points doit être la même quelle que soit la distance du centre que nous regardons. Cela signifie par exemple, qu'en regardant sur le périmètre d'un cercle de circonférence 2, nous devrions trouver deux fois plus de points que le nombre de points sur le périmètre d'un cercle de circonférence 1.
Puisque la circonférence d'un cercle (2π r ) croît linéairement avec r , il s'ensuit que le nombre de points aléatoires devrait croître linéairement avec r . En d'autres termes, la fonction de densité de probabilité souhaitée (PDF) croît linéairement. Puisqu'un PDF doit avoir une aire égale à 1 et le rayon maximum est 1, nous avons
Nous savons donc à quoi devrait ressembler la densité souhaitée de nos valeurs aléatoires. Maintenant: comment générer une telle valeur aléatoire alors que tout ce que nous avons est une valeur aléatoire uniforme entre 0 et 1?
Nous utilisons une astuce appelée échantillonnage par transformée inverse
Cela semble compliqué? Permettez-moi d'insérer un blockquote avec une petite piste latérale qui transmet l'intuition:
… Donc, revenons à la génération de valeurs de rayon aléatoires où notre PDF est égal à 2 x .
Étape 1: créer le CDF:
Puisque nous travaillons avec des réels, le CDF est exprimé comme l'intégrale du PDF.
CDF ( x ) = ∫ 2 x = x 2
Étape 2: miroir du CDF le long de y = x :
Mathématiquement, cela se résume à permuter x et y et à résoudre pour y :
CDF : y = x 2
Swap: x = y 2
Résoudre: y = √ x
CDF -1 : y = √ x
Étape 3: appliquez la fonction résultante à une valeur uniforme entre 0 et 1
CDF -1 (aléatoire ()) = √ aléatoire ()
C'est ce que nous avons décidé de tirer :-)
la source
random(min_radius², max_radius²)
, voulez-vous dire quelque chose d'équivalent àrandom() * (max_radius² - min_radius²) + min_radius²
, oùrandom()
renvoie une valeur uniforme entre 0 et 1?Voici une solution simple et rapide.
Choisissez deux nombres aléatoires dans la plage (0, 1), à savoir
a
etb
. Sib < a
, échangez-les. Votre point est(b*R*cos(2*pi*a/b), b*R*sin(2*pi*a/b))
.Vous pouvez penser à cette solution comme suit. Si vous preniez le cercle, le coupiez, puis le redressiez, vous obtiendriez un triangle rectangle. Échelle que vers le bas triangle, et vous auriez un triangle de
(0, 0)
à(1, 0)
à(1, 1)
et revenir de nouveau(0, 0)
. Toutes ces transformations modifient uniformément la densité. Ce que vous avez fait, c'est uniformément choisi un point aléatoire dans le triangle et inversé le processus pour obtenir un point dans le cercle.la source
b < a
nous pouvons y arriver! par exemple en javascript jsfiddle.net/b0sb5ogL/1Notez la densité de point proportionnelle à l' inverse du carré du rayon, donc au lieu de choisir à
r
partir[0, r_max]
, choisir à partir[0, r_max^2]
, puis calculer vos coordonnées comme:Cela vous donnera une distribution uniforme des points sur un disque.
http://mathworld.wolfram.com/DiskPointPicking.html
la source
Pensez-y de cette façon. Si vous avez un rectangle où un axe est un rayon et un est un angle, et vous prenez les points à l'intérieur de ce rectangle qui sont proches du rayon 0. Ceux-ci tomberont tous très près de l'origine (c'est-à-dire rapprochés sur le cercle). Cependant, les points proches du rayon R, ceux-ci tomberont tous près du bord du cercle (c'est-à-dire éloignés les uns des autres).
Cela pourrait vous donner une idée de la raison pour laquelle vous obtenez ce comportement.
Le facteur dérivé sur ce lien vous indique la quantité de zone correspondante dans le rectangle qui doit être ajustée pour ne pas dépendre du rayon une fois qu'il est mappé au cercle.
Edit: Donc, ce qu'il écrit dans le lien que vous partagez est: "C'est assez facile à faire en calculant l'inverse de la distribution cumulative, et nous obtenons pour r:".
La prémisse de base est ici que vous pouvez créer une variable avec une distribution souhaitée à partir d'un uniforme en mappant l'uniforme par la fonction inverse de la fonction de distribution cumulative de la fonction de densité de probabilité souhaitée. Pourquoi? Prenez-le pour acquis pour l'instant, mais c'est un fait.
Voici mon explication intuitive des mathématiques. La fonction de densité f (r) par rapport à r doit être proportionnelle à r lui-même. Comprendre ce fait fait partie de tous les livres de calcul de base. Voir les sections sur les éléments de la zone polaire. Quelques autres affiches l'ont mentionné.
Nous l'appellerons donc f (r) = C * r;
Cela s'avère être la majeure partie du travail. Maintenant, puisque f (r) devrait être une densité de probabilité, vous pouvez facilement voir qu'en intégrant f (r) sur l'intervalle (0, R) vous obtenez que C = 2 / R ^ 2 (c'est un exercice pour le lecteur .)
Ainsi, f (r) = 2 * r / R ^ 2
OK, c'est ainsi que vous obtenez la formule dans le lien.
Ensuite, la dernière partie part de la variable aléatoire uniforme u dans (0,1) que vous devez mapper par la fonction inverse de la fonction de distribution cumulative à partir de cette densité souhaitée f (r). Pour comprendre pourquoi c'est le cas, vous devez probablement trouver un texte de probabilité avancé comme Papoulis (ou le dériver vous-même.)
En intégrant f (r) vous obtenez F (r) = r ^ 2 / R ^ 2
Pour trouver la fonction inverse de cela, vous définissez u = r ^ 2 / R ^ 2, puis résolvez pour r, ce qui vous donne r = R * sqrt (u)
Cela a également un sens intuitif, u = 0 doit correspondre à r = 0. De plus, u = 1 doit correspondre à r = R. De plus, il passe par la fonction racine carrée, qui a du sens et correspond au lien.
la source
La raison pour laquelle la solution naïve ne fonctionne pas est qu'elle donne une densité de probabilité plus élevée aux points les plus proches du centre du cercle. En d'autres termes, le cercle qui a un rayon r / 2 a une probabilité r / 2 d'obtenir un point sélectionné, mais il a une aire (nombre de points) pi * r ^ 2/4.
Par conséquent, nous voulons qu'une densité de probabilité de rayon ait la propriété suivante:
La probabilité de choisir un rayon plus petit ou égal à un r donné doit être proportionnelle à l'aire du cercle de rayon r. (parce que nous voulons avoir une distribution uniforme sur les points et des zones plus grandes signifient plus de points)
En d'autres termes, nous voulons que la probabilité de choisir un rayon entre [0, r] soit égale à sa part de l'aire globale du cercle. L'aire totale du cercle est pi * R ^ 2, et l'aire du cercle de rayon r est pi * r ^ 2. Ainsi, nous aimerions que la probabilité de choisir un rayon entre [0, r] soit (pi * r ^ 2) / (pi * R ^ 2) = r ^ 2 / R ^ 2.
Vient maintenant le calcul:
La probabilité de choisir un rayon entre [0, r] est l'intégrale de p (r) dr de 0 à r (c'est simplement parce que nous ajoutons toutes les probabilités des rayons les plus petits). Nous voulons donc l'intégrale (p (r) dr) = r ^ 2 / R ^ 2. Nous pouvons clairement voir que R ^ 2 est une constante, donc tout ce que nous devons faire est de déterminer quel p (r), une fois intégré, nous donnerait quelque chose comme r ^ 2. La réponse est clairement r * constante. intégrale (r * constante dr) = r ^ 2/2 * constante. Cela doit être égal à r ^ 2 / R ^ 2, donc constant = 2 / R ^ 2. Vous avez donc la distribution de probabilité p (r) = r * 2 / R ^ 2
Remarque: Une autre façon plus intuitive de penser au problème est d'imaginer que vous essayez de donner à chaque cercle de rayon une densité de probabilité égale à la proportion du nombre de points qu'il a sur sa circonférence. Ainsi un cercle qui a un rayon r aura 2 "pi" r "points" sur sa circonférence. Le nombre total de points est pi * R ^ 2. Ainsi, vous devriez donner la probabilité du cercle ra égale à (2 * pi * r) / (pi * R ^ 2) = 2 * r / R ^ 2. C'est beaucoup plus facile à comprendre et plus intuitif, mais ce n'est pas aussi sain mathématiquement.
la source
Soit ρ (rayon) et φ (azimut) deux variables aléatoires correspondant aux coordonnées polaires d'un point arbitraire à l'intérieur du cercle. Si les points sont uniformément distribués, alors quelle est la fonction de répartition de ρ et φ?
Pour tout r: 0 <r <R, la probabilité que la coordonnée de rayon ρ soit inférieure à r est
P [ρ <r] = P [le point est dans un cercle de rayon r] = S1 / S0 = (r / R) 2
Où S1 et S0 sont les zones de cercle de rayon r et R respectivement. Ainsi, le CDF peut être donné comme:
Et PDF:
Notez que pour R = 1 variable aléatoire sqrt (X) où X est uniforme sur [0, 1) a ce CDF exact (car P [sqrt (X) <y] = P [x <y ** 2] = y * * 2 pour 0 <y <= 1).
La distribution de φ est évidemment uniforme de 0 à 2 * π. Vous pouvez maintenant créer des coordonnées polaires aléatoires et les convertir en cartésiennes à l'aide d'équations trigonométriques:
Je ne peux pas résister à publier du code python pour R = 1.
Tu auras
la source
Cela dépend vraiment de ce que vous entendez par «uniformément aléatoire». C'est un point subtil et vous pouvez en savoir plus sur la page wiki ici: http://en.wikipedia.org/wiki/Bertrand_paradox_%28probability%29 , où le même problème, donnant des interprétations différentes de `` uniformément aléatoire '' donne réponses différentes!
Selon la façon dont vous choisissez les points, la distribution peut varier, même s'ils sont uniformément aléatoires certains sens.
Il semble que l'entrée de blog tente de le rendre uniformément aléatoire dans le sens suivant: si vous prenez un sous-cercle du cercle, avec le même centre, la probabilité que le point tombe dans cette région est proportionnelle à la zone de la région. Cela, je crois, tente de suivre l'interprétation désormais standard de `` uniformément aléatoire '' pour les régions 2D avec des zones définies sur elles : la probabilité qu'un point tombe dans une région (avec une zone bien définie) est proportionnelle à la zone de cette région.
la source
Voici mon code Python pour générer
num
des points aléatoires à partir d'un cercle de rayonrad
:la source
r = np.sqrt(np.random.uniform(0.0, rad**2, num))
?Je pense que dans ce cas, l'utilisation de coordonnées polaires est un moyen de compliquer le problème, il serait beaucoup plus facile si vous choisissez des points aléatoires dans un carré avec des côtés de longueur 2R, puis sélectionnez les points
(x,y)
tels quex^2+y^2<=R^2
.la source
Solution en Java et l'exemple de distribution (2000 points)
basé sur la solution previus https://stackoverflow.com/a/5838055/5224246 de @sigfpe
la source
D'abord, nous générons un cdf [x] qui est
Probabilité qu'un point soit inférieur à la distance x du centre du cercle. Supposons que le cercle ait un rayon de R.
évidemment si x est nul alors cdf [0] = 0
évidemment si x est R alors le cdf [R] = 1
évidemment si x = r alors le cdf [r] = (Pi r ^ 2) / (Pi R ^ 2)
En effet, chaque "petite zone" sur le cercle a la même probabilité d'être sélectionnée, donc la probabilité est proportionnelle à la zone en question. Et l'aire à une distance x du centre du cercle est Pi r ^ 2
donc cdf [x] = x ^ 2 / R ^ 2 parce que les Pi s'annulent
nous avons cdf [x] = x ^ 2 / R ^ 2 où x va de 0 à R
Nous résolvons donc pour x
Nous pouvons maintenant remplacer cdf par un nombre aléatoire de 0 à 1
finalement
on obtient les coordonnées polaires {0,601168 R, 311,915 deg}
la source
Il existe une relation linéaire entre le rayon et le nombre de points "près" de ce rayon, il doit donc utiliser une distribution de rayon qui rend également le nombre de points de données près d'un rayon
r
proportionnel àr
.la source
J'ai utilisé une fois cette méthode: celle-ci peut être totalement non optimisée (c'est-à-dire qu'elle utilise un tableau de points donc son inutilisable pour les grands cercles) mais donne une distribution aléatoire suffisante. Vous pouvez ignorer la création de la matrice et dessiner directement si vous le souhaitez. La méthode consiste à randomiser tous les points d'un rectangle qui se trouvent à l'intérieur du cercle.
la source
L'élément d'aire dans un cercle est dA = rdr * dphi. Ce facteur supplémentaire r a détruit votre idée de choisir au hasard ar et phi. Alors que phi est distribué à plat, r ne l'est pas, mais à plat dans 1 / r (c'est-à-dire que vous êtes plus susceptible de toucher la frontière que "l'oeil de boeuf").
Donc, pour générer des points uniformément répartis sur le cercle, choisissez phi à partir d'une distribution plate et r à partir d'une distribution 1 / r.
Vous pouvez également utiliser la méthode Monte Carlo proposée par Mehrdad.
ÉDITER
Pour choisir un r aléatoire aléatoire dans 1 / r, vous pouvez choisir un x aléatoire dans l'intervalle [1 / R, infini] et calculer r = 1 / x. r est alors réparti à plat dans 1 / r.
Pour calculer un phi aléatoire, choisissez un x aléatoire dans l'intervalle [0, 1] et calculez phi = 2 * pi * x.
la source
Je ne sais pas si cette question est toujours ouverte pour une nouvelle solution avec toutes les réponses déjà données, mais il se trouve que j'ai été confronté exactement à la même question moi-même. J'ai essayé de "raisonner" avec moi-même pour une solution, et j'en ai trouvé une. Ce pourrait être la même chose que certains l'ont déjà suggéré ici, mais de toute façon ici c'est:
pour que deux éléments de la surface du cercle soient égaux, en supposant des dr égaux, nous devons avoir dtheta1 / dtheta2 = r2 / r1. Écriture de l'expression de la probabilité pour cet élément comme P (r, thêta) = P {r1 <r <r1 + dr, thêta1 <thêta <thêta + dthêta1} = f (r, thêta) * dr * dthêta1, et définition des deux probabilités (pour r1 et r2) égales, on arrive à (en supposant que r et thêta sont indépendants) f (r1) / r1 = f (r2) / r2 = constant, ce qui donne f (r) = c * r. Et le reste, la détermination de la constante c découle de la condition sur f (r) étant un PDF.
la source
Une solution de programmation:
Le bitmap n'est nécessaire que pour l'explication de la logique. Voici le code sans le bitmap:
la source
Je ne suis toujours pas sûr de l'exact '(2 / R2) × r' mais ce qui est évident, c'est le nombre de points à distribuer dans l'unité donnée 'dr', c'est-à-dire que l'augmentation de r sera proportionnelle à r2 et non à r.
vérifiez de cette façon ... le nombre de points sous un certain angle thêta et entre r (0,1r à 0,2r), c'est-à-dire la fraction du r et le nombre de points entre r (0,6r à 0,7r) serait égal si vous utilisez la génération standard, car la différence n'est que de 0,1r entre deux intervalles. mais comme la zone couverte entre les points (0,6r à 0,7r) sera beaucoup plus grande que la zone couverte entre 0,1r à 0,2r, le nombre égal de points sera légèrement espacé dans une zone plus grande, je suppose que vous le savez déjà, donc la fonction pour générer les points aléatoires ne doit pas être linéaire mais quadratique, (puisque le nombre de points à distribuer dans une unité donnée 'dr', c'est-à-dire l'augmentation de r sera proportionnelle à r2 et non r), donc dans ce cas, il sera inverse de quadratique, puisque le delta que nous avons (0.
la source
Un tel problème amusant.
La justification de la probabilité qu'un point soit choisi baissant à mesure que la distance par rapport à l'origine de l'axe augmente est expliquée plusieurs fois ci-dessus. Nous tenons compte de cela en prenant la racine de U [0,1]. Voici une solution générale pour un r positif dans Python 3.
la source
Vous pouvez également utiliser votre intuition.
L'aire d'un cercle est
pi*r^2
Pour
r=1
Cela nous donne une superficie de
pi
. Supposons que nous avons une sorte de fonctionf
qui perturberait uniformémentN=10
points à l'intérieur d'un cercle. Le rapport ici est10 / pi
Maintenant, nous doublons la surface et le nombre de points
Pour
r=2
etN=20
Cela donne une zone de
4pi
et le rapport est maintenant20/4pi
ou10/2pi
. Le rapport deviendra de plus en plus petit plus le rayon est grand, car sa croissance est quadratique etN
échelles linéaires.Pour résoudre ce problème, nous pouvons simplement dire
Si vous générez un vecteur en coordonnées polaires comme celui-ci
Plus de points atterriraient autour du centre.
length
n'est plus uniformément distribué, mais le vecteur sera désormais uniformément distribué.la source
1) Choisissez un X aléatoire entre -1 et 1.
2) En utilisant la formule du cercle, calculez les valeurs maximales et minimales de Y étant donné que X et un rayon de 1:
3) Choisissez un Y aléatoire entre ces extrêmes:
4) Incorporez vos valeurs d'emplacement et de rayon dans la valeur finale:
la source