ให้คอมพิวเตอร์นับจำนวน คำนวณความน่าจะเป็น

คอมพิวเตอร์ทำงานหลายๆอย่างได้เร็วมาก สามารถช่วยแก้ปัญหาที่คนทำแล้วเหนื่อยหรือไม่อยากทำ เช่นคราวนี้เราจะให้มันคำนวณความน่าจะเป็นให้

คำถามมีอยู่ว่า: ซื้อขนมชนิดนึง ในกล่องมีให้สะสมตุ๊กตากล่องละแบบ มีตุ๊กตาทั้งหมด 4 แบบ สะสมครบ 4 แบบจะได้รับรางวัลพิเศษ เราไม่รู้ว่าแต่ละกล่องมีตุ๊กตาแบบไหนแต่ตุ๊กตาแต่ละตัวมีโอกาสเท่าๆกันที่จะอยู่ในขนมแต่ละกล่อง ถ้าซื้อขนมนี้มา 8 กล่องถามว่าความน่าจะเป็นที่จะได้รางวัลพิเศษมีเท่าไหร่

เราจะแก้ปัญหานี้โดยให้คอมพิวเตอร์สร้างรูปแบบที่ขนม 8 กล่องจะเป็นไปได้ทั้งหมด ดูว่ารูปแบบไหนมีตุ๊กตาครบ 4 แบบ แล้วคำนวณความน่าจะเป็นที่จะได้รางวัลพิเศษ

เราเรียกตุ๊กตาว่ามีแบบที่ 1, 2, 3, 4 ดังนี้:

In [1]:
ตุ๊กตา = (1,2,3,4)

เราสร้างรูปแบบขนม 8 กล่องที่เป็นได้ทั้งหมด และนับว่ารูปแบบไหนมีตุ๊กตาครบ 4 แบบดังนี้:

In [2]:
แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    for f in ตุ๊กตา:
                        for g in ตุ๊กตา:
                            for h in ตุ๊กตา:
                                แบบที่เป็นไปได้ = แบบที่เป็นไปได้ + 1
                                รูปแบบ = (a,b,c,d,e,f,g,h)
                                #ดูว่าได้รางวัลหรือไม่ คือดูว่า 1,2,3,4 ต้องมีใน 8 กล่อง
                                if 1 in รูปแบบ and 2 in รูปแบบ and 3 in รูปแบบ and 4 in รูปแบบ:
                                    แบบที่ได้รางวัล = แบบที่ได้รางวัล + 1
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 65536
จำนวนแบบที่ได้รางวัล =  40824
ความน่าจะเป็นที่จะได้รางวัล = 62.3%

เราหัดใช้ all() และ any() เพื่อตรวจดูว่าสมาชิกทุกตัวในลิสต์เป็นจริง หรือสมาชิกบางตัวในหลิสต์เป็นจริงหรือไม่ (all และ any ใช้กับสิ่งอื่นๆที่เรียกว่า iterable เช่น dictionary, tuple, string, range,... ได้ด้วย)

In [3]:
def ได้รางวัล(รูปแบบขนม):
    
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  #จะเป็นลิสต์ยาวเท่ากับจำนวนตุ๊กตา 
                                                    #โดยสมาชิกแต่ละตัวจะเป็น True หรือ False 
                                                    #ขึ้นกับว่าตุ๊กตาแบบนั้นอยู่ในรูปแบบขนมหรือไม่
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม
In [4]:
# (1,2,3,4,3,2,1,4) มีตุ๊กตาครบทุกแบบ 1,2,3,4
ได้รางวัล((1,2,3,4,3,2,1,4))
Out[4]:
True
In [5]:
# (1,1,1,1,1,2,2,3) มีตุ๊กตาไม่ครบ ขาดแบบที่ 4 ไป
ได้รางวัล((1,1,1,1,1,2,2,3))
Out[5]:
False

เราเลยเขียนโปรแกรมเราดูอีกทีโดยใช้ all() ด้วย:

