python怎么以一定概率执行某段代码

python怎么以一定概率执行某段代码,第1张

文章目录
  • 最便捷的实现方法
  • 问题背景
  • 代码实现及测试
  • 更为鲁棒的函数封装实现

最便捷的实现方法

对于概率p(0~1之间的浮点数),采用random.random()方法生成一个介于0~1之间的均匀的浮点数R,如果R,则执行代码,否则不执行。

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:
	不执行
问题背景

在某些情况下,需要我们按照某概率 p p p(给定的,通常是百分制)执行某段代码(比如说按照概率 p p p执行网络流中的“丢包事件”),我们可以通过下面这种方法来实现这种需求:

  • 百分制概率 p p p转化为整数(可以乘100) I I I
  • 使用pythonrandom模块中的方法random.randint(a,b)来随机生成一个介于a~b之间的整数 R R R
  • R R R落在了 1 ∼ I 1\sim I 1I之间,则执行代码;否则不执行

注意如果 p p p的精度高于 0.01 % 0.01\% 0.01%,依然可以乘 1 0 n 10^n 10n将其转化为整数,只不过后面的区间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的要求也更加宽松!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/918569.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)