Goûtez la distribution de Pareto


22

La distribution de Pareto est une distribution de probabilité qui revient beaucoup dans la nature. Il possède de nombreuses propriétés spéciales, telles qu'une moyenne infinie. Dans ce défi, vous allez sortir un nombre échantillonné à partir de cette distribution.

La distribution de Pareto est définie comme étant supérieure ou égale à xavec probabilité 1/x, pour tous xsupérieure ou égale à 1.

Par conséquent, un nombre échantillonné à partir de cette distribution est supérieur ou égal à 1 avec probabilité 1, supérieur ou égal à 2 avec probabilité exactement 1/2, supérieur ou égal à 3 avec probabilité exactement 1/3, supérieur ou égal à 11,4 avec probabilité exactement 1 / 11,4, et ainsi de suite.

Puisque vous échantillonnerez cette distribution, votre programme ou fonction ne prendra aucune entrée et produira un nombre aléatoire, avec les probabilités ci-dessus. Cependant, si votre programme ne correspond pas parfaitement aux probabilités ci-dessus en raison d'une impression en virgule flottante, c'est OK. Voir le bas du défi pour plus de détails.

(C'est ce qu'on appelle la distribution de Pareto avec alpha 1 et borne inférieure 1, pour être exact)

Voici 10 exemples tirés de cette distribution:

1.1540029602790338
52.86156818209856
3.003306506971116
1.4875532217142287
1.3604286212876546
57.5263129600285
1.3139866916055676
20.25125817471419
2.8105749663695208
1.1528212409680156

Remarquez comment 5 d'entre eux sont inférieurs à 2 et 5 supérieurs à 2. Comme il s'agit du résultat moyen, il aurait pu être supérieur ou inférieur, bien sûr.

Votre réponse ne doit être correcte que dans les limites de votre type à virgule flottante, type à nombre réel ou tout autre élément que vous utilisez, mais vous devez être en mesure de représenter des nombres avec au moins 3 chiffres décimaux de précision et des nombres jusqu'à 1 000 000 . Si vous ne savez pas si quelque chose va bien, n'hésitez pas à demander.

C'est le golf de code.


Détails sur l'imprécision:

  • Pour chaque plage [a, b], où 1 <= a < b, la probabilité idéale que l'échantillon tombe dans cette plage est 1/a - 1/b. La probabilité que votre programme produise un nombre dans cette plage doit être 0.001de 1/a - 1/b. Si Xest la sortie de votre programme, il est nécessaire que |P(a <= X <= b) - (1/a - 1/b)| < 0.001.

  • Notez qu'en appliquant la règle ci-dessus avec a=1et bsuffisamment grand, il est vrai que votre programme doit sortir un nombre supérieur ou égal à 1 avec au moins une probabilité de 0,999. Le reste du temps, il peut planter, produire Infinityou faire autre chose.

Je suis assez certain que les soumissions existantes du formulaire 1/1-xou 1/x, où xest un flottant aléatoire dans [0, 1)ou (0, 1)ou [0, 1], satisfont toutes à cette exigence.



2
Note à tout le monde: issacg a ajouté quelques règles qui permettent certaines imprécisions, donc la plupart des réponses ici sont plus longues que nécessaire. [désolé pour les commentaires abusifs aussi, mais c'est ce qui se passerait lorsque OP changerait de manière significative la question]
user202729

Réponses:




5

R, 10 octets

1/runif(1)

Assez simple.


2
Notez que runif ne renvoie jamais 0 ou 1 dans le cas par défaut , il n'y a donc aucun problème avec cela.
Giuseppe

Oui merci. Et je n'y ai pas pensé en entrant cette réponse mais vous pouvez en effet vérifier la distribution si besoin.
plannapus

2
@Mego qui est incorrect. La distribution de Pareto est absolument continue et a donc la mesure 0 pour tout nombre.
Therkel

3
@Mego OK, cela peut être du sable mouvant pour moi (étant donné que je ne sais presque rien de la virgule flottante), mais je pense en fait que si la probabilité de runifdonner 1 est nulle, la probabilité de 1/runifdonner 1 ne l'est pas, en raison de la précision en virgule flottante ( c'est-à-dire généralement 1 / 0,9999999 renvoie 1 dans R).
plannapus

1
@plannapus Hmm ... C'est un bon point. Les flotteurs rendent cela trop compliqué.
Mego

4

TI-Basic, 2 octets

rand^-1      (AB 0C in hex)

