文章目录
- 最便捷的实现方法
- 问题背景
- 代码实现及测试
- 更为鲁棒的函数封装实现
最便捷的实现方法
对于概率p
(0~1之间的浮点数),采用random.random()
方法生成一个介于0~1之间的均匀的浮点数R
,如果R<p
,则执行代码,否则不执行。
def random_unit(p: float):
if p == 0:
return False
if p == 1:
return True
R = random.random()
if R < p:
return True
else:
return False
if random_unit(p) == True:
执行代码
else:
不执行
问题背景
在某些情况下,需要我们按照某概率(给定的,通常是百分制)执行某段代码(比如说按照概率执行网络流中的“丢包事件”),我们可以通过下面这种方法来实现这种需求:
- 百分制概率转化为整数(可以乘100)。
- 使用python
random
模块中的方法random.randint(a,b)
来随机生成一个介于a~b之间的整数 - 若落在了之间,则执行代码;否则不执行
注意如果的精度高于,依然可以乘将其转化为整数,只不过后面的区间1~I
也要相应扩大。
代码实现及测试
代码实现可以如下:
import random
if __name__ == "__main__":
p = 0.19 # 概率
f = 0.19*100 # 将概率转化为整数
interval_begin = 1 # 区间起始
interval__end = f # 区间结束
R = random.randint(1, 100)
if R >= interval_begin and R <= interval__end:
print(f"R={R}")
print("执行这里的代码")
else:
print(f"R={R}")
print("上面的代码未被执行")
执行效果如下:
接下来看看是不是按照指定概率执行了代码,测试方法是执行较多次数循环,统计被调度代码被执行的次数:
import random
if __name__ == "__main__":
p = 0.19 # 概率
f = 0.19*100 # 将概率转化为整数
interval_begin = 1 # 区间起始
interval__end = f # 区间结束
max_time = 100 # 总运行次数
i = 0 # 循环变量
run_time = 0 # 记录运行“被调度”代码的执行次数
while i < max_time:
R = random.randint(1, 100)
if R >= interval_begin and R <= interval__end:
run_time += 1 # 满足条件,执行次数+1
i += 1
implementation_rates = float(run_time)/float(max_time) # 代码执行率
print(f"执行了共计 {max_time} 次主循环")
print(f"其中指定代码被执行了 {run_time} 次")
print(f"执行率为:{implementation_rates}")
执行一百次的执行率:
还是比较接近的,再把次数设置为1000次试试:
可以看到已经非常接近0.19了(甚至有一次就是0.19!),平均执行率肯定是趋于0.19的。成功达成效果!
更为鲁棒的函数封装实现
注意上面的代码只支持概率p
的精度最大为0.01
,超过该精度的概率p
值,如0.195,就会出错。
下面给出一种封装实现,支持浮点精度内的,介于0~1的p,其思想同上面的代码类似,只不过是反了过来,将生成的随机整数转化为了0~1之间的浮点数然后进行范围比较:
import random
def random_unit(p):
assert p >= 0 and p <= 1, "概率P的值应该处在[0,1]之间!"
if p == 0:#概率为0,直接返回False
return False
if p == 1:#概率为1,直接返回True
return True
p_digits = len(str(p).split(".")[1])
interval_begin = 1
interval__end = pow(10, p_digits)
R = random.randint(interval_begin, interval__end)
if float(R)/interval__end < p:
return True
else:
return False
再次执行测试代码:
import random
def random_unit(p):
assert p >= 0 and p <= 1, "概率P的值应该处在[0,1]之间!"
if p == 0: # 概率为0,直接返回False
return False
if p == 1: # 概率为1,直接返回True
return True
p_digits = len(str(p).split(".")[1])
interval_begin = 1
interval__end = pow(10, p_digits)
R = random.randint(interval_begin, interval__end)
if float(R)/interval__end < p:
return True
else:
return False
if __name__ == "__main__":
p = 0.195 # 概率
max_time = 10000 # 总运行次数
i = 0 # 循环变量
run_time = 0 # 记录运行“被调度”代码的执行次数
while i < max_time:
R = random_unit(p)
if R == True:
run_time += 1 # 满足条件,执行次数+1
i += 1
implementation_rates = float(run_time)/float(max_time) # 代码执行率
print(f"执行了共计 {max_time} 次主循环")
print(f"其中指定代码被执行了 {run_time} 次")
print(f"执行率为:{implementation_rates}")
也能达到效果,对概率p的要求也更加宽松!