Wie generiere ich Zahlen gemäß einer Soliton-Verteilung?

10

Die Soliton-Verteilung ist eine diskrete Wahrscheinlichkeitsverteilung über eine Menge mit der Wahrscheinlichkeitsmassenfunktion{1,,N}

p(1)=1N,p(k)=1k(k1)for k{2,,N}

Ich möchte es als Teil einer Implementierung eines LT-Codes verwenden , idealerweise in Python, wo ein einheitlicher Zufallszahlengenerator verfügbar ist.

Alex Chamberlain
quelle

Antworten:

9

Wenn wir bei , ist das Summen-Teleskop für die (modifizierte) CDF. Wenn Sie dies invertieren und sich um den Sonderfall kümmern , erhalten Sie den folgenden Algorithmus ( ich fürchte, codiert , aber Sie können ihn als Pseudocode für eine Python-Implementierung verwenden):1 - 1 / k k = 1k=211/kk=1R

rsoliton <- function(n.values, n=2) {
  x <- runif(n.values)         # Uniform values in [0,1)
  i <- ceiling(1/x)            # Modified soliton distribution
  i[i > n] <- 1                # Convert extreme values to 1
  i
}

Als Beispiel für seine Verwendung (und einen Test) zeichnen wir Werte für : N = 10105N=10

n.trials <- 10^5
i <- rsoliton(n.trials, n=10)
freq <- table(i) / n.trials  # Tabulate frequencies
plot(freq, type="h", lwd=6)

Häufigkeitsverteilung

whuber
quelle
1
Für die damit verbundene "robuste" Solitonenverteilung müssen Sie sich wahrscheinlich mit einer etwas weniger effizienten Lösung zufrieden geben (basierend auf einer binären Suche oder einer gleichwertigen).
whuber
Wie bist du so schnell darauf gekommen?
Alex Chamberlain
2
@ Alexander Chamberlain, weil er gut ist: D
gui11aume
7

Python (angepasst an die R-Lösung von @ whuber )

from __future__ import print_function, division                                           
import random                                                                   
from math import ceil                                                           

def soliton(N, seed):                                                           
  prng = random.Random()                                                        
  prng.seed(seed)                                                                  
  while 1:                                                                         
    x = random.random() # Uniform values in [0, 1)                                 
    i = int(ceil(1/x))       # Modified soliton distribution                            
    yield i if i <= N else 1 # Correct extreme values to 1                         

if __name__ == '__main__':                                                         
  N = 10                                                                           
  T = 10 ** 5 # Number of trials                                                   
  s = soliton(N, s = soliton(N, random.randint(0, 2 ** 32 - 1)) # soliton generator                   
  f = [0]*N                       # frequency counter                              
  for j in range(T):                                                               
    i = next(s)                                                                    
    f[i-1] += 1                                                                    

  print("k\tFreq.\tExpected Prob\tObserved Prob\n");                               

  print("{:d}\t{:d}\t{:f}\t{:f}".format(1, f[0], 1/N, f[0]/T))                     
  for k in range(2, N+1):                                                          
    print("{:d}\t{:d}\t{:f}\t{:f}".format(k, f[k-1], 1/(k*(k-1)), f[k-1]/T))

Beispielausgabe

k   Freq.   Expected Prob   Observed Prob

1   9965    0.100000    0.099650
2   49901   0.500000    0.499010
3   16709   0.166667    0.167090
4   8382    0.083333    0.083820
5   4971    0.050000    0.049710
6   3354    0.033333    0.033540
7   2462    0.023810    0.024620
8   1755    0.017857    0.017550
9   1363    0.013889    0.013630
10  1138    0.011111    0.011380

Bedarf

Der Code sollte in Python 2 oder 3 funktionieren.

Alex Chamberlain
quelle
+1 Vielen Dank, dass Sie die Python-Übersetzung geteilt haben. Willkommen auf unserer Webseite!
whuber
Keine Bange. Wenn ich LT-Codes zum Laufen bringe, sind sie auf GitHub.
Alex Chamberlain
1
@ Whuber LT Implementierung jetzt auf GitHub . Nicht perfekt, aber es ist ein Anfang.
Alex Chamberlain