Amostra da distribuição Pareto


22

A distribuição de Pareto é uma distribuição de probabilidade que surge muito na natureza. Possui muitas propriedades especiais, como uma média infinita. Neste desafio, você produzirá um número amostrado dessa distribuição.

A Distribuição de Pareto é definida como maior ou igual a xcom probabilidade 1/x, para todos xmaiores ou iguais a 1.

Portanto, um número amostrado dessa distribuição é maior ou igual a 1 com probabilidade 1, maior ou igual a 2 com probabilidade exatamente 1/2, maior ou igual a 3 com probabilidade exatamente 1/3, maior ou igual a 11.4 com probabilidade exatamente 1/11.4, e assim por diante.

Como você fará uma amostra dessa distribuição, seu programa ou função não receberá nenhuma entrada e emitirá um número aleatório, com as probabilidades acima. No entanto, se o seu programa não corresponder perfeitamente às probabilidades acima devido à impressão de ponto flutuante, tudo bem. Veja o final do desafio para mais detalhes.

(Isso é chamado de Distribuição de Pareto com alfa 1 e limite inferior 1, para ser exato)

Aqui estão 10 exemplos desta distribuição:

1.1540029602790338
52.86156818209856
3.003306506971116
1.4875532217142287
1.3604286212876546
57.5263129600285
1.3139866916055676
20.25125817471419
2.8105749663695208
1.1528212409680156

Observe como 5 deles estão abaixo de 2 e 5 estão acima de 2. Como esse é o resultado médio, poderia ter sido maior ou menor, é claro.

Sua resposta só precisa estar correta até os limites do seu tipo de ponto flutuante, número real ou qualquer outra coisa que você usar, mas você deve ser capaz de representar números com pelo menos três dígitos decimais de precisão e representar até 1.000.000 . Se você não tiver certeza se algo está bem, não hesite em perguntar.

Isso é código de golfe.


Detalhes sobre imprecisão:

  • Para cada intervalo [a, b], onde1 <= a < b a probabilidade ideal de que a amostra caia nesse intervalo 1/a - 1/b. A probabilidade de seu programa produzir um número nesse intervalo deve estar com 0.001de 1/a - 1/b. Se Xé a saída do seu programa, é necessário isso |P(a <= X <= b) - (1/a - 1/b)| < 0.001.

  • Observe que, ao aplicar a regra acima com a=1e bsuficientemente grande, é possível que seu programa produza um número maior ou igual a 1 com pelo menos probabilidade 0,999. O resto do tempo pode travar, gerar saída Infinityou fazer o que mais.

Estou bastante certo de que os envios existentes do formulário 1/1-xou 1/x, onde xhá uma flutuação aleatória no [0, 1)ou(0, 1) ou [0, 1], todos atendem a esse requisito.



2
Nota para todos: issacg adicionou algumas regras que permitem algumas imprecisões; portanto, a maioria das respostas aqui são mais longas que o necessário. [pena de comentário sobre abuso também, mas isso é o que aconteceria quando a pergunta mudança OP significativamente]
user202729

Respostas:




5

R, 10 bytes

1/runif(1)

Bem direto.


2
Observe que runif nunca retorna 0 ou 1 no caso padrão, portanto, não há problemas com isso.
Giuseppe

Sim obrigado. E não pensei nisso ao inserir esta resposta, mas é possível verificar a distribuição, se necessário.
plannapus

2
@ Megego está incorreto. A distribuição de Pareto é absolutamente contínua e, portanto, possui a medida 0 para qualquer número.
Therkel # 15/17

3
@Mego OK, que pode ser areia movediça para mim (dado que não sei quase nada sobre ponto flutuante), mas acho que, embora a probabilidade de runifdar 1 seja nula, a probabilidade de 1/runifdar 1 não é, devido à precisão do ponto flutuante ( ie tipicamente 1 / 0.9999999 retorna 1 em R).
plannapus

1
@ plannapus Hmm ... Esse é um bom ponto. Os carros alegóricos tornam isso muito complicado.
Mego

4

TI-Basic, 2 bytes

rand^-1      (AB 0C in hex)

Para quem está se perguntando, randretorna um valor aleatório em (0,1]. "Devido às especificidades do algoritmo de geração de número aleatório, o menor número possível de gerar é um pouco maior que 0. O maior número possível é realmente 1 ... "( origem ). Por exemplo, semear rand com 196164532 produz 1.


Estranhamente, o código equivalente não funcionaria em uma calculadora da série TI-89. Embora seus geradores de números aleatórios sejam quase idênticos, um TI-89 retornará 0 sempre que um TI-83 + retornar 0,99999999999889.
Misha Lavrov

