這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

《計算思維與Python編程》是我們早期的Mathematics for the Digital Age and Programming in Python一書的 “更早講Python”的版本。在本書中,我們更早地介紹了Python特性,爲讀者提供了必要的工具,使讀者可以更快地以更加“Python式(pythonic)”的慣用方式,開始編寫Python代碼。在本書中,我們增加了兩章(“第9章 海龜繪圖”和“第14章 向量和矩陣”),以及介紹斐波那契數列的一節(“第10章 序列與和”的10.5節);更新了許多示例、練習和解答;更改了標題,從而更好地匹配這一系列主題和快速變化的技術環境與詞彙。

但《計算思維與Python編程》的主要理念仍然沒有改變:介紹離散數學概念和思維,我們認爲這些概念是所有有基礎的編程人員的基本知識。這種數學知識很容易學習,但美國大多數中小學數學課程還沒有包括離散數學的內容。本書的數學部分包括許多動手編程練習,這些練習可以強化學生對編程和數學的認識。

“那麼,這是一本數學書還是一本計算機編程書?”這可能是心急的讀者心中的第一個問題。但爲什麼必須選擇呢?這是圖書管理員的困境:“它是屬於數學類還是計算機類?”有一個簡單的解決方案:在每類書架上各放一本。

本書的目的是教授一種特定的思維方式——精確思維,以及如何解決需要這種思維方式的問題。數學和計算機編程都能培養精確思維的能力,並解決那些需要精確解的問題。

數學教會我們欣賞嚴謹論證的美。從長遠來看,這比解決當前實際問題的課程更有價值。數學並不是存在於真空中的——它的抽象植根於幾個世紀以來積累的實踐知識。數學教學借鑑了我們周圍世界的例子和類比,至少它應該如此。然而,我們周圍的世界變化得越來越快。在過去的五六十年間,我們的世界變得數字化了。這種變化如此深刻,以至於人們有時難以完全理解。我們的中小學數學課程在很大程度上忽略了這種變化,這是否就是人們難以理解這種變化的原因?

如果我們能夠造出“時間機器”,讓歐幾里得穿越時空來到現代化的世界,他會覺得很欣慰,因爲在現代技術的浪潮中,他熟悉的幾何學仍然在學校裏教授。“老對手”牛頓和萊布尼茨都會感到非常滿意,因爲成千上萬的美國高二和高三學生正在學習如何求導和使用積分。但是,離現在不遠的喬治·布爾(George Boole),儘管他的名字在每一種現代計算機編程語言中都是不朽的,但他仍然需要搜尋幾十本教材才能找到他提出的代數。至於約翰·馮·諾依曼(John von Neumann),這位才華橫溢的數學家,也是計算機技術的先驅之一……好吧,按照他一貫的樂觀態度,他會預測在20年左右的時間裏,每個小學生都會學習與門、或門和非門。但是,爲什麼事實不是如此呢?

在《計算思維與Python編程》中,我們彙集了一些與數字世界相關的更容易理解的數學主題。其中許多主題,通常在大學新生課程中以“離散數學”之名講授。離散數學已成爲所有基礎數學的代名詞,但在標準的初中和高中代數、微積分初步和微積分課程中,這種數學都被忽略了。在20世紀70年代,唐納德·克努特(Donald Knuth)和他在斯坦福大學的同事創造了“具體數學”這一名詞(融合了連續數學和離散數學,並且也很具體,不是太抽象),來描述克努特在斯坦福大學教授的課程。後來,“具體數學”成爲了他們的一本閱讀起來很愉快的書的標題[1]。正如他們在序言中解釋的那樣,克努特“發現他的技能中缺少一些數學工具,他需要一些數學工具,以便對計算機程序有徹底的、充分的理解,這些數學工具與他在大學裏作爲數學專業學生所學的東西完全不同”。