In [6]:
ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  #จะเป็นลิสต์ยาวเท่ากับจำนวนตุ๊กตา 
                                                    #โดยสมาชิกแต่ละตัวจะเป็น True หรือ False 
                                                    #ขึ้นกับว่าตุ๊กตาแบบนั้นอยู่ในรูปแบบขนมหรือไม่
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    for f in ตุ๊กตา:
                        for g in ตุ๊กตา:
                            for h in ตุ๊กตา:
                                แบบที่เป็นไปได้ += 1 #หัดใช้ += ความหมายของ x += 1 คือ x = x + 1
                                รูปแบบ = (a,b,c,d,e,f,g,h)
                                if ได้รางวัล(รูปแบบ): #ใช้ฟังก์ชั่น ได้รางวัล() ที่ใช้ all() ข้างบน
                                    แบบที่ได้รางวัล += 1 #หัดใช้ +=
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 65536
จำนวนแบบที่ได้รางวัล =  40824
ความน่าจะเป็นที่จะได้รางวัล = 62.3%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อแค่ 3 กล่อง ซึ่งไม่มีทางที่จะได้รางวัลเพราะของเล่นมีอย่างมาก 3 แบบ:

In [7]:
#ซื้อขนม 3 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            แบบที่เป็นไปได้ += 1 
            รูปแบบ = (a,b,c)
            if ได้รางวัล(รูปแบบ): 
                แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 64
จำนวนแบบที่ได้รางวัล =  0
ความน่าจะเป็นที่จะได้รางวัล = 0.0%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อ 4 กล่อง:

In [8]:
#ซื้อขนม 4 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                แบบที่เป็นไปได้ += 1 
                รูปแบบ = (a,b,c,d)
                if ได้รางวัล(รูปแบบ): 
                    แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 256
จำนวนแบบที่ได้รางวัล =  24
ความน่าจะเป็นที่จะได้รางวัล = 9.4%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อ 5 กล่อง:

In [9]:
#ซื้อขนม 5 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    แบบที่เป็นไปได้ += 1 
                    รูปแบบ = (a,b,c,d,e)
                    if ได้รางวัล(รูปแบบ): 
                        แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 1024
จำนวนแบบที่ได้รางวัล =  240
ความน่าจะเป็นที่จะได้รางวัล = 23.4%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อ 6 กล่อง:

In [10]:
#ซื้อขนม 6 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    for f in ตุ๊กตา:
                        แบบที่เป็นไปได้ += 1 
                        รูปแบบ = (a,b,c,d,e,f)
                        if ได้รางวัล(รูปแบบ): 
                            แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 4096
จำนวนแบบที่ได้รางวัล =  1560
ความน่าจะเป็นที่จะได้รางวัล = 38.1%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อ 7 กล่อง จะพบว่าความน่าจะเป็นเริ่มเกิน 50%:

In [11]:
#ซื้อขนม 7 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    for f in ตุ๊กตา:
                        for g in ตุ๊กตา:
                            แบบที่เป็นไปได้ += 1 
                            รูปแบบ = (a,b,c,d,e,f,g)
                            if ได้รางวัล(รูปแบบ): 
                                แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 16384
จำนวนแบบที่ได้รางวัล =  8400
ความน่าจะเป็นที่จะได้รางวัล = 51.3%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อ 9 กล่อง:

In [12]:
#ซื้อขนม 9 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    for f in ตุ๊กตา:
                        for g in ตุ๊กตา:
                            for h in ตุ๊กตา:
                                for i in ตุ๊กตา:
                                    แบบที่เป็นไปได้ += 1 
                                    รูปแบบ = (a,b,c,d,e,f,g,h,i)
                                    if ได้รางวัล(รูปแบบ): 
                                        แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 262144
จำนวนแบบที่ได้รางวัล =  186480
ความน่าจะเป็นที่จะได้รางวัล = 71.1%

ทดลองคำนวณความน่าจะเป็นถ้าซื้อ 10 กล่อง:

In [13]:
#ซื้อขนม 10 กล่อง

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม


แบบที่เป็นไปได้ = 0
แบบที่ได้รางวัล = 0

