Prova la distribuzione di Pareto


22

La distribuzione di Pareto è una distribuzione di probabilità che emerge molto in natura. Ha molte proprietà speciali, come una media infinita. In questa sfida, verrà emesso un numero campionato da questa distribuzione.

La distribuzione di Pareto è definita come maggiore o uguale a xcon probabilità 1/x, per tutti xmaggiori o uguali a 1.

Pertanto, un numero campionato da questa distribuzione è maggiore o uguale a 1 con probabilità 1, maggiore o uguale a 2 con probabilità esattamente 1/2, maggiore o uguale a 3 con probabilità esattamente 1/3, maggiore o uguale a 11.4 con probabilità esattamente 1 / 11.4 e così via.

Poiché campionerai questa distribuzione, il tuo programma o funzione non accetterà alcun input e produrrà un numero casuale, con le probabilità di cui sopra. Tuttavia, se il tuo programma non corrisponde perfettamente alle probabilità di cui sopra a causa dell'impressione in virgola mobile, va bene. Vedi il fondo della sfida per maggiori dettagli.

(Questa è chiamata distribuzione di Pareto con alfa 1 e limite inferiore 1, per l'esattezza)

Ecco 10 esempi tratti da questa distribuzione:

1.1540029602790338
52.86156818209856
3.003306506971116
1.4875532217142287
1.3604286212876546
57.5263129600285
1.3139866916055676
20.25125817471419
2.8105749663695208
1.1528212409680156

Nota come 5 di questi sono inferiori a 2 e 5 superiori a 2. Dato che questo è il risultato medio, ovviamente avrebbe potuto essere più alto o più basso.

La tua risposta deve solo essere corretta fino ai limiti del tipo a virgola mobile, del tipo di numero reale o di qualsiasi altra cosa tu usi, ma devi essere in grado di rappresentare numeri con almeno 3 cifre decimali di precisione e rappresentare numeri fino a 1.000.000 . Se non sei sicuro che qualcosa vada bene, non esitare a chiedere.

Questo è il codice golf.


Dettagli sull'imprecisione:

  • Per ogni intervallo [a, b], dove 1 <= a < b, la probabilità ideale che il campione rientri in quell'intervallo è 1/a - 1/b. La probabilità che il programma produce un numero in tale intervallo deve essere con 0.001del 1/a - 1/b. Se Xè l'output del tuo programma, è necessario che |P(a <= X <= b) - (1/a - 1/b)| < 0.001.

  • Nota che applicando la regola sopra con a=1e bsufficientemente grande, è il caso che il tuo programma debba generare un numero maggiore o uguale a 1 con almeno probabilità 0,999. Il resto del tempo potrebbe arrestarsi in modo anomalo, produrre Infinityo fare qualsiasi altra cosa.

Sono abbastanza certo che gli invii esistenti del modulo 1/1-xo 1/x, dove si xtrova un float casuale in [0, 1)o (0, 1)o [0, 1], soddisfano tutti questo requisito.



2
Nota a tutti: issacg ha aggiunto alcune regole che consentono alcune imprecisioni, quindi la maggior parte delle risposte qui sono più lunghe del necessario. [scusate anche per l'abuso di commenti, ma è quello che succederebbe se OP cambiasse in modo significativo la domanda]
user202729

Risposte:




5

R, 10 byte

1/runif(1)

Abbastanza diretto.


2
Si noti che runif non restituisce mai 0 o 1 nel caso predefinito, quindi non ci sono problemi con questo.
Giuseppe,

Sì grazie. E non ci ho pensato quando ho inserito questa risposta, ma puoi effettivamente verificare la distribuzione se necessario.
plannapus

2
@Mego che non è corretto. La distribuzione di Pareto è assolutamente continua e quindi ha la misura 0 per qualsiasi numero.
Therkel,

3
@Mego OK che potrebbe essere sabbie mobili per me (dato che non conosco quasi nulla sul punto in virgola mobile), ma in realtà penso che mentre la probabilità di runifdare 1 è nulla, la probabilità di 1/runifdare 1 non lo è, a causa della precisione in virgola mobile ( cioè tipicamente 1 / 0.9999999 restituisce 1 in R).
plannapus,

1
@plannapus Hmm ... Questo è un buon punto. I galleggianti lo rendono del tutto troppo complicato.
Mego

4

TI-Basic, 2 byte

rand^-1      (AB 0C in hex)

Per chiunque si stia chiedendo, randrestituisce un valore casuale in (0,1]. "A causa delle specifiche dell'algoritmo di generazione di numeri casuali, il numero più piccolo possibile da generare è leggermente maggiore di 0. Il numero più grande possibile è in realtà 1 ... "( fonte ). Ad esempio, il seeding rand con 196164532 produce 1.


Stranamente, il codice equivalente non funzionerebbe su una calcolatrice della serie TI-89. Anche se i loro generatori di numeri casuali sono implementati in modo quasi identico, una TI-89 restituirà 0 ogni volta che una TI-83 + restituirà 0.99999999999889.
Misha Lavrov,

2
Gli sviluppatori di TI-Basic sapevano in anticipo che questa sfida si sarebbe verificata ...? Sembra vincere questa volta.
user202729

@ user202729 Evitare 0 e 1 rende randpiù utile come subroutine per gli altri comandi della calcolatrice, motivo per cui TI ha preso questa decisione di progettazione. Ad esempio, randNorm(0,1restituisce -7.02129...con seed 196164532. L'uso dell'algoritmo RNG senza la regolazione darebbe un valore di 1e99, che è un valore irragionevole per una variabile normalmente distribuita.
Misha Lavrov,

@ user202729 Sì, in realtà ho appena viaggiato un po 'per fare tutto. Ne vale la pena per questi voti.
Timtech,

4

R , 12 byte

exp(rexp(1))

Provalo online!

Verifica la distribuzione

Questo adotta un approccio diverso, sfruttando il fatto che if Y~exp(alpha), quindi X=x_m*e^Yè un Pareto con parametri x_m,alpha. Poiché entrambi i parametri sono 1 e il parametro di velocità predefinito per rexpè 1, ciò comporta la distribuzione di Pareto appropriata.

Mentre questa risposta è un approccio abbastanza specifico per la R, è purtroppo meno goloso di quello del plannapus .

R , 14 byte

1/rbeta(1,1,1)

Provalo online!

Ancora meno golfy, ma un altro modo di ottenere la risposta.

Un'altra proprietà della distribuzione esponenziale è che if X ~ Exp(λ) then e^−X ~ Beta(λ, 1), quindi 1/Beta(1,1)è a Pareto(1,1).

Inoltre, un acuto osservatore ricorderebbe che se X ~ Beta(a,b)e a=b=1, quindi X~Unif(0,1), lo è davvero 1/runif(1).


Non ne ho idea. Ma la realtà è che c'è un'enorme confusione su ciò che è permesso e ciò che non è in questa sfida.
user202729

@ user202729 è giusto, ma quelli che hanno sollevato preoccupazioni al riguardo avrebbero almeno commentato, quindi è improbabile che il downvote (a mio avviso) sia correlato a questo. EDIT: il misterioso downvoter ha rimosso il downvote.
Giuseppe,

Ho annullato il voto perché pensavo che usare R su una sfida come questa fosse banale, ma ero un po 'contento. Mi rendo conto che questo utilizza un metodo diverso rispetto alla maggior parte delle altre risposte, quindi ho rimosso il mio voto negativo.
KSmarts,

@KSmarts La risposta "banale" in R non è stata utilizzata da nessuno in realtà actuar::rpareto(1,1,1)
:,

Per info, ci sono ca. 20 distribuzioni hardcoded nella base R, ma Pareto non è una di queste, quindi la necessità di utilizzare un work-around o un pacchetto aggiuntivo.
plannapus,

3

Carbone , 10 byte

I∕Xφ²⊕‽Xφ²

Provalo online!

Il collegamento è alla versione dettagliata:

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

Commenti:

  • Il carbone ha solo metodi per ottenere numeri interi casuali, quindi per ottenere un numero a virgola mobile casuale tra 0 e 1 dobbiamo ottenere un numero intero casuale tra 0 e N e dividere per N.
  • Versione precedente di questa risposta che utilizzava la 1/(1-R)formula: In questo caso, N è impostato su 1000000 poiché l'OP chiede che sia il minimo. Per ottenere questo numero, Carbone fornisce una variabile preimpostata f= 1000. Quindi solo calcolando f^2otteniamo 1000000. Nel caso in cui il numero casuale sia 999999 (il massimo),1/(1-0.999999)=1000000 .
  • Il suggerimento di Neil (risparmio di 3 byte): se ho 1/(1-R/N)dove Rè un numero casuale compreso tra 0 e N, è lo stesso che calcolare N/(N-R). Ma considerando che gli interi casuali N-Re Rhanno la stessa probabilità di verificarsi, è uguale al solo calcolo N/R(essendo Rin quest'ultimo caso un numero compreso tra 1 e N compreso per evitare la divisione per zero).


@Neil, per favore, aspetta un momento mentre provo a capire cosa fa il tuo codice ... :-)
Charlie,

In realtà non ho bisogno di MapAssignRightpiù, 10 byte! lavori.
Neil,

@ Assimilazione del codice completata! Risposta modificata. MrGreen
Charlie il

3

Haskell , 61 56 byte

La funzione randomIO :: IO Floatproduce numeri casuali nell'intervallo [0,1) , quindi trasformarli usando x -> 1/(1-x)produrrà realizzazioni pareto.

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

Provalo online!


Lo spostamento dell'annotazione del tipo consente di risparmiare alcuni byte:randomIO>>=print.((1::Float)/)
Laikoni il

E poiché le funzioni sono consentite, direi che puoi eliminare main=.
Laikoni,

Approssimativamente la gamma è [0,1)secondo questa risposta
flawr

@flawr Whoops, hai ragione! Ho dimenticato come funzionano temporaneamente i float.
Mego

Bene comunque, grazie per il commento, non avrei avuto idea :)
flawr

3

Excel, 9 byte

=1/rand()

Sì, Excel è (semi) competitivo per un cambiamento!


Funziona anche in LibreOffice Calc :)
ElPedro il

Puoi cambiarlo in fogli di Google per -1 byte ( =1/Rand()
Taylor Scott

3

Mathematica, 10 byte

1/Random[]

Provalo online!

-4 byte da M.Stern


2
Questo ha il potenziale di fallire, perché RandomRealgenera un numero reale nell'intervallo chiuso [0, 1]. Pertanto, la divisione per 0 è possibile. Dovrai manipolare il valore casuale per rimuovere quella possibilità.
Mego

2
@Mego dove hai trovato esattamente queste informazioni?
J42161217,

1
@Mego qual è la probabilità di ottenere 0?
J42161217

4
Jenny_mathy: Secondo la proposta su meta, the burden of proof should be on the person claiming to have a valid answer- è il tuo lavoro dimostrare che è valido, non chiedere a @Mego di fornire un caso di test non valido. Anche perché i float sono discreti, la probabilità di ottenere 0 è diversa da zero.
user202729

1
Tornando all'argomento, non credo che ci sia la possibilità di ottenere uno zero usando questa funzione. Mathematica produrrà infatti numeri inferiori a $MinMachineNumber. Prova questo: Table[RandomReal[{0, $MinMachineNumber}], 100]. Si scopre che Mathematica è abbastanza intelligente da abbandonare i numeri delle macchine e passare a numeri di precisione arbitrari. LOL.
Kelly Lowder,

2

Rubino, 14 8 byte

p 1/rand

Programma di prova, non credo che possa essere più breve.


Nota a tutti: issacg ha aggiunto alcune regole che consentono alcune imprecisioni, quindi la maggior parte delle risposte qui sono più lunghe del necessario.
user202729

2

Excel VBA, 6 byte

Funzione di finestra immediata VBE anonima che non accetta input e output nella finestra immediata di VBE

?1/Rnd

1

Python , 41 byte

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

Provalo online!


L'uso del built-in è in realtà più lungo:

Python , 43 byte

lambda:paretovariate(1)
from random import*

Provalo online!

Entrambe le soluzioni funzionano sia in Python 2 che in Python 3.


1
I programmi completi sono più brevi per le attività che non usano l'input, usando printsalva un byte.
Erik the Outgolfer,

1

J , 5 byte

%-.?0

Come funziona:

?0 genera un valore casuale maggiore di 0 e inferiore a 1

-. sottrai da 1

% reciproco

Provalo online!


Nota a tutti: issacg ha aggiunto alcune regole che consentono alcune imprecisioni, quindi la maggior parte delle risposte qui sono più lunghe del necessario.
user202729


1

APL (Dyalog) , 5 byte

÷1-?0

Provalo online!

Come?

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

Nota a tutti: issacg ha aggiunto alcune regole che consentono alcune imprecisioni, quindi la maggior parte delle risposte qui sono più lunghe del necessario.
user202729

1

Japt , 6 byte

1/1-Mr è della stessa lunghezza ma questo sembra un po 'meno noioso!

°T/aMr

Provalo


Spiegazione

Incrementa ( °) zero ( T) e dividi per ( /) la sua differenza assoluta ( a) con Math.random().


Nota a tutti: issacg ha aggiunto alcune regole che consentono alcune imprecisioni, quindi la maggior parte delle risposte qui sono più lunghe del necessario.
user202729

1

Gelatina , 5 byte

Jelly inoltre non ha un float casuale, quindi questo usa x/ndove xc'è un intero casuale nel range [1, n](incluso) per emulare un float casuale nel range (0, 1]. In questo programma nè impostato per essere .108

ȷ8µ÷X

Provalo online!

Spiegazione

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

Enlist , 3 byte

ØXİ

Provalo online!

Enlist batte Jelly! (TI-Basic non ancora)

Spiegazione

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

Naturalmente questo ha una probabilità diversa da zero di prendere l'inverso di 0.


La soluzione Enlist non fallirebbe se ØXrestituita 0? (Dichiarazione di non responsabilità: non conosco affatto la lista!)
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(dalle regole della sfida)
user202729

1

Formula IBM / Lotus Notes, 13 byte

1/(1-@Random)

Esempio (10 corse)

inserisci qui la descrizione dell'immagine


Nota a tutti: issacg ha aggiunto alcune regole che consentono alcune imprecisioni, quindi la maggior parte delle risposte qui sono più lunghe del necessario.
user202729

Non sono sicuro che potrei accorciare le modifiche alle regole :)
ElPedro il


1

JavaScript REPL, 15 19 byte

1/Math.random()

3
Questo non produrrà risultati corretti se Math.random() restituisce 0
Mr. Xcoder il

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

Risolto usando la soluzione di u * 29
l4m2 il

È necessario _=>all'inizio per rendere questa una funzione; gli snippet non sono ammessi.
Shaggy,

È un programma completo che utilizza la console in esecuzione
l4m2 il


0

J, 9 byte

p=:%@?@0:

Non sono riuscito a capire come fare in modo che non richieda alcun input, poiché p =:%? 0 valuterebbe immediatamente e rimarrebbe fisso. Per questo motivo è un po 'lungo.

Come funziona:

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

Valutato 20 volte:

    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

Pulito , 91 byte

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

A Clean non piacciono i numeri casuali.

Poiché al generatore casuale (un Mersenne Twister) deve essere assegnato un seme, devo prendere il timestamp del sistema per ottenere qualcosa che differisca passivamente per ogni esecuzione e per fare qualsiasi cosa relativa all'IO ho bisogno di usare un'intera Startdichiarazione perché è il unico posto per ottenere aWorld .

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.