离散概率模型的Python实现。下面是源代码。
# -*- coding: UTF-8 -*-
import random
import numpy as np
# random.sample(lst, N)
def randstr(s, N=1):
# generate a string randomly from s (string)
return ''.join([random.choice(s) for _ in range(N)])
def shufflestr(s):
lst = list(s)
np.random.shuffle(lst)
return ''.join(lst)
# def choicex(s, p=None, F=None):
# '''principle: P(X=s[i])=p[i]=P(F[i-1]=r<F[i]), r ~ U[0,1], let F[-1]=0'''
# if F is None:
# if p is None:
# p = [1/len(s) for _ in range(len(s))]
# F = np.cumsum(p)
# r = np.random.rand()
# for v, f in zip(s, F):
# if r < f:
# return v
class RandomGenrator:
# random genrator, base class for Probability Model
def random(self):
pass
def sequence(self, N=1):
# generator a sequence of rv with N length
rv = []
for _ in range(N):
rv.append(self.random())
return rv
class RandomSelector(RandomGenrator):
'''Classical (Discrete) Probability Model
RandomSelector has 2 (principal) propteries:
values: list of values
prob: list of probability [unifrom distribution]
dist: distribution [unifrom distribution]
-----------------------
principle:
P(X=s[i])=p[i]=P(F[i-1]=r<F[i]), r ~ U[0,1], let F[-1]=0'''
def __init__(self, values, prob=None, dist=None):
self.values = values
self.prob = prob
if dist is None:
# if dist is None, it should be calculated with prob
if prob is None:
N = len(values)
prob = [1/N for _ in range(N)]
self.dist = np.cumsum(prob)
else:
self.dist = dist
def __call__(self, x):
# get the probability of x
for v, p in zip(self.values, self.prob):
if v == x:
return p
def random(self):
# choose a number from values randomly
r = np.random.rand()
for v, f in zip(self.values, self.dist):
if r < f:
return v
if __name__ == '__main__':
rc = RandomSelector('string',p=每个字符的概率,默认为均匀分布)
s = rc.random()
print(s)
s = rc.sequence(3)
print(s)