因此,如果你對計算機編程感興趣,我們希望本書能讓你成爲更好的計算機程序員。如果你對數學更感興趣,你將有充分的機會解決有趣的問題,並在計算機程序中,對其中的一些問題進行建模。你將熟悉通常初中生和高中生不會接觸到的有趣的數學;你將學會解決真實問題(即你事先並不知道如何解決的問題);你將感受到數學推理和證明的力量。作爲獎勵,你將獲得Python(一種流行的經濟有效的編程語言)編程的實用技能。

我們選擇Python有幾個原因。首先,Python讓你有機會在交互式環境中,通過即時反饋來體驗該語言。其次,Python的語法並不太複雜。再次,Python具有簡單但強大的功能,可用於處理列表和“字典”(映射)。最後,Python易於安裝和使用,它是免費的。當然,還有其他編程語言具有類似的屬性,可以滿足我們的需求。歸根結底,重要的不是特定的編程語言,而是能夠精確地思考數學知識和計算機程序。

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

  • 這本書在美國高中和大學的相關課程中都獲得了巨大成功;
  • 本書文字優美、引人入勝;

教授基本的Python編程技能,並提高讀者的計算思維能力和數學水平。 
我曾經這樣告訴校長:"通常,我們很難去誇獎教材,但這本書的確是一本出色的教材"。 
——Michel Paul,美國比佛利山莊高中 
我一般不會寫評論,但是這本書值得!實際上,閱讀這本書,你可以學習數學和Python編程的方方面面,這在學習更高水平的Python編程時將非常有用。我是一名新手程序員,迫切需要這樣一本書! 
——Willis Cook,讀者 
這是一本精彩的圖書,闡釋了包括數論在內的豐富的數學知識。高中生就能夠理解這些內容,並完成書中的編程示例和問題。 
——Earl J. Strassberger,美國芝加哥公立學校

樣章試讀:第13章 概率

13.1 引言

當我們擲一對骰子時,得到11點的可能性是多少?7點或11點,哪個更有可能?如果我們擲一對骰子100次,我們大概會得到多少次11點?概率論可以幫助回答這些問題。

事件的概率是介於0和1之間的數字,用於描述當我們多次重複實驗時發生該事件的可能性。0意味着事件永遠不會發生,1表示事件總是發生,0.5表示事件大約在一半情況下發生。

要詢問和回答有關概率的問題,我們首先需要正式描述事件是什麼,然後我們可以找出一種計算事件概率的方法。

假設我們有一個實驗產生一些結果(一個數字、一個事物或一個特定的事物組合)。所有可能結果的集合稱爲實驗的“概率空間”。在本書中,我們僅處理具有有限數量的可能結果的實驗。換句話說,概率空間是有限集。例如,當我們擲出表面上有1、2、3、4、5和6點的骰子時,有6種可能的結果,因此概率空間是一組6個元素的集合,{1, 2, 3, 4 , 5, 6}。

“事件”被定義爲概率空間的子集,它由滿足特定標準的所有“有利”結果組成。我們可以定義以下事件:骰子上的點數爲3或更大。此事件可以描述爲集合{3, 4, 5, 6}。事件的其他例子:骰子上的點數是偶數,{2, 4, 6};點數是6,{6}。在後一個例子中,事件是僅有一個元素的概率空間的子集。

13.2 通過計數計算概率

如果概率空間中的所有結果可能性相等,事件的概率被定義爲有利結果的數量與所有可能結果的數量的比值。

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

 

例1

當我們擲出表面上有1、2、3、4、5和6點的骰子時,獲得3點或更大點的概率是多少?

有6種可能的結果,6種結果的可能性都是相等的。其中4種結果點數爲3或以上,即{3, 4, 5, 6}。因此,獲得3點或更大點的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

=

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

✦ ✦ ✦

當我們擲一對骰子時,情況稍微複雜一些。這種情況下我們如何定義概率空間?第一個骰子和第二個骰子上的任何點組合都是不同的結果。那麼概率空間將由36個元素組成(見圖13-1)。同樣,36種不同結果中的每一種的可能性都是相等的。

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