for a in ตุ๊กตา:
    for b in ตุ๊กตา:
        for c in ตุ๊กตา:
            for d in ตุ๊กตา:
                for e in ตุ๊กตา:
                    for f in ตุ๊กตา:
                        for g in ตุ๊กตา:
                            for h in ตุ๊กตา:
                                for i in ตุ๊กตา:
                                    for j in ตุ๊กตา:
                                        แบบที่เป็นไปได้ += 1 
                                        รูปแบบ = (a,b,c,d,e,f,g,h,i,j)
                                        if ได้รางวัล(รูปแบบ): 
                                            แบบที่ได้รางวัล += 1 
                                    
print(f"จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
print(f"จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
print(f"ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
จำนวนแบบที่เป็นไปได้ทั้งหมด = 1048576
จำนวนแบบที่ได้รางวัล =  818520
ความน่าจะเป็นที่จะได้รางวัล = 78.1%

Advanced Topics: ใช้ itertools.product

ถ้าเราสนใจจะเขียนฟังก์ชั่นที่คำนวณความน่าจะเป็นเมื่อซื้อขนมกี่กล่องก็ได้โดยไม่ต้องก๊อปปี้โค้ดแล้วแก้ด้วยมือ เราสามารถใช้ความสามารถของ itertools.product() ได้

itertools.product(A,B) ทำหน้าที่วนเอาของใน A, B มาให้เราเหมือน

for a in A:
    for b in B:
        ...

หรือถ้ามีวนสามชั้น itertools.product(A,B,C) ก็วนเอาของใน A, B, C มาให้เราเหมือน

for a in A:
    for b in B:
        for c in C:
            ...

นอกจากนี้เราสามารถใส่ตัวแปร repeat ให้ itertools.product วนเอาของจาก A ซ้ำๆได้ด้วยเช่น itertools.product(A, repeat=3) จะวนเอาของใน A มาให้สามชั้นเหมือน

for a in A:
    for b in A:
        for c in A:
            ...

ตัวอย่างเช่นถ้าซื้อขนมมาสองกล่อง รูปแบบตุ๊กตาที่เป็นไปได้ก็จะมี 16 แบบดังนี้:

In [14]:
import itertools
for รูปแบบ in itertools.product(ตุ๊กตา, repeat=2):
    print(รูปแบบ)
(1, 1)
(1, 2)
(1, 3)
(1, 4)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 1)
(3, 2)
(3, 3)
(3, 4)
(4, 1)
(4, 2)
(4, 3)
(4, 4)

เราจึงสามารถเขียนฟังก์ชั่นคำนวณความน่าจะเป็นเมื่อซื้อขนมกี่กล่องก็ได้ดังนี้:

In [15]:
import itertools

ตุ๊กตา = (1,2,3,4)

def ได้รางวัล(รูปแบบขนม):
    
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  #จะเป็นลิสต์ยาวเท่ากับจำนวนตุ๊กตา 
                                                    #โดยสมาชิกแต่ละตัวจะเป็น True หรือ False 
                                                    #ขึ้นกับว่าตุ๊กตาแบบนั้นอยู่ในรูปแบบขนมหรือไม่
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม

def แสดงความน่าจะเป็นเมื่อซื้อขนม_N_กล่อง(N):
    
    แบบที่เป็นไปได้ = 0
    แบบที่ได้รางวัล = 0
    
    for รูปแบบ in itertools.product(ตุ๊กตา, repeat = N):
        แบบที่เป็นไปได้ += 1
        if ได้รางวัล(รูปแบบ):
            แบบที่ได้รางวัล += 1 
                                    
    print(f"ขนม {N} กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = {แบบที่เป็นไปได้}")
    print(f"ขนม {N} กล่อง: จำนวนแบบที่ได้รางวัล =  {แบบที่ได้รางวัล}")
    print(f"ขนม {N} กล่อง: ความน่าจะเป็นที่จะได้รางวัล = {100 * แบบที่ได้รางวัล/แบบที่เป็นไปได้:.1f}%")
In [16]:
#ทดลองกับ 8 กล่อง:
แสดงความน่าจะเป็นเมื่อซื้อขนม_N_กล่อง(8)
ขนม 8 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 65536
ขนม 8 กล่อง: จำนวนแบบที่ได้รางวัล =  40824
ขนม 8 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 62.3%
In [17]:
#ลองไล่ไปถึง 12 กล่อง:
for n in range(0,13):
    แสดงความน่าจะเป็นเมื่อซื้อขนม_N_กล่อง(n)
    print("-"*50)
ขนม 0 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 1
ขนม 0 กล่อง: จำนวนแบบที่ได้รางวัล =  0
ขนม 0 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 0.0%
--------------------------------------------------
ขนม 1 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 4
ขนม 1 กล่อง: จำนวนแบบที่ได้รางวัล =  0
ขนม 1 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 0.0%
--------------------------------------------------
ขนม 2 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 16
ขนม 2 กล่อง: จำนวนแบบที่ได้รางวัล =  0
ขนม 2 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 0.0%
--------------------------------------------------
ขนม 3 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 64
ขนม 3 กล่อง: จำนวนแบบที่ได้รางวัล =  0
ขนม 3 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 0.0%
--------------------------------------------------
ขนม 4 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 256
ขนม 4 กล่อง: จำนวนแบบที่ได้รางวัล =  24
ขนม 4 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 9.4%
--------------------------------------------------
ขนม 5 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 1024
ขนม 5 กล่อง: จำนวนแบบที่ได้รางวัล =  240
ขนม 5 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 23.4%
--------------------------------------------------
ขนม 6 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 4096
ขนม 6 กล่อง: จำนวนแบบที่ได้รางวัล =  1560
ขนม 6 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 38.1%
--------------------------------------------------
ขนม 7 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 16384
ขนม 7 กล่อง: จำนวนแบบที่ได้รางวัล =  8400
ขนม 7 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 51.3%
--------------------------------------------------
ขนม 8 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 65536
ขนม 8 กล่อง: จำนวนแบบที่ได้รางวัล =  40824
ขนม 8 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 62.3%
--------------------------------------------------
ขนม 9 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 262144
ขนม 9 กล่อง: จำนวนแบบที่ได้รางวัล =  186480
ขนม 9 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 71.1%
--------------------------------------------------
ขนม 10 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 1048576
ขนม 10 กล่อง: จำนวนแบบที่ได้รางวัล =  818520
ขนม 10 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 78.1%
--------------------------------------------------
ขนม 11 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 4194304
ขนม 11 กล่อง: จำนวนแบบที่ได้รางวัล =  3498000
ขนม 11 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 83.4%
--------------------------------------------------
ขนม 12 กล่อง: จำนวนแบบที่เป็นไปได้ทั้งหมด = 16777216
ขนม 12 กล่อง: จำนวนแบบที่ได้รางวัล =  14676024
ขนม 12 กล่อง: ความน่าจะเป็นที่จะได้รางวัล = 87.5%
--------------------------------------------------

จำนวนแบบที่เป็นไปได้เพิ่มขึ้นรวดเร็วมากเมื่อจำนวนกล่องเพิ่ม (เท่ากับ $4^{N}$ เมื่อ $N$ คือจำนวนกล่อง) ถ้าเราซื้อ 20 กล่อง จำนวนที่เป็นไปได้จะเป็นล้านล้านแบบ (เลข 12 หลัก) ถ้าซื้อ 30 กล่อง จำนวนที่เป็นไปได้จะเป็นล้านล้านล้านแบบ (เลข 18 หลัก) เราต้องใช้วิธีอื่นประมาณความน่าจะเป็น

วิธีสุ่ม (Sampling)

เราสามารถใช้คอมพิวเตอร์ประมาณความน่าจะเป็นที่เราไม่สามารถแจกแจงทุกรูปแบบที่เป็นไปได้โดยการสุ่ม วิธีก็ง่ายมากคือสมมุติให้คอมพิวเตอร์เข้าไปซื้อขนมหลายๆครั้ง แล้วดูว่าได้รางวัลกี่ครั้ง อัตราส่วนจำนวนครั้งที่ได้รางวัลต่อจำนวนครั้งที่เข้าไปซื้อก็คือค่าประมาณของความน่าจะเป็นที่ได้รางวัล

ตัวอย่างโค้ดที่ให้คอมพิวเตอร์ลองซื้อขนมหลายๆครั้งเป็นดังนี้:

In [18]:
import random #จะใช้ random.choice()เพื่อสุ่มเลือกตุ๊กตา

ตุ๊กตา = (1,2,3,4)

def ซื้อ_N_กล่อง(N): #จะให้รูปแบบกล่องที่มีตุ๊กตาสุ่มมาเมื่อซื้อขนม N กล่อง
    รูปแบบ = []
    for i in range(N):
        รูปแบบ.append(random.choice(ตุ๊กตา))
    return รูปแบบ

def ได้รางวัล(รูปแบบขนม):
    
    ตุ๊กตาอยู่ในขนมไหม = [x in รูปแบบขนม for x in ตุ๊กตา]  #จะเป็นลิสต์ยาวเท่ากับจำนวนตุ๊กตา 
                                                    #โดยสมาชิกแต่ละตัวจะเป็น True หรือ False 
                                                    #ขึ้นกับว่าตุ๊กตาแบบนั้นอยู่ในรูปแบบขนมหรือไม่
    return all(ตุ๊กตาอยู่ในขนมไหม)  #ให้ค่าเป็น True เมื่อตุ๊กตาทุกแบบมีอยู่ในขนม

def ประมาณความน่าจะเป็นเมื่อซื้อ_N_กล่อง(N, จำนวนครั้งที่ลองซื้อ):
    จำนวนครั้งที่ได้รางวัล = 0
    for i in range(จำนวนครั้งที่ลองซื้อ + 1):
        รูปแบบ = ซื้อ_N_กล่อง(N)
        if ได้รางวัล(รูปแบบ):
            จำนวนครั้งที่ได้รางวัล += 1
    print(f"ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ {N} กล่อง = {100* จำนวนครั้งที่ได้รางวัล/จำนวนครั้งที่ลองซื้อ:.1f}")
    
In [19]:
#ทดลองกับ 8 กล่อง
ประมาณความน่าจะเป็นเมื่อซื้อ_N_กล่อง(8,10_000)
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 8 กล่อง = 62.9
In [20]:
#ลองกับหลายๆกล่อง

จำนวนครั้งที่ลอง = 100_000 
for i in range(31):
    ประมาณความน่าจะเป็นเมื่อซื้อ_N_กล่อง(i, จำนวนครั้งที่ลอง)
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 0 กล่อง = 0.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 1 กล่อง = 0.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 2 กล่อง = 0.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 3 กล่อง = 0.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 4 กล่อง = 9.4
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 5 กล่อง = 23.5
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 6 กล่อง = 38.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 7 กล่อง = 51.1
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 8 กล่อง = 62.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 9 กล่อง = 71.1
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 10 กล่อง = 78.1
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 11 กล่อง = 83.5
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 12 กล่อง = 87.7
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 13 กล่อง = 90.4
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 14 กล่อง = 93.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 15 กล่อง = 94.7
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 16 กล่อง = 96.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 17 กล่อง = 97.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 18 กล่อง = 97.8
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 19 กล่อง = 98.2
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 20 กล่อง = 98.7
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 21 กล่อง = 99.0
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 22 กล่อง = 99.3
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 23 กล่อง = 99.5
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 24 กล่อง = 99.6
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 25 กล่อง = 99.7
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 26 กล่อง = 99.8
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 27 กล่อง = 99.8
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 28 กล่อง = 99.9
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 29 กล่อง = 99.9
ความน่าจะเป็นโดยประมาณที่จะได้รางวัลเมื่อซื้อ 30 กล่อง = 99.9

ถ้าวาดเป็นกราฟจะมีหน้าตาประมาณนี้:

Screen%20Shot%202562-11-23%20at%2012.15.07.jpg

In [ ]: