2015-06-08 26 views
8

Sto cercando di generare numeri interi casuali con distribuzione logaritmica. Io uso la seguente formula:Genera numeri casuali con distribuzione logaritmica e pendenza personalizzata

idx = Math.floor(Math.log((Math.random() * Math.pow(2.0, max)) + 1.0)/Math.log(2.0)); 

Questo funziona bene e produce sequenza così per 1000 iterazioni (ciascun numero rappresenta il numero di volte in cui indice è stato generato):

[525, 261, 119, 45, 29, 13, 5, 1, 1, 1] 

Fiddle

I Sto cercando ora di regolare la pendenza di questa distribuzione in modo che non diminuisca rapidamente e produca qualcosa come:

[150, 120, 100, 80, 60, ...] 

Giocare alla cieca con i coefficienti non mi dava quello che volevo. Qualche idea su come ottenerlo?

+1

imposta ogni '2.0' nella tua formula più vicino a' 1.0' e, g. '1.3' – zmii

+0

@zmii che funziona bene se' max = 10', ma se 'max = 2' produce una pendenza ancora più nitida:' [830, 170] 'vs' [744, 256] 'per' 2.0' – serg

+0

I fai in questo modo: [numeri pseudo casuali con una distribuzione predefinita] (http://stackoverflow.com/a/22422035/2521214) – Spektre

risposta

4

Si menziona una distribuzione logaritmica, ma sembra che il codice sia progettato per generare una distribuzione geometrica troncata, sebbene sia difettosa. Esiste più di una distribuzione chiamata distribuzione logaritmica e nessuna di queste è comune. Si prega di chiarire se si intende veramente uno di loro.

Calcola il piano [log_2 U] dove U è distribuito uniformemente da 1 a (2^max) +1. Questo ha un 1/2^possibilità massima di produrre max, ma lo si limita a max-1. Quindi, hai una probabilità massima di 1/2 di produrre 0, 2/2^possibilità massima di produrre 1, 4/2^possibilità massima di produrre 2, ... fino a 1/2 + 1/2^max possibilità di produrre max-1.

Presente nel codice, ma manca la descrizione in questione, è che si sta lanciando l'indice calcolato in giro con

idx = (max-idx) - 1 

Dopo questo, hai la possibilità di produrre 0 è 1/2 + 1/2^max e la tua possibilità di produrre un valore di k è 1/2^(k + 1).

Penso che sia un errore lasciare U uniforme su [1,2^max + 1]. Invece, penso che tu voglia che U sia uniforme su [1,2^max]. Quindi la tua possibilità di generare idx = k è 2^(max-k-1)/((2^max) -1).

idx = Math.floor(Math.log((Math.random()*(Math.pow(2.0, max)-1.0)) + 1.0)/Math.log(2.0)); 

commento di zmii che si potrebbe ottenere una distribuzione più piatta, sostituendo sia 2.0s con un valore più vicino a 1,0 è buono. Il motivo per cui ha prodotto risultati insoddisfacenti per piccoli valori di max è stato il campionamento in modo uniforme da [1,1.3^max + 1] invece di [1,1,3^max]. Il +1 in più ha fatto una differenza maggiore quando il massimo era più piccolo e la base era più piccola. Prova il seguente:

var zmii = 1.3; 
idx = Math.floor(Math.log((Math.random()*(Math.pow(zmii, max)-1.0))+1.0)/Math.log(zmii)); 
+0

Grazie, funziona alla grande ora. – serg