Scegliere n numeri con sum fissa

In alcuni codici voglio scegliere n numeri casuali in [0,1) che sumno a 1 .

Lo faccio scegliendo i numeri in modo indipendente in [0,1) e normalizzandoli dividendo ciascuno per la sum totale:

 numbers = [random() for i in range(n)] numbers = [n/sum(numbers) for n in numbers] 

Il mio “problema” è che la distribuzione che ottengo è abbastanza distorta. Scegliendo un milione di numeri non uno solo diventa 1/2 . Con qualche sforzo ho calcolato il pdf, e non è bello.

Ecco il pdf dall’aspetto strano che ottengo per 5 variabili:

inserisci la descrizione dell'immagine qui

Hai un’idea per un buon algoritmo per scegliere i numeri, che si traduce in una distribuzione più uniforms o semplice?

Stai cercando di suddividere la distanza da 0 a 1.

Scegliere n – 1 numeri da 0 a 1, ordinarli e determinare le distanze tra ciascuno di essi.

Questo dividerà lo spazio da 0 a 1, il che dovrebbe produrre il risultato occasionale di grandi dimensioni che non si ottiene.

Anche così, per valori elevati di n, puoi generalmente aspettarti che anche il tuo valore massimo diminuisca, ma non altrettanto rapidamente quanto il tuo metodo.

Potresti essere interessato alla distribuzione di Dirichlet che viene utilizzata per generare quantità pari a 1 se stai cercando probabilità. C’è anche una sezione su come generarli usando le distribuzioni gamma qui .

Un altro modo per ottenere n numeri casuali che ammontano a 1:

 import random def create_norm_arr(n, remaining=1.0): random_numbers = [] for _ in range(n - 1): r = random.random() # get a random number in [0, 1) r = r * remaining remaining -= r random_numbers.append(r) random_numbers.append(remaining) return random_numbers random_numbers = create_norm_arr(5) print(random_numbers) print(sum(random_numbers)) 

Ciò rende più probabili i numeri più alti.