Soliton 분포에 따라 숫자를 어떻게 생성합니까?


10

솔리톤 분포 세트 위에 이산 확률 분포 확률 질량 함수{1,,N}

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

균일 한 난수 생성기가있는 Python에서 이상적으로 LT 코드 구현의 일부로 사용하고 싶습니다 .

답변:


9

우리가 시작하면, , 합계를 제공 망원경 1 - 1 / K 제 (변형)를위한 CDF. 이것을 뒤집고 특별한 경우 k = 1 을 돌보면 다음 알고리즘이 제공됩니다 (로 코딩되어 있습니다.하지만 파이썬 구현을 위해 의사 코드로 사용할 수 있습니다).k=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
}

사용 및 테스트의 예로 N = 10에 대해 값을 그 립니다 .105N=10

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

주파수 분포


1
관련된 "견고한"솔리톤 분포의 경우, 약간 덜 효율적인 솔루션 (이진 검색 또는 이에 상응하는 기반)을 해결해야합니다.
whuber

어떻게 그렇게 빨리 그렇게 했습니까?
Alex Chamberlain

2
@Alex Chamberlain 그가 좋기 때문에 : D
gui11aume

7

Python ( @whuber의 R 솔루션 에서 채택 )

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))

샘플 출력

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

요구 사항

코드는 Python 2 또는 3에서 작동해야합니다.


+1 파이썬 번역을 공유해 주셔서 감사합니다. 우리 사이트에 오신 것을 환영합니다!
whuber

걱정 마. LT 코드가 작동하면 GitHub에 있습니다.
Alex Chamberlain

1
이제 GitHub 에서 @whuber LT 구현 . 완벽하지는 않지만 시작입니다.
Alex Chamberlain
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.