E' una domanda non banale... In prima approssimazione le funzioni che generano numeri casuali in C/C# hanno una distribuzione uniforme tra 0 e N, cioè ciascun numero tra 0 e N ha la stessa probabilità di uscire.
Supponendo di avere una sequenza di numeri xn uniformemente distribuiti nell'intervallo [0,1], puoi ricavare una nuova sequenza con la distribuzione desiderata calcolando
dove F-1(x) è l'inversa della funzione di ripartizione della distribuzione desiderata
Qui trovi la stessa spiegazione con un esempio riguardante la distribuzione esponenziale (che potrebbe andare bene nel tuo caso come puoi vedere da qui:
)
Se vuoi fare qualcosa di più semplice, invece, potresti pensare i tuoi numeri da estrarre come una sequenza ordinata di numeri che appaiono in "quantità" diversa. Per esempio supponiamo di voler estrarre un numero compreso tra [0,N]; puoi immaginarti la sequenza come una cosa di questo tipo (non andremo a memorizzarla in un array... serve solo per capire meglio; come vedrai dopo, nelle formule non ci sono riferimenti alla sequenza)
quello che faremo è andare ad
estrarre una posizione X a caso
tra [0,(N+1)*N/2-1] -> formula di Gauss per trovare il limite superiore
Il
numero estratto sarà
N-floor((sqrt(8*X-1)-1)/2) per
X!=0, altrimenti
N per
X=0
NB per floor intendo l'arrotondamento all'intero precedente e per sqrt la radice quadrata (la formula è tratta dalle proprietà dei numeri triangolari:
)