2
Os desenvolvedores da TI-Basic sabiam com antecedência que esse desafio aconteceria ...? Parece ganhar desta vez.
user202729

@ user202729 Evitar 0 e 1 torna randmais útil como sub-rotina para os outros comandos da calculadora, e é provavelmente por isso que a TI tomou essa decisão de design. Por exemplo, randNorm(0,1retorna -7.02129...com a semente 196164532. O uso do algoritmo RNG sem o ajuste forneceria um valor de 1e99, que é um valor irracional para uma variável normalmente distribuída.
Misha Lavrov

@ user202729 Sim, na verdade eu apenas viajei um pouco para fazer tudo. Definitivamente vale a pena por esses votos positivos.
Timtech

4

R , 12 bytes

exp(rexp(1))

Experimente online!

Verifique a distribuição

Isso adota uma abordagem diferente, explorando o fato de que se Y~exp(alpha), então, X=x_m*e^Yé um Pareto com parâmetros x_m,alpha. Como os dois parâmetros são 1, e o parâmetro de taxa padrão pararexp 1, isso resulta na distribuição Pareto apropriada.

Embora essa resposta seja uma abordagem bastante específica para R, infelizmente é menos eficiente do que a do plannapus .

R , 14 bytes

1/rbeta(1,1,1)

Experimente online!

Ainda menos golfe, mas outra maneira de obter a resposta.

Outra propriedade da distribuição exponencial é que se X ~ Exp(λ) then e^−X ~ Beta(λ, 1), portanto, 1/Beta(1,1)é a Pareto(1,1).

Além disso, um observador atento lembraria que se X ~ Beta(a,b)e a=b=1, então,X~Unif(0,1) , é verdade 1/runif(1).


Eu não faço ideia. Mas a realidade é que há uma enorme confusão sobre o que é permitido e o que não está nesse desafio.
user202729

@ user202729 isso é justo, mas aqueles que têm levantado preocupações com relação a isso pelo menos teriam comentado, então o voto negativo é (na minha opinião) improvável que esteja relacionado a isso. EDIT: o downvoter misterioso removeu o voto negativo.
Giuseppe

Fiz uma votação baixa porque pensei que usar R em um desafio como esse era trivial, mas fiquei um pouco satisfeito. Percebo que isso usa um método diferente do que a maioria das outras respostas, então removi meu voto negativo.
KSmarts

@KSmarts A resposta "trivial" em R não foi usada por ninguém na verdade: actuar::rpareto(1,1,1)porque é mais longa :)
plannapus

Para informações, existem ca. 20 distribuições codificadas na base R, mas Pareto não é uma delas, daí a necessidade de usar uma solução alternativa ou um pacote adicional.
plannapus

3

Carvão , 10 bytes

I∕Xφ²⊕‽Xφ²

Experimente online!

O link é para a versão detalhada:

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

Comentários:

  • O carvão vegetal possui apenas métodos para obter números inteiros aleatórios; portanto, para obter um número aleatório de ponto flutuante entre 0 e 1, precisamos obter um número inteiro aleatório entre 0 e N e dividir por N.
  • Versão anterior desta resposta que usou a 1/(1-R)fórmula: Nesse caso, N é definido como 1000000, pois o OP solicita que seja o mínimo. Para obter esse número, o Charcoal fornece uma variável predefinida f= 1000. Então, apenas calculando f^2, obtemos 1000000. No caso de o número aleatório ser 999999 (o máximo) 1/(1-0.999999)=1000000,.
  • Ponta de Neil (poupança de 3 bytes): Se tiver 1/(1-R/N)onde Ré um número aleatório entre 0 e N, que é o mesmo que apenas calcular N/(N-R). Mas, considerando que os números inteiros aleatórios N-Re Rtêm a mesma probabilidade de ocorrer, que é o mesmo que apenas calcular N/R(sendo Rneste último caso um número entre 1 e N inclusive a divisão evitar por zero).


@Neil por favor aguarde um momento, enquanto eu tento entender o que seu código faz ... :-)
Charlie

Na verdade, não preciso MapAssignRightmais, 10 bytes! trabalho.
Neil

@ Neil assimilação do seu código concluída! Resposta editada. :-D
Charlie

3

Haskell , 61 56 bytes

A função randomIO :: IO Floatproduz números aleatórios no intervalo [0,1) , portanto, transformá-los usando x -> 1/(1-x)produzirá realizações de pareto.

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

Experimente online!


Mover a anotação de tipo salva alguns bytes:randomIO>>=print.((1::Float)/)
Laikoni

E como as funções são permitidas, eu diria que você pode largar o main=.
Laikoni