Pour tous ceux qui se demandent, randrenvoie une valeur aléatoire dans (0,1]. "En raison des spécificités de l'algorithme de génération de nombres aléatoires, le plus petit nombre possible à générer est légèrement supérieur à 0. Le plus grand nombre possible est en fait 1 ... "( source ). Par exemple, ensemencer le rand avec 196164532 donne 1.


Étrangement, le code équivalent ne fonctionnerait pas sur une calculatrice de la série TI-89. Même si leurs générateurs de nombres aléatoires sont presque identiques, une TI-89 renverra 0 chaque fois qu'une TI-83 + renverra 0,99999999999889.
Misha Lavrov

2
Les développeurs TI-Basic savaient à l'avance que ce défi se produira ...? Il semble gagner cette fois.
user202729

@ user202729 Éviter 0 et 1 rend randplus utile comme sous-programme pour les autres commandes de la calculatrice, c'est probablement pourquoi TI a pris cette décision de conception. Par exemple, randNorm(0,1renvoie -7.02129...avec la valeur de départ 196164532. L'utilisation de l'algorithme RNG sans l'ajustement donnerait une valeur de 1e99, qui est une valeur déraisonnable pour une variable normalement distribuée.
Misha Lavrov

@ user202729 Oui, en fait, j'ai juste un peu voyagé dans le temps pour tout faire. Ça vaut vraiment le coup pour ces votes positifs.
Timtech

4

R , 12 octets

exp(rexp(1))

Essayez-le en ligne!

Vérifier la distribution

Cela prend une approche différente, exploitant le fait que si Y~exp(alpha), alors X=x_m*e^Yc'est un Pareto avec des paramètres x_m,alpha. Étant donné que les deux paramètres sont 1 et que le paramètre de taux par défaut rexpest 1, cela donne la distribution de Pareto appropriée.

Bien que cette réponse soit une approche assez spécifique à R, elle est malheureusement moins golfique que celle de plannapus .

R , 14 octets

1/rbeta(1,1,1)

Essayez-le en ligne!

Encore moins golfique, mais une autre façon d'arriver à la réponse.

Une autre propriété de la distribution exponentielle est que si X ~ Exp(λ) then e^−X ~ Beta(λ, 1), d'où 1/Beta(1,1)est a Pareto(1,1).

De plus, un observateur avisé se rappellerait que si X ~ Beta(a,b)et a=b=1alors X~Unif(0,1), il en est vraiment ainsi 1/runif(1).


Je n'ai aucune idée. Mais la réalité est qu'il y a une énorme confusion sur ce qui est autorisé et ce qui ne relève pas de ce défi.
user202729

@ user202729 c'est juste, mais ceux qui ont soulevé des inquiétudes à ce sujet auraient au moins commenté, donc le downvote est (à mon avis) peu susceptible d'être lié à cela. EDIT: mystère downvoter a supprimé le downvote.
Giuseppe

J'ai voté contre parce que je pensais que l'utilisation de R sur un défi comme celui-ci était triviale, mais j'étais un peu heureux de la gâchette. Je me rends compte que cela utilise une méthode différente de la plupart des autres réponses, j'ai donc supprimé mon downvote.
KSmarts

@KSmarts La réponse "triviale" dans R n'a été utilisée par personne en fait actuar::rpareto(1,1,1)
:,

Pour info, il y a ca. 20 distributions codées en dur dans la base R, mais Pareto n'en fait pas partie, d'où la nécessité d'utiliser une solution de contournement ou un package supplémentaire.
plannapus

3

Fusain , 10 octets

I∕Xφ²⊕‽Xφ²

Essayez-le en ligne!

Lien vers la version détaillée:

Print(Cast(Divide(Power(f, 2), ++(Random(Power(f, 2))))));

Commentaires:

  • Le charbon de bois n'a que des méthodes pour obtenir des nombres entiers aléatoires, donc pour obtenir un nombre à virgule flottante aléatoire entre 0 et 1, nous devons obtenir un entier aléatoire entre 0 et N et diviser par N.
  • Version précédente de cette réponse qui utilisait la 1/(1-R)formule: dans ce cas, N est défini sur 1000000 car l'OP le demande comme étant le minimum. Pour obtenir ce nombre, le charbon de bois fournit une variable prédéfinie f= 1000. Il suffit donc de calculer f^2nous obtenons 1000000. Dans le cas où le nombre aléatoire est 999999 (le maximum), 1/(1-0.999999)=1000000.
  • Astuce de Neil (économie de 3 octets): Si j'ai 1/(1-R/N)Rest un nombre aléatoire entre 0 et N, c'est la même chose que de calculer N/(N-R). Mais étant donné que les entiers aléatoires N-Ret Ront la même probabilité de se produire, c'est la même chose que de simplement calculer N/R(étant Rdans ce dernier cas un nombre compris entre 1 et N inclus pour éviter la division par zéro).


