Làm cách nào để tạo số theo phân phối Soliton?


10

Các phân phối soliton là một phân phối xác suất rời rạc trên một tập với chức năng xác xuất hàng loạt{1,,N}

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

Tôi muốn sử dụng nó như là một phần của việc triển khai mã LT , lý tưởng nhất là trong Python nơi có sẵn trình tạo số ngẫu nhiên thống nhất.

Câu trả lời:


9

Nếu chúng ta bắt đầu ở , kính thiên văn tính tổng, cho cho CDF (đã sửa đổi). Đảo ngược điều này và quan tâm đến trường hợp đặc biệt , đưa ra thuật toán sau (được mã hóa , tôi sợ, nhưng bạn có thể coi nó là mã giả để triển khai Python):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
}

Để làm ví dụ về việc sử dụng nó (và thử nghiệm), hãy rút ra giá trị cho :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)

Phân phối tần số


1
Đối với phân phối soliton "mạnh mẽ" có liên quan, có lẽ bạn phải giải quyết một giải pháp kém hiệu quả hơn một chút (dựa trên tìm kiếm nhị phân hoặc tương đương).
whuber

Làm thế nào bạn đến với điều đó rất nhanh?
Alex Chamberlain

2
@Alex Chamberlain vì anh ấy tốt: D
gui11aume

7

Python (được điều chỉnh từ giải pháp R của @ whuber's )

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

Đầu ra mẫu

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

Yêu cầu

Mã sẽ hoạt động trong Python 2 hoặc 3.


+1 Cảm ơn bạn đã chia sẻ bản dịch Python. Chào mừng đến với trang web của chúng tôi!
whuber

Đừng lo lắng. Nếu tôi nhận được mã LT hoạt động, chúng sẽ có trên GitHub.
Alex Chamberlain

1
@whuber LT triển khai ngay bây giờ trên GitHub . Không hoàn hảo, nhưng đó là một khởi đầu.
Alex Chamberlain
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.