圖13-1 擲出兩個骰子的可能結果的概率空間有36個元素,第一個和第二個骰子上所有可能的點的組合

例2

當我們擲一對骰子時,骰子上的點總和是11的概率是多少?總和是7的概率是多少?

得到11的概率可以計算爲2/36 = 1/18,因爲正好有2個可能的結果產生總和11點,即5 + 6和6 + 5。得到7的概率是6/36 = 1/6,因爲有6個可能的結果得到總和7點1 + 6、2 + 5、3 + 4、4 + 3、5 + 2和6 + 1(見圖13-2)。

✦ ✦ ✦

當整個概率空間被分成幾個非重疊事件時,這些事件的概率和總是1。

圖13-2展示了一個例子。

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

圖13-2 在一對骰子上獲得一定點數的概率

你可能想知道:如果我們對兩個骰子上的點數之和感興趣,爲什麼不選擇一個只包含11個元素的簡單概率空間,可能的總和爲2,3,…,12?從技術上講,我們可以這麼做,但這樣的概率空間不會非常有用。因爲正如我們所看到的,這個概率空間中的不同結果具有不同的概率。這個概率空間無助於我們計算每個結果的概率,也無法計算各種其他事件的概率。

當我們爲問題構造概率空間時,總是嘗試選擇一個所有結果具有相同概率的空間。

在所有結果具有相同概率的空間中,每個結果的概率是1/n,其中n是所有可能結果的數量。然後,我們可以簡單地計數滿足事件標準的結果數量,並將該計數除以n,從而求出事件的概率。

✦ ✦ ✦

有時我們可以針對相同的情況,以不同的方式定義概率空間,但對於相同事件的概率,我們應該得到相同的結果。

例3

如果我們從52張牌中隨機抽出2張牌,抽到2張A的概率是多少?

我們可以將概率空間定義爲所有牌對的集合(忽略牌對中兩張牌的順序)。有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種方法可以從52張牌中選擇一對牌。有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種方法可以從4個A中選擇一對A(有利的結果)。答案是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

另解:我們可以將概率空間定義爲所有有序牌對的集合。這個空間中的元素數量是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,有序的A對的數量是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。我們得到了同樣的答案:

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

例4

如果我們拋3次硬幣,那麼出現剛好2次正面朝上的概率是多少?

這裏的概率空間是{HHH, HHT, HTH, HTT, THH, THT, TTH, TTT},期望的結果是{HHT, HTH, THH}。答案是3/8。

第13.2節練習

1.如果隨機猜測5個答案選項的多項選擇題,猜中正確答案的概率是多少? ✔

2.如果你擲2個骰子,那麼點數的總和大於7的概率是多少?

3.你必須在36個方格的網格上標記正確的6個方格。你標記正確的概率是多少?✔

4.如果你拋硬幣5次,出現至少4次反面的概率是多少?

5.輪盤中有36個槽的編號爲1~36,另有2個槽,標記爲0,表示對於獲勝。36個槽18個紅色和18個黑色交替,0是綠色。如果你選擇17號槽,獲勝的概率是多少?如果你選擇“紅色”,獲勝的概率是多少(如果球擊中任何紅色位置你就贏了)? ✔

6.從前50個正整數中隨機選擇的數字,被3整除的概率是多少?

7.隨機選擇兩位正整數(即10到99之間的整數),兩個數字相同的概率是多少?

8.■編寫一個Python程序,計算在擲3個骰子時獲得不同點數總和(3~18)的概率。什麼點數總和出現概率最高? »提示:初始化一個計數列表,全部設置爲0,然後在三個骰子上生成所有可能的點組合,併爲每個組合增加適當的計數。«

13.3 更多通過計數的概率

我們知道,要計算事件的概率,必須計算所有“有利”結果的數量,並將它除以所有可能結果的數量。當我們進行計數時,可以回顧在第12章的組合學問題中學到的所有技巧。

例1