@Neil s'il vous plaît attendez un moment pendant que j'essaye de comprendre ce que fait votre code ... :-)
Charlie

En fait, je n'ai plus besoin MapAssignRightde 10 octets! travaux.
Neil

L'assimilation @Neil de votre code est terminée! Réponse modifiée. :-D
Charlie

3

Haskell , 61 56 octets

La fonction randomIO :: IO Floatproduit des nombres aléatoires dans l'intervalle [0,1) , donc les transformer en utilisant x -> 1/(1-x)produira des réalisations pareto.

import System.Random
randomIO>>=print.(1/).((1::Float)-)

Essayez-le en ligne!


Le déplacement de l'annotation de type permet d'économiser quelques octets:randomIO>>=print.((1::Float)/)
Laikoni

Et comme les fonctions sont autorisées, je dirais que vous pouvez supprimer le main=.
Laikoni

Apparemment, la plage est [0,1)conforme à cette réponse
flawr

@flawr Oups, vous avez raison! J'ai oublié comment les flotteurs fonctionnent temporairement.
Mego

Eh bien de toute façon, merci pour les commentaires, je n'aurais pas eu la moindre idée :)
flawr


3

Mathematica, 10 octets

1/Random[]

Essayez-le en ligne!

-4 octets de M.Stern


2
Cela a le potentiel d'échouer, car RandomRealgénère un nombre réel dans la plage fermée [0, 1]. Ainsi, la division par 0 est possible. Vous devrez manipuler la valeur aléatoire afin d'éliminer cette possibilité.
Mego

2
@Mego où exactement avez-vous trouvé cette information?
J42161217

1
@Mego quelle est la probabilité d'obtenir 0?
J42161217

4
Jenny_mathy: Selon la proposition sur la méta, the burden of proof should be on the person claiming to have a valid answer- c'est votre travail de prouver qu'elle est valide, pas de demander à @Mego de fournir un cas de test invalide. De plus, comme float sont discrets, la probabilité d'obtenir 0 est non nulle.
user202729

1
Revenons au sujet, je ne pense pas qu'il y ait une possibilité d'obtenir un zéro en utilisant cette fonction. Mathematica produira en fait des nombres inférieurs à $MinMachineNumber. Essayez ceci: Table[RandomReal[{0, $MinMachineNumber}], 100]. Il s'avère que Mathematica est suffisamment intelligent pour abandonner les numéros de machine et passer à des nombres de précision arbitraires. LOL.
Kelly Lowder

2

Rubis, 14 8 octets

p 1/rand

Programme trivial, je ne pense pas qu'il puisse être plus court.


Note à tout le monde: issacg a ajouté quelques règles qui permettent certaines imprécisions, donc la plupart des réponses ici sont plus longues que nécessaire.
user202729

2

Excel VBA, 6 octets

Fonction de fenêtre immédiate VBE anonyme qui ne prend aucune entrée et sortie dans la fenêtre immédiate VBE

?1/Rnd

1

Python , 41 octets

lambda:1/(1-random())
from random import*

Essayez-le en ligne!


L'utilisation de la fonction intégrée est en fait plus longue:

Python , 43 octets

lambda:paretovariate(1)
from random import*

Essayez-le en ligne!

Les deux solutions fonctionnent à la fois dans Python 2 et Python 3.


1
Les programmes complets sont plus courts pour les tâches qui n'utilisent pas d'entrée, en utilisant printenregistre un octet.
Erik the Outgolfer

1

J , 5 octets

%-.?0

Comment ça marche:

?0 génère une valeur aléatoire supérieure à 0 et inférieure à 1

-. soustraire de 1

% réciproque

Essayez-le en ligne!


Note à tout le monde: issacg a ajouté quelques règles qui permettent certaines imprécisions, donc la plupart des réponses ici sont plus longues que nécessaire.
user202729


1

APL (Dyalog) , 5 octets

÷1-?0

Essayez-le en ligne!

Comment?

 ÷   1-     ?0