Apranetly, o intervalo está de [0,1)acordo com esta resposta #
flawr

@ Flawr Opa, você está certo! Esqueci como os carros alegóricos funcionam temporariamente.
Mego

Bem de qualquer maneira, obrigado por comentar, eu não teria tido qualquer ideia :)
flawr

3

Excel, 9 bytes

=1/rand()

Sim, o Excel é (semi-) competitivo para variar!


Também funciona no LibreOffice Calc :)
ElPedro

Você pode alterar isso no google sheets para -1 Bytes ( =1/Rand()
Taylor Scott

3

Mathematica, 10 bytes

1/Random[]

Experimente online!

-4 bytes de M.Stern


2
This has the potential to fail, because RandomReal outputs a real number in the closed range [0, 1]. Thus, division by 0 is possible. You’ll need to manipulate the random value in order to remove that possibility.
Mego

2
@Mego where exactly did you find that info?
J42161217

1
@Mego what is the probability to get 0?
J42161217

4
Jenny_mathy: According to the proposal on meta, the burden of proof should be on the person claiming to have a valid answer - it's your work to prove that it's valid, not to ask @Mego to provide an invalid test case. Also because float are discrete the probability to get 0 is nonzero.
user202729

1
Back to the topic, I do not believe there is a possibility of getting a zero using this function. Mathematica will in fact produce numbers less than $MinMachineNumber. Try this: Table[RandomReal[{0, $MinMachineNumber}], 100]. Turns out Mathematica is smart enough to abandon machine numbers and switch over to arbitrary precision numbers. LOL.
Kelly Lowder

2

Ruby, 14 8 bytes

p 1/rand

Trivial program, I don't think it can get any shorter.


Note to everyone: issacg has added some rules that allow some imprecisions, therefore most answers here are longer than necessary.
user202729

2

Excel VBA, 6 Bytes

Anonymous VBE immediate window function that takes no input and outputs to the VBE immediate window

?1/Rnd

1

Python, 41 bytes

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

Try it online!


Using the builtin is actually longer:

Python, 43 bytes

lambda:paretovariate(1)
from random import*

Try it online!

Both solutions work in both Python 2 and Python 3.


1
Full programs are shorter for tasks which don't use input, using print saves a byte.
Erik the Outgolfer

1

J, 5 bytes

%-.?0

How ot works:

?0 generates a random value greater than 0 and less than 1

-. subtract from 1

% reciprocal

Try it online!


Note to everyone: issacg has added some rules that allow some imprecisions, therefore most answers here are longer than necessary.
user202729



1

Japt, 6 bytes

1/1-Mr is the same length but this felt a little less boring!

°T/aMr

Try it


Explanation

Increment (°) zero (T) and divide by (/) its absolute difference (a) with Math.random().


Note to everyone: issacg has added some rules that allow some imprecisions, therefore most answers here are longer than necessary.
user202729

1

Jelly, 5 bytes

Jelly also doesn't have random float, so this uses x/n where x is an random integer in range [1, n] (inclusive) to emulate a random float in range (0, 1]. In this program n is set to be 108.

ȷ8µ÷X

Try it online!

Explanation

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

Enlist, 3 bytes

ØXİ

Try it online!

Enlist beats Jelly! (TI-Basic not yet)

Explanation

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

Of course this has nonzero probability of take the inverse of 0.


Would the Enlist solution not fail if ØX returned 0? (Disclaimer: I don't know Enlist at all!)
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 (from the challenge rules)
user202729

1

IBM/Lotus Notes Formula, 13 bytes

1/(1-@Random)

Sample (10 runs)

enter image description here


Note to everyone: issacg has added some rules that allow some imprecisions, therefore most answers here are longer than necessary.
user202729

Not sure I could make this much shorter whatever rule changes are made :)
ElPedro


1

JavaScript REPL, 15 19 bytes

1/Math.random()

3
This will not yield correct results if Math.random() returns 0
Mr. Xcoder

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

Fixed using u*29's solution
l4m2

You need _=> at the start to make this a function; snippets aren't allowed.
Shaggy

It's a full program using console running
l4m2


0

J, 9 Bytes

p=:%@?@0:

I couldn't figure out how to make it take no input, since p=:%?0 would evaluate immediately and remain fixed. Because of this its sort of long.

How it works:

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

Evaluated 20 times:

    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

Clean, 91 bytes

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

Clean doesn't like random numbers.

Because the random generator (a Mersenne Twister) needs to be given a seed, I have to take the system timestamp to get something that differs passively per-run, and to do anything IO-related I need to use a whole Start declaration because it's the only place to obtain a World.

Try it online!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.