如果5張牌是從52張牌中隨機發出的,獲得“兩對”的概率是多少(即一對牌有一樣的牌面數字,另一對牌有一樣的牌面數字,剩下那張牌有不一樣的牌面數字)?

發5張牌的方法總數是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。爲了形成“兩對”,讓我們首先從13種牌面大小中選擇2種作爲對子,有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種辦法。對於每一種牌面數字,有6種方法可以從4張牌中選擇2張。最後有44種方法可以選擇剩下的牌(從剩下的11種牌面數字選擇)。答案是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

例2

袋中有60個果凍豆,其中,15個是紅色,15個是藍色,15個是綠色,15個是黃色。丹尼已經拿出1個紅色的果凍豆和1個藍色的果凍豆,袋子裏還剩58個果凍豆。如果丹尼隨機再拿出3個果凍豆,他最終得到3個顏色相同的果凍豆的概率是多少?

我們將使用計數的加法和乘法規則。對於有利的結果,有4種相互排斥的可能性:丹尼最終會得到3個紅色、3個藍色、3個綠色或3個黃色的果凍豆。要得到3個紅色的果凍豆,他需要選擇袋子裏剩下的14個紅色果凍豆中的2個,有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種辦法。然後他需要再選擇一個不是紅色的果凍豆,有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種辦法。因此,有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種方法拿5個果凍豆,其中3個是紅色。拿出3個藍色果凍豆的方法總數相同。要獲得3個綠色果凍豆,丹尼需要在15個綠色果凍豆中選擇3個,有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種方法。同樣,有455種方法可以選擇3個黃色果凍豆。有利結果的總數是4004 + 4004 + 455 + 455 = 8918。所有可能結果的總數是從58個果凍豆中選擇3個果凍豆的方法的數量,即

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。獲得3個相同顏色的果凍豆的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

✦ ✦ ✦

當我們將概率計算爲有利結果的數量與所有可能結果的數量的比率時,概率空間中的所有可能結果具有相等的概率是非常重要的。如果不是這樣,那麼簡單比率方法將導致答案錯誤。

例3

考慮兩個玩家之間的遊戲。每個玩家最多擲3次硬幣,誰先獲得正面誰勝。如果他們第一次得到硬幣的同一面,就會進行一個決勝局;如果再次得到相同的一面,他們會進行另一個決勝局。第一個玩家獲勝的概率是多少?

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

在一個不成熟的方法中,我們會考慮所有可能的遊戲過程:

有7種可能的方式玩家A會贏,有7種可能的方式玩家B會贏。遊戲有8種可能的方式以平局結束。

似乎玩家A獲勝的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。答案錯誤!上面列出的22種可能的遊戲過程,不是等可能的。爲了看到這一點,讓我們允許每個玩家擲3次,無論發生何種情況,最後才決定勝利者。

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

這裏*是一個通配符,可以代表硬幣的任何一面。這個新的概率空間定義恰當,所有結果都是等可能的,舊的概率空間沒有這個屬性。正如我們現在所看到的,H/T遊戲的獲勝概率實際上是HH/HT的遊戲的4倍,是HHH/HHT遊戲的16倍。

新概率空間可能的結果總數是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,正確的答案是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

在這個例子中,我們不必計算所有獲勝組合數。根據玩家的對稱性,有一個快捷方法:結果總數是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,平局遊戲結果的數量是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,所以玩家A獲勝的結果數量是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

第13.3節練習

1.在一副牌(52張)中獲得“4張同點”撲克牌的概率是多少(同一牌面大小的4張牌加上任意第五張牌)?✔

2.■“皇家同花順”是最好的牌,即同一花色的A、K、Q、J和10。當你從一套標準的52張牌中隨機發出5張牌時,獲得皇家同花順的概率是多少?✔

3.■在“十點”基諾遊戲中,你在一張有80個數字的卡片上標記10個“點”(數字),然後對手隨機挑選20個數字。要贏得勝利,你需要讓10個數字全被對手數字“擊中”。贏得勝利的概率是多少?(基諾遊戲給玩家帶來了所有遊戲中最小的獲勝概率。)✔

