统计概率

2022-09-22  本文已影响0人  Python_Camp

我们有一把枪,可以射出不同颜色的小画球。我们想计算按特定顺序射出一定数量的特定颜色的小球的概率。

在开始射击之前,将小球混合起来,使每个小球都有相同的概率被选中射击。每次射击后都要重复这个动作。

例如,枪里总共有18个球。9个黄色,4个红色和5个蓝色。就像我们下面的这几组。

我们想知道这组球(balls_set)出现以下连续4次射击事件的概率:

e1 = ["RD", "YL", "YL", "BL"] 

RD表示红色,YL表示黄色,BL表示蓝色

概率将是

p(e1) = 4/18 * 9/17 * 8/16 * 5/15 = 1440/73440 = 1/51

但是下面这个事件,对于同样的球_集来说,5次投篮的这个事件是不可能的:

e2 = ["RD", "YL", "YL", "BL", "GN"] p(e2) = 0

这里的新是GN,GN意味着绿色。在上面给出的集合中没有绿色的球。

你将得到一个无序的、具有不同颜色的球的集合和一个期望的事件。balls_set有颜色名称的全称(第一个字母为大写字母),是一个数组。事件也是一个数组,但有相应的颜色缩写(见下面的表格)。你应该将所需事件的概率输出为一个不可还原的分数,其分子和分母是一个数组,[num, den](numden应该是同素数)。

上面给出的例子将是

set_balls = ["Red", "Red", "Blue", "Yellow", "Yellow", "Yellow", "Blue", "Yellow", "Red", "Blue", "Yellow", "Blue",Yellow" ]
e = ["RD", "YL", "YL", "BL"]
find_prob(set_balls, e1) === [1,51]

而上述情况下,当概率为0时,该函数将输出一个带有 "不可能 "字样的数组。

set_balls = ["Red", "Red", "Blue", "Yellow", "Yellow", "Yellow", "Blue", "Yellow", "Red", "Blue", "Yellow", "Blue",Yellow" ]
e = ["RD", "YL", "YL", "BL, "GN"]
find_prob(set_balls, e1) === ['Impossible'] #不可能

你应该记住,概率非常低、非常接近0的事件是不可能的,但概率等于0的事件是不可能的。 下表显示了对应的缩写和所有可能的球的颜色,可用于该卡塔。

缩写 颜色
AL 铝色
AM 琥珀
BG 米色
BK 黑
BL 蓝色
BN 棕色
BZ 青铜色
CH 炭色
CL 透明
GD 金色
GN 绿色
GY 灰色
GT 花岗岩
IV 象牙色
LT 光
OL 橄榄色
OP 不透明
OR 橙色
PK 粉红色
RD 红色
SM 烟雾色
TL 半透明的
TN 棕褐色
TP 透明的
VT 紫色
WT 白色
YL 黄色

词典ABBREVIATIONS(在Ruby中为$ABBREVIATIONS)已经为你预装,以加快你的解决方案的创建。随机测试的特点。

球的长度(球的总量)在20和100000之间
根据球的总量决定事件的数量
在测试的例子中,有更多的案例。
该枪有数量可观的各色子弹。

手动建立色彩拼写缩写的字典

Abbreviation Color

colors = '''
AL                  Aluminum 
AM                  Amber 
BG                  Beige 
BK                  Black 
BL                  Blue 
BN                  Brown 
BZ                  Bronze 
CH                  Charcoal 
CL                  Clear 
GD                  Gold 
GN                  Green 
GY                  Gray 
GT                  Granite 
IV                  Ivory 
LT                  Light  
OL                  Olive 
OP                  Opaque 
OR                  Orange 
PK                  Pink 
RD                  Red 
SM                  Smoke 
TL                  Translucent 
TN                  Tan 
TP                  Transparent 
VT                  Violet 
WT                  White 
YL                  Yellow 

主程序

#色彩缩写字典
c = [c for c in colors.split(" ") if c != '']
abbr = [c[i][1:] for i in range(0,len(c),2)]
colo = [c[i] for i in range(1,len(c),2)]
color = dict(zip(colo,abbr))

#按色彩统计数量的高级函数
#实现结果为互质的库
from collections import Counter
from fractions import Fraction

def find_prob(balls_set, event):
    d = Counter(balls_set)
    balls = {color[k]:v for k,v in d.items()}

    if any([e not in balls for e in event]):
        return ["Impossible"]
    divisor, divided= 1,1
    lng = len(balls_set)
    for i,e in enumerate(event):
        if balls[e] > 0:
            divided *= balls[e]
            divisor *= lng
            balls[e] -= 1
            lng -= 1
        else:return ["Impossible"]
    out = Fraction(divisor,divided)
    return [out.denominator, out.numerator] 

1st solve
使用内置 ABBREVIATIONS字典省去了手动建立色彩字典

from collections import Counter
from fractions import Fraction as F

def find_prob(balls_set, event):
    count = len(balls_set)
    ct = Counter(balls_set)
    coefs = 1
    for e in event:
        name = ABBREVIATIONS[e]
        if ct[name] == 0 or count == 0: return ["Impossible"]
        
        coefs *= F(str(ct[name]) + '/' + str(count))
        count -= 1
        ct[name] -= 1

    return [coefs.numerator, coefs.denominator]

2nd 使用GCD()函数实现互素的输出

from collections import Counter
from math import gcd
d = ABBREVIATIONS
def find_prob(stock, event):
    total, c, N, D = len(stock), Counter(stock), 1, 1
    for i in event:
        if d[i] not in stock or not total : return ['Impossible']
        N, D, total, c[d[i]] = N*c[d[i]], D*total, total-1, c[d[i]]-1
    G = gcd(N,D)
    return [N//G, D//G] if N else ['Impossible']

尽快熟悉库函数!!

本文由mdnice多平台发布

上一篇下一篇

猜你喜欢

热点阅读