排列組合python,從排列與組合的python實現到生日問題的解釋

 2023-11-18 阅读 18 评论 0

摘要:在 數論及Python實踐一文中,我們介紹了組合的基本定義以及一些常規實現方法,并未充分發揮python語言的優勢,本文我們從reduce函數的角度(從這個角度我們應當恢復reduce正宮娘娘的地位,因為在python3中Guido將reduce從系統內置函數降格為fu

在 數論及Python實踐一文中,我們介紹了組合的基本定義以及一些常規實現方法,并未充分發揮python語言的優勢,本文我們從reduce函數的角度(從這個角度我們應當恢復reduce正宮娘娘的地位,因為在python3中Guido將reduce從系統內置函數降格為functools中的函數),重新實現給出排列組合的各自實現,以及據此給出”生日問題”的概率解釋。

?(nk)=n!k!(n?k)!?(nk)=(n?1k)+(n?1k?1)??

第二行公式可看做其遞歸定義式。我們換個記號繼續推導:
C?k?n?===?C?k?n?1?+C?k?1?n?1?C?k?n?1?+C?k?1?n?2?+C?k?2?n?2????

這里還有一個經典的結論:
?k=0?n?(nk)=2?n??

如何證明,其實很簡單,回歸定義(組合數combination,又叫二項式系數binomial coefficients),對 2?n??進行二項展開,即:
2?n?===?(1+1)?n?(n0)+(n1)+?+(nn?1)+(nn)?k=0?n?(nk)??

排列組合python?

2?n?? 這不正是二進制嘛!這個結論有什么用?舉個栗子,給定三個卡片,編號為 1?3?,使用該等式可得其會有 2?3?=8?種組合(combinations或叫subsets)(包括空集):

|{{};{1};{2};{3};{1,2};{1,3};{2,3};{1,2,3}}|=8?

以二進制的形式理解的話即為:

  • 0:000
  • 1:001
  • 2:010
  • 3:011
  • 4:100
  • 5:101
  • 6:110
  • 7:111

再來考慮這樣一種情形,從 n?個數中隨機選擇 k 個,再從余下的 n?k?個隨機選擇p?個,組合數一共多少:

(nk)?(n?kp)=n!k!(n?k)! ?(n?k)!p!(n?k?p)! =n!k!p!(n?k?p)!  

將此記為:(nk,p)?,也即 (nk,p)=n!k!p!(n?k?p)!??

再來看幾個結論:

A?k?n?=n!(n?k)!??

所以有:
(nk)A?k?k?=n!k!(n?k)!?k!=A?k?n??

python中排序、

N?k?[A?k?N?=(Nk)A?k?k?]?

左邊允許重復,右邊不允許重復;

當我們試圖用reduce實現組合數的計算時,

(nk)=n!k!(n?k)!?=?i=n?k+1?n?ik!?=A?k?n?k!??

python生日,

from functools import reduce
import operatordef fac(n):return reduce(operator.mul, range(1, n+1), 1)# 階乘n!的定義# reduce與operator.mul結合
def perm(n, k):return reduce(operator.mul, range(n-k+1, n+1), 1)   # 排列數的定義
def comb(n, k):return perm(n, k)//fac(k)                   def test():print('{}!={}'.format(5, fac(5)))print('A_{}^{}={}'.format(5, 2, perm(5, 2)))print('C_{}^{}={}'.format(5, 2, comb(5, 2)))
if __name__ == '__main__':test()

運行結果為:

5!=120
A_5^2=20
C_5^2=10

由以上準備,我們可求解概率論史上的經典問題(概率論史上的經典問題一般是指違反直覺的那些問題)”生日問題”:

一次聚會上,只要有23個人,就有50%的可能性其中至少有兩個人生日相同,如果人數達到50人,至少有兩個人生日相同的概率達到97%。(這個結論很恐怖,只要是班上的人數超過50,老師便可以說,我們班至少有兩個人生日相同,其實在人數超過23的時候,我們便可以這么說,應為概率占優,注意,是班上會有來個人生日相同,不是說,班上至少存在一個人生日生日與相同)。

當然這類問題從其反問題對立事件出發,1?P()=P()?

p=1?A?23?365?365?23??p=1?A?50?365?365?50???

python 3。

這里的A?50?365??可以理解為,隨意指定一個生日,他生日所在的自由度(或者作可選空間)為365,則下一個人只有365-1的自由度,依次類推。365?50??是考慮到這50個人的生日大體獨立,也即每一個的生日都有365個自由度(也即365種選擇)。所謂概率,頻率的觀點(另有貝葉斯的觀點)來看就是出現的次數與總的可能性之比。

>>> 1-perm(365, 23)/(365**23)
0.5072972343239854
>>> 1-perm(365, 50)/(365**50)   
0.9703735795779884

注意:如果預先指定一個生日,隨機選取125人,250人,500人,出現某人生日正好是這一生日的概率分別是:

1?(364365?)?125?0.290316187907482261?(364365?)?250?0.496348886853832051?(364365?)?500?0.7463355562266258?

python生日祝福,比想象的要小很多,再次說明概率中的許多問題都比較違反直覺。

補充:

365?50?(36550)A?50?50??

為什么不等于呢?在于,左邊 允許重復(同一個位置,既可以是你,也可以是他),右邊 不允許重復

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/176618.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息