基础工具#

随机变量分布处理工具#

class GGanalysis.distribution_1d.FiniteDist(dist: list | ndarray | FiniteDist = [1])#

有限长一维分布

用于快速进行有限长一维离散分布的相关计算,创建时通过传入分布数组进行初始化,可以代表一个随机变量。 本质上是对一个 numpy 数组的封装,通过利用 FFT、快速幂思想、局部缓存等方法使得各类分布相关的运算能方便高效的进行,有良好的算法复杂度。

  • * 运算 定义 FiniteDist 类型和数值之间的 * 运算为数值乘,将返回 FiniteDist.dist 和数值进行数乘后的结果;定义两个 FiniteDist 类型之间的 * 运算为卷积,即计算两个随机变量相加的分布。

  • / 运算 定义 FiniteDist 类型和数值之间的 / 运算为数值乘,将返回 FiniteDist.dist 和数值进行数乘后的结果; 定义两个 FiniteDist 类型之间的 + 运算为分布叠加,将返回将两个 FiniteDist.dist 加和后的结果。

  • ** 运算 定义 FiniteDist 类型与整数的 ** 运算为自卷积,将返回卷积自身数值次后的结果;FiniteDist 变量A与另一个 FiniteDist 变量B的 ** 运算为 \(\sum_{i=0}^{len(B)}{A^B[i]}\)

类属性

  • dist : 用列表、numpy数组、FiniteDist表示在自然数位置的分布。若不传入初始化分布默认为全部概率集中在0位置,即离散卷积运算的幺元。

  • exp :这个一维分布的期望

  • var :这个一维分布的方差

  • p_sum :这个一维分布所有位置的概率的和

  • entropy_rate :这个一维分布的熵率,即分布的熵除其期望,意义为平均每次尝试的信息量

  • randomness_rate :此处定义的随机度为此分布熵率和概率为 \(\frac{1}{exp}\). 的伯努利信源的熵率的比值,越低则说明信息量越低

注意

FiniteDist 类型默认是不可变的对象,不能在外部直接修改 dist 变量,FiniteDist.dist 获得的是一个不可编辑的副本。 这样设计是为了保证对象内容始终一致,进而能利用缓存信息加速计算。

用例

# 定义随机变量 dist_a
dist_a = FiniteDist([0.5, 0.5])
# 定义随机变量 dist_b
dist_b = FiniteDist([0, 1])
# 通过卷积计算两个随机变量叠加 dist_a + dist_b 的分布
dist_a * dist_b
# 计算独立同分布的随机变量 dist_b 累加 10 次后的分布
dist_b ** 10
calc_cdf()#

将自身分布转为cdf返回

calc_dist_attribution(p_error=1e-06) None#

计算分布的基本属性 exp var p_sum

  • p_error : 容许 p_sum 和 1 之间的差距,默认为 1e-6

calc_entropy_attribution(p_error=1e-06) None#

计算分布熵相关属性 entropy_rate randomness_rate

  • p_error : 容许 p_sum 和 1 之间的差距,默认为 1e-6

normalized() FiniteDist#

返回分布进行归一化后的结果

quantile_point(quantile_p)#

返回分位点位置

distribution_1d.pad_zero(target_len)#

给 numpy 数组末尾补零至指定长度

distribution_1d.cut_dist(cut_pos)#

切除分布并重新进行概率归一化,默认切除头部

distribution_1d.calc_expectation() float#

计算离散分布列的期望

distribution_1d.calc_variance() float#

计算离散分布列的方差

distribution_1d.dist2cdf() ndarray#

将分布转为cdf

distribution_1d.cdf2dist() FiniteDist#

将cdf转化为分布

distribution_1d.linear_p_increase(pity_begin=100, step=1, hard_pity=100)#

计算线性递增模型的保底参数

  • base_p : 基础概率

  • pity_begin :概率开始上升位置

  • step :每次上升概率

  • hard_pity :硬保底位置

distribution_1d.p2dist() FiniteDist#

将保底概率参数转化为分布列

distribution_1d.dist2p() ndarray#

将分布转换为条件概率表

distribution_1d.p2exp()#

对于列表,认为是概率提升表,返回对应分布期望

distribution_1d.p2var()#

对于列表,认为是概率提升表,返回对应分布方差

马尔可夫链处理工具#

markov_method.table2matrix(state_trans)#

将邻接表变为邻接矩阵

  • state_num : 状态数量

  • state_trans :邻接表

根据 state_num 和 state_trans 构造矩阵示例

# Epitomized Path & Fate Points
state_num = {'get':0, 'fate1UP':1, 'fate1':2, 'fate2':3}
state_trans = [
    ['get', 'get', 0.375],
    ['get', 'fate1UP', 0.375],
    ['get', 'fate1', 0.25],
    ['fate1UP', 'get', 0.375],
    ['fate1UP', 'fate2', 1-0.375],
    ['fate1', 'get', 0.5],
    ['fate1', 'fate2', 0.5],
    ['fate2', 'get', 1]
]
matrix = table2matrix(state_num, state_trans)
markov_method.calc_stationary_distribution()#

计算转移矩阵对应平稳分布

转移矩阵如下,平稳分布为列向量

|1 0.5|   |x|
|0 0.5|   |y|

x = x + 0.5y y = 0.5y 所得平稳分布为转移矩阵特征值1对应的特征向量

markov_method.multi_item_rarity(once_pull_times: int, is_complete=True)#

计算连抽情况下获得多个道具的概率 仅仅适用于保底抽卡模型

采用三阶段计算,主要是因为直接计算数值收敛性不好,此方法兼顾速度和准确 先得出一直连抽后的保底情况平稳分布,再在平稳分布的基础上计算连抽时首个道具的分布位置 最后根据第一个分布位置,使用组合数算出概率

class GGanalysis.markov_method.PriorityPitySystem(item_p_list: list, extra_state=1, remove_pity=False)#

不同道具按照优先级排序的保底系统 若道具为固定概率p,则传入列表填为 [0, p]

get_next_state(pity_state, get_item=None) list#

返回下一个状态

pity_state 为当前状态 get_item 为当前获取的道具,若为 None 则表示没有获得数据

get_number(pity_state) int#

根据保底情况获得状态编号

get_state(state_num) list#

根据状态编号获得保底情况

get_stationary_p() list#

以列表形式返回每种道具的综合概率

get_transfer_matrix() ndarray#

根据当前的设置生成转移矩阵

get_type_distribution(type) ndarray#

获取对于某一类道具花费抽数的分布(平稳分布的情况)

集齐问题处理工具#

class GGanalysis.coupon_collection.GeneralCouponCollection(p_list: list | ndarray, item_names: list[str] = None)#

不同奖券概率不均等的奖券集齐问题类 默认以集齐为吸收态,状态按照从低到高位对应输入列表的从前往后

collection_dp(n, init_state=None)#

通过DP计算抽n次后的状态分布,返回DP数组

decode_state_number(state_num)#

根据对应状态返回状态道具列表

encode_state_number(item_list)#

根据道具列表生成对应状态

get_collection_p(n, init_state=None, target_state=None, DP_array=None)#

返回抽n抽后达到目标状态的概率数组

get_expectation(state=None, target_state=None)#

带缓存递归计算抽取奖券到目标态时抽取数量期望

get_satisfying_state(target_state=None)#

返回一个标记了满足目标状态要求的01numpy数组

sim_collection(state=None)#

蒙特卡洛模拟抽取次数,用于验证

coupon_collection.get_equal_coupon_collection_exp(init_type=0, target_type=None)#

获得每样道具均等情况下的集齐期望