4.■一個袋子中有3個紅色大理石和5個藍色大理石。如果你隨機抽出4個,得到2個紅色和2個藍色的概率是多少?

5.◆ 從52張牌中抽牌,直到得到2張牌面數字相同的牌。不超過3張牌就結束的概率是多少?✔

6.◆ 書中的頁面編號爲1到96。我們剪下所有頁碼並將它們剪成單獨的數字,從中隨機選擇兩個數字,它們的和爲10的概率是多少?

7.◆ 將16個檯球隨機放入6個口袋中。(假設一個口袋可以容納任意數量的球。)東北角口袋少於3個球的概率是多少? ✔

8.◆ 隨機的21點的3張牌,值爲21點的概率是多少?在21點中,每張數字牌按由2到10的面值計數;A算作1或11,你可以選擇一種;其他“圖片”牌(J、Q或K)計爲10。 ✔

13.4 乘法、加法和減法

還記得我們如何使用乘法、加法和減法來計數嗎?當然,在計算“有利”結果和實驗的所有可能結果的數量時,我們可以應用這些方法。但有一條捷徑:我們可以直接對概率應用乘法、加法和減法運算。讓我們從乘法開始。

假設我們有兩個相互獨立的實驗。假設事件A可以在第一個實驗中發生,事件B可以在第二個實驗中發生。A和B在各自實驗中發生的概率是A的概率乘以B的概率。

例1

如果我們連續擲兩次骰子,獲得兩個6的概率是多少?

第一次擲骰子得到6的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,第二次得到6的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。連續獲得兩個6的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。注意,擲兩次骰子與同時擲兩個一樣的骰子相同。

例2

我有3個信封。其中兩個有1美元,第3個是空的。你可以帶走任意兩個信封。你最終得到兩美元的概率是多少?

拿第一個信封時,獲得1美元的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。如果你得到第一個1美元,從剩下的兩個信封獲得第二個1美元的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。獲得2美元的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。如果我們假設第一個實驗在第二個實驗之前是成功的,乘法規則仍然有效。這類似於計數組合而沒有重複,正如我們在12.3節中討論的那樣。

✦ ✦ ✦

概率可以在兩種情況下相乘:當事件彼此獨立時,如上面的例1所示;當基於第一事件已經發生的假設成立計算第二事件的概率時 ,如上面的例2所示。

例3

在加勒比海的尼維斯島上,平均每年降雨45天。連續兩天下雨的概率是多少?

這是一個棘手的問題。你可能想應用乘法規則,並說概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。但是,乘法規則要求事件彼此獨立地發生,天氣情況不是這樣,在尼維斯島,雨季是9月和10月,在這兩個月裏連續兩天降雨很有可能。爲了論證這一問題,假設在某個神祕島上,45個雨天總是在9月1日到10月15日之間,並且在一年中的其餘時間裏根本不會下雨。那麼,如果我們隨機選擇一年中連續兩天,則兩天都會下雨的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。如果沒有關於全年雨天分佈的更多信息,我們無法回答最初關於尼維斯島的問題。

✦ ✦ ✦

當我們需要找到可以分成兩個無重疊事件的事件概率時,使用加法。

例4

在擲骰子的遊戲中,你擲兩個骰子。如果你擲到7或11,你就贏了;如果你擲到2、3或12,就輸了;其他情況遊戲繼續。在第一次擲骰子上贏或輸的概率是多少?

在第一次擲骰子時獲勝的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

(見圖13-2);在第一次擲骰子時失敗的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。(但這不是遊戲的結束,獲勝規則是這樣的:最終在遊戲中贏得超過一半的比賽。)

例5

在“隨機行走”中,你可以隨機選擇下一步行走的方向(前進、後退、左或右),它們具有相同的概率。兩步後返回起始位置的概率是多少?

有以下4個序列在兩步後可返回起始位置,{前,後}、{後,前}、{左,右}和{右,左}。每個序列發生的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。4個序列中的任何一個發生的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

