PRD介绍
PRD伪随机算法多用于游戏中,主要用于减弱真随机算法带来的运气成分
代码展示
下面用于展示PRD中概率增量的求解代码
# _*_ coding: utf-8 _*_
# @Author : *******
# @Time : 2022/8/24 9:48
# @File : PseudoRandomDistribution.py
# @Project: TestCase
import math
ENV = "DEBUG"
def log_out(content):
if "DEBUG" == ENV:
print(content)
class PRD:
def __init__(self):
# 精度
self.precision = 0.0000000000001
def sum_arithmetic_sequence(self, N):
"""
等差数列前N项求和
:param N:第N项
:return:和
"""
res = 0
for i in range(N + 1):
res += i
return res
def get_avgp_by_c(self, c):
"""
通过c求得Nmax次操作中的平均概率
:param c:概率增量
:return:平均概率
"""
# 初始化变量
p_sum_pre_success = 0
p_sum = 0
# 计算c值对应的最大操作次数
Nmax = math.ceil(1 / c)
log_out(f"--当前[ c: {c}, Nmax: {Nmax} ]")
for i in range(1, Nmax + 1):
p_curr = min(1, i * c) * (1 - p_sum_pre_success)
p_sum_pre_success += p_curr
p_sum += i * p_curr
log_out(f"{i}: [sum_pre_success_p: {p_sum_pre_success}, curr_p: {p_curr}, sum_p: {p_sum}")
p_avg = 1 / p_sum
log_out(f"--p_avg: {p_avg}\n#")
return p_avg
def get_c_by_p(self, p):
"""
通过已知触发某项操作的概率求得概率增量
e.g.已知暴击率为50%,求概率增量c
:param p:触发某项操作的概率
:return:概率增量
"""
min_ = 0
max_ = p
while True:
mid_ = (min_ + max_) / 2
p_avg = self.get_avgp_by_c(mid_)
if abs(p_avg - p) < self.precision:
log_out(f"--FINAL C: {mid_}")
return mid_
if p_avg > p:
max_ = mid_
else:
min_ = mid_
if __name__ == '__main__':
prd = PRD()
prd.get_c_by_p(0.5)
运行日志
D:\software_install\Python\Python39\python.exe D:/projects/project-python/TestCase/game_prob/PseudoRandomDistribution.py
--当前[ c: 0.25, Nmax: 4 ]
1: [sum_pre_success_p: 0.25, curr_p: 0.25, sum_p: 0.25
2: [sum_pre_success_p: 0.625, curr_p: 0.375, sum_p: 1.0
3: [sum_pre_success_p: 0.90625, curr_p: 0.28125, sum_p: 1.84375
4: [sum_pre_success_p: 1.0, curr_p: 0.09375, sum_p: 2.21875
--p_avg: 0.4507042253521127
#
--当前[ c: 0.375, Nmax: 3 ]
1: [sum_pre_success_p: 0.375, curr_p: 0.375, sum_p: 0.375
2: [sum_pre_success_p: 0.84375, curr_p: 0.46875, sum_p: 1.3125
3: [sum_pre_success_p: 1.0, curr_p: 0.15625, sum_p: 1.78125
--p_avg: 0.5614035087719298
#
--当前[ c: 0.3125, Nmax: 4 ]
1: [sum_pre_success_p: 0.3125, curr_p: 0.3125, sum_p: 0.3125
2: [sum_pre_success_p: 0.7421875, curr_p: 0.4296875, sum_p: 1.171875
3: [sum_pre_success_p: 0.98388671875, curr_p: 0.24169921875, sum_p: 1.89697265625
4: [sum_pre_success_p: 1.0, curr_p: 0.01611328125, sum_p: 1.96142578125
--p_avg: 0.5098332088623351
#
--当前[ c: 0.28125, Nmax: 4 ]
1: [sum_pre_success_p: 0.28125, curr_p: 0.28125, sum_p: 0.28125
2: [sum_pre_success_p: 0.685546875, curr_p: 0.404296875, sum_p: 1.08984375
3: [sum_pre_success_p: 0.95086669921875, curr_p: 0.26531982421875, sum_p: 1.88580322265625
4: [sum_pre_success_p: 1.0, curr_p: 0.04913330078125, sum_p: 2.08233642578125
--p_avg: 0.480229797461676
#
--当前[ c: 0.296875, Nmax: 4 ]
1: [sum_pre_success_p: 0.296875, curr_p: 0.296875, sum_p: 0.296875
2: [sum_pre_success_p: 0.71435546875, curr_p: 0.41748046875, sum_p: 1.1318359375
3: [sum_pre_success_p: 0.9687576293945312, curr_p: 0.25440216064453125, sum_p: 1.8950424194335938
4: [sum_pre_success_p: 1.0, curr_p: 0.03124237060546875, sum_p: 2.0200119018554688
--p_avg: 0.4950465881322068
#
--当前[ c: 0.3046875, Nmax: 4 ]
1: [sum_pre_success_p: 0.3046875, curr_p: 0.3046875, sum_p: