离散概率模型的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)


Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