✦ ✦ ✦

如果事件發生的概率爲p,則不發生同一事件的概率爲1−p。

例6

戴夫擊出本壘打的概率是0.13。戴夫不會擊出本壘打的概率是多少?

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

例7

艾米莉平均每15次用飛鏢擊中“靶心”1次。艾米莉在3次嘗試中至少會擊中靶心1次的概率是多少?

假設艾米莉擊中靶心的概率爲p,錯過靶心的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。則艾米莉連續3次錯過靶心的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,3次嘗試中至少1次擊中靶心的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。這裏

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。答案是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

第13.4節練習

1.連續3次擲骰子都得到3的概率是多少? ✔

2.在Scrabble中,有98個寫有字母的方塊。有2個B、9個A和6個T。如果你從盒子中隨機拿出3個方塊,每次將方塊放回到盒子中,按順序獲得B、A、T的概率是多少?

3.擲3次骰子而從未得到6的概率是多少?至少得到一次6的概率是多少? ✔

4.■ 如例5所述,在隨機行走時,你在4步後返回起始位置的概率是多少?

5.■在壁球比賽中,一連串連續的擊球被稱爲1個回合。當你發球時,要得分,你需要贏得該回合。如果你的對手發球,贏得1個回合只是給你下一個發球的權利。如果艾莉在她發球時,平均贏得10個回合中的4個;在她的對手發球時,贏得10個回合中的3個。那麼從對手發球開始,2回合後,艾莉得一分(一球一分)的概率是多少? ✔

6.◆ 練習題5描述了壁球得分的規則。不管是誰發球,蘇珊平均在3個回合中有2個回合擊敗吉米。如果蘇珊開始發球,她在3個回合中贏得下一分的概率是多少?在5個回合中蘇珊最終會贏得下一分的概率是多少? »提示:在情況下,我們得到一個無窮極數,但我們已經知道如何處理它……« ✔

7.◆ 如果選手發球,並且選手的對手和選手水平相當(也就是說,每個選手贏得一個回合的概率是0.5,無論誰發球),那麼選手在壁球中贏得下一分的概率是多少(參見練習題6)?

8.◆ 一個飛鏢靶有20個外部扇區,20個內部扇區和一個叫“靶心”的中心。如果平均而言,在30次嘗試中擊中靶心一次,內部扇區5次(在它們中間等可能),外部扇區20次,完全錯過了4次。那麼連續兩次擊中同一扇區(或靶心)的概率是多少?✔

9.◆ 在某抽獎活動中,你可以從42個數字中選擇6個數字。如果你的數字與計算機抽出的數字相匹配,那麼你將獲得累積獎金。計算機還抽出第七個“鼓勵”數字。如果你沒有中獎,但是你的6個數字與電腦抽取的7個數字(包括鼓勵數字)中的任意6個數字相匹配,你將獲得10000美元的安慰鼓勵獎。還有其他獎品,但它們相對較小。只有當你的“平均贏額”(中獎概率乘獎金的大小,加上安慰鼓勵獎的概率乘以鼓勵獎金的大小)超過票價時,你才決定玩遊戲。如果一張票的價格爲1.00美元,那麼累積獎金達到多少才值得你玩?

10.◆ 一個棋子從棋盤左下角的黑色方格開始移動。在每次移動中,棋子以相同的概率向上或向右移動一個方格,它到達右邊或頂邊時停止。棋子最後在黑色方格上的概率是多少? »提示:擴展棋盤,使它形成一個等邊直角三角形,直角在左下角,並將所有路徑延伸到它的斜邊,使所有路徑的長度相等。«

13.5 僞隨機數

計算機應該是可預測的,從相同的位置開始,執行相同的步驟,你應該得到相同的結果。但有時我們希望計算機隨機行動。例如,在遊戲和隨機過程的計算機模擬中,隨機行動是有用的。