1÷  (1-  random 0..1)

Note à tout le monde: issacg a ajouté quelques règles qui permettent certaines imprécisions, donc la plupart des réponses ici sont plus longues que nécessaire.
user202729

1

Japt , 6 octets

1/1-Mr est la même longueur mais cela semblait un peu moins ennuyeux!

°T/aMr

Essayez-le


Explication

Incrémentez ( °) zéro ( T) et divisez par ( /) sa différence absolue ( a) avec Math.random().


Note à tout le monde: issacg a ajouté quelques règles qui permettent certaines imprécisions, donc la plupart des réponses ici sont plus longues que nécessaire.
user202729

1

Gelée , 5 octets

Jelly n'a pas non plus de flottant aléatoire, donc cela utilise x/nxest un entier aléatoire dans la plage [1, n](inclus) pour émuler un flottant aléatoire dans la plage (0, 1]. Dans ce programme nest réglé pour être .108

ȷ8µ÷X

Essayez-le en ligne!

Explication

ȷ8     Literal 10^8.
  µ    New monad.
   ÷   Divide by
    X  random integer.

Inscrire , 3 octets

ØXİ

Essayez-le en ligne!

Enlist bat Jelly! (TI-Basic pas encore)

Explication

  İ    The inverse of...
ØX     a random float in [0, 1)

Bien sûr, cela a une probabilité non nulle de prendre l'inverse de 0.


La solution Enlist n'échouerait-elle pas si elle était ØXretournée 0? (Avertissement: Je ne sais pas du tout enrôler!)
Shaggy

@Shaggy your program must output a number greater than or equal to 1 with at least probability 0.999. The rest of the time it may crash(d'après les règles du défi)
user202729

1

Formule IBM / Lotus Notes, 13 octets

1/(1-@Random)

Échantillon (10 séries)

enter image description here


Note à tout le monde: issacg a ajouté quelques règles qui permettent certaines imprécisions, donc la plupart des réponses ici sont plus longues que nécessaire.
user202729

Je ne suis pas sûr que je pourrais rendre cela beaucoup plus court quelles que soient les modifications apportées aux règles :)
ElPedro


1

JavaScript REPL, 15 19 octets

1/Math.random()

3
Cela ne donnera pas de résultats corrects si Math.random() renvoie 0
M. Xcoder

1
Probablement 1/(1-Math.random())?
user202729

Correction en utilisant la solution de u * 29
l4m2

Vous avez besoin _=>au début pour en faire une fonction; les extraits ne sont pas autorisés.
Shaggy

C'est un programme complet utilisant la console en cours d'exécution
l4m2


0

J, 9 octets

p=:%@?@0:

Je ne pouvais pas comprendre comment le faire ne prendre aucune entrée, car p =:%? 0 serait évalué immédiatement et resterait fixe. Pour cette raison, c'est un peu long.

Comment ça marche:

p=:        | Define the verb p
       0:  | Constant function. Returns 0 regardless of input.
     ?@    | When applied to 0, returns a random float in the range (0,1)
   %@      | Reciprocal

Évalué 20 fois:

    p"0 i.20
1.27056 1.86233 1.05387 16.8991 5.77882 3.42535 12.8681 17.4852 2.09133 1.82233 2.28139 1.58133 1.79701 1.09794 1.18695 1.07028 3.38721 2.88339 2.06632 2.0793

0

Pyth , 4 octets

c1O0

Essayez-le ici!

Alternative: c1h_O0.


c1tOZest 5, ça ne marche pas?
Dave

@Dave Ne fonctionne pas, cela renvoie des valeurs négatives. Je n'ai 1-npas besoinn-1
M. Xcoder

Pyth n'a-t-il pas de constante pour 100?
Shaggy

@Shaggy Je souhaite que ce soit le cas. Malheureusement, pas de constante pour l' 100AFAIK
M. Xcoder

0

Nettoyer , 91 octets

import StdEnv,Math.Random,System.Time
Start w=1.0/(1.0-hd(genRandReal(toInt(fst(time w)))))

Clean n'aime pas les nombres aléatoires.

Parce que le générateur aléatoire (un Mersenne Twister) a besoin recevoir une valeur de départ, je dois prendre l'horodatage du système pour obtenir quelque chose qui diffère passivement par exécution, et pour faire tout ce qui concerne les E / S, je dois utiliser une Startdéclaration entière car c'est la seul endroit pour obtenir un World.

Essayez-le en ligne!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.