典型的編程語言具有生成“隨機”數字的庫函數。這些數字是利用某種算法在軟件中生成的,因此它們並非真正隨機,但它們近似於隨機行爲。這些數字稱爲“僞隨機數”。

Python庫有一個random模塊,它有許多生成和返回隨機數的函數。要獲取隨機整數r,a

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

r

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

b,請將函數randint導入random模塊,並調用randint(a, b)。例如:

>>> from random import randint
>>> randint(1,3)
2
>>> randint(1,3)
3
>>> randint(1,3)
3
>>> randint(1,3)
1
>>> randint(1,3)
2

(你的顯示可能會有所不同,因爲randint會返回僞隨機數。)

來自同一模塊的random函數返回一個浮點型數x,0.0

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

x<1.0。例如:

>>> from random import random
>>> random()
0.21503763019111777
>>> random()
0.80958843480468412

另一個choice函數從字符串(或元組、列表或任何其他“序列”中的元素)中選擇隨機字符並返回。例如:

>>> from random import choice
>>> choice('ABC')
'B'
>>> choice('ABC')
'A'
>>> choice('ABC')
'A'

shuffle函數以隨機順序重新排列列表的元素。例如:

>>> from random import shuffle
>>> lst = [1, 2, 3, 4, 5]
>>> shuffle(lst)
>>> lst
[5, 2, 3, 1, 4]

✦ ✦ ✦

有時,理論上的解決方案爲我們提供了一個公式,但數字可能太大或難以計算。於是,計算機可以提供幫助,通過計算或對隨機過程建模並觀察結果。這種模型被稱爲“蒙特卡羅模擬”。

在25人中,更有可能的是有兩個人同一天生日,還是每個人的生日在不同的一天?

我們假設一個生日可以是365天中的任何一天(忽略閏年)。一種方法是通過編程進行蒙特卡羅模擬,生成一組隨機的25個生日,並檢查是否有兩個生日在同一天。比方說,重複10,000次,並計數有多少組有兩人同一天生日,有多少組沒有。這個程序留給你作爲練習(見練習題6)。

解決生日問題的另一種方法是使用我們學到的知識,在理論上計算概率。第一個人的生日可以是365天中的任意一天,第二個人也是,依此類推。利用乘法規則,我們發現有36525種生日的可能排列。利用沒有重複的乘法規則,我們得出結論,當所有25個人生日都不同時,有

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

種排列。因此,所有人生日不同的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

,而至少兩個人生日相同的概率是

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

現在讓我們針對n個人的情況解決同樣的問題。不需額外的工作,我們就能夠得到“交叉點”:當概率大於1/2時的人數。請嘗試猜測這個數字,這只是爲了檢查一下你的直覺!

似乎我們必須處理分子和分母非常大的數字。例如,36525有65位數字。(我們用Python發現了這個數字。)Python支持大整數,其中一個數字可以有任意長度,僅受計算機內存大小的限制。當常規的4字節int值超出範圍時,Python會自動切換到使用更長的值。所以在Python中,我們可以直接計算分數的分子和分母,取其比值並完成。然而,在其他語言中,處理非常大的數字可能涉及更多工作。幸運的是,我們可以更簡便地處理這個問題,不用大整數。請注意,我們可以將比率分成單個分數的乘積:

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

。這樣很容易將每個分數計算爲一個浮點型數據。在練習題5中,你將完成這個程序。

第13.5節練習

1.編寫並測試一個Python函數,該函數從52張牌中隨機選擇5張牌。每張牌由一對數據(一個元組)描述,保存牌的花色(“S”“H”“D”“C”表示黑桃、紅桃、方塊、草花)和牌面數字(1到13)。 ✔

2.假設你有一個Python函數random_letter,它返回字母表的一個隨機字母(26個字母的概率大致相等)。random_letter連續返回3個元音字母(AEIOU)的概率是多少? ✔

3.編寫一個Python函數random_letter,如練習題2所述。運行3次以查看是否得到連續3個元音。重複100,000次,統計連續3個元音的次數,並估計這種事件發生的概率。將你的結果與你在練習題2中獲得的理論概率進行比較。

4.編寫一個使用蒙特卡羅方法估算 的程序。將一百萬個隨機(虛擬)點“投擲”到一個單位正方形中,並計數它們與原點的距離小於1的點的數量。

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

5.■ 使用本節中描述的理論方法,編寫一個程序,輸出n個人中至少有兩個人具有相同生日的概率,n取值爲1到50,不使用太大的整數。這個程序只有幾行代碼。輸出應如下所示:

 1: 0.000
 2: 0.003
 3: 0.008

...

48: 0.961
49: 0.966
50: 0.970

注意“OBOBs”(off-by-one bugs,差1錯誤),當程序中的循環運行少一次或多一次時,我們就說發生了這種錯誤。根據輸出結果確定,概率大於0.5的n的值。

6.■編寫一個程序,實現蒙特卡羅模擬。編寫一個生成n個隨機生日列表的函數(數字從1到365),如果列表中的所有數字都不同,則返回True。儘量多地調用此函數,以計算n中至少有兩個人具有相同生日的概率。將你的結果與練習題5中獲得的理論結果進行比較。 »提示:找出生成的數字是否有重複的簡單方法是,分配365個計數變量,並針對每個隨機數遞增適當的計數變量,然後檢查是否有任何計數變量大於1。«

7.■在海龜繪圖中,繪製一個以原點爲中心的半徑爲100的圓,然後將海龜歸回原點(到原點)。模擬隨機行走,在每次移動中,將海龜的方向設置爲0度、90度、180度或270度,以相等的概率隨機選擇,然後向前移動20。保持筆落下以查看海龜的路徑,計算並報告海龜離開圓圈所需的步數。 »提示:turtle的函數distance (x,y)返回從當前海龜位置到點(x, y)的距離。«

8.■下面的函數從序列s中返回一個隨機的正數:

def positive_choice(s):
    lst = [x for x in s if x > 0]
    if len(lst) > 0:
        return choice(lst)

列表中的每個正數有相同的概率被選中。重寫此函數,不從s創建任何臨時正數列表或集合,也不提前計算它們的數量。 »提示:假設r保存從s的前k個正數中隨機選擇的一個正數,從k = 0和r = None開始。當你取得下一個正數x時,你可以保持r不變或用x替換r。用x替換r的概率應該是多少?(你永遠不會知道:x可能是s中的最後一個正數。你需要給它一個公平的機會……)«

在(−1, 1, 2, 0, 3, −2, 4, 5, −6)上運行你的positive_choice函數,比方說10000次,從而測試它,並計算每個數字1、2、3、4、5的返回次數。所有數字的返回次數應該在2000左右,計數與2000的差距不大於120。 ✔

9.■本題探討將多個隨機數加在一起時會發生什麼。寫一個簡短的程序,幫助你做到這一點。創建一個包含100個計數器的列表:counters = 100*[0]。運行以下程序:取100個隨機數r,0

這是一本數學書還是一本編程書?學好數學,讓你成爲更好的程序員

 

r<1(由random函數返回)的總和,將和截斷爲整數,得到i,並遞增計數器counters[i]。重複這些步驟,比如重複2000次。然後在計數器中將值顯示爲海龜繪圖中的垂直線段(一種簡單的條形圖)。生成的圖是什麼樣的?

»提示:

for i in range(100):
    x = x_offset + x_scale*i
    y = y_scale*counters[i]
    ...

使用合理的偏移量和縮放比:

x_offset, y_offset = -200, -100
x_scale, y_scale = 5, 1

使用goto(x, y)繪製。

13.6 複習

本章介紹的術語。

概率

概率空間

獨立事件

概率的乘法規則

概率的加法和減法規則

蒙特卡羅模擬

隨機行走

本章介紹的一些Python特性。

from random import randint, random, choice, shuffle
randint(m, n)
random()
choice(s)
shuffle(lst)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章