




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
模擬與設(shè)計(jì)第九章課程目標(biāo)課程目標(biāo)1理解模擬的應(yīng)用可能是解決現(xiàn)實(shí)問題的一種方式324理解偽隨機(jī)數(shù)及其在蒙特卡羅模擬中的應(yīng)用理解并能應(yīng)用自頂向下和螺旋式設(shè)計(jì)技術(shù)來編寫復(fù)雜的程序理解單元測試,并能將這種技術(shù)應(yīng)用于復(fù)雜程序的實(shí)現(xiàn)和調(diào)試PART1模擬短柄壁球1模擬短柄壁球解決現(xiàn)實(shí)問題的一個(gè)特別強(qiáng)大的技術(shù)就是“模擬”。開發(fā)一個(gè)短柄壁球比賽的簡單模擬。PART2一個(gè)模擬問題2一個(gè)模擬問題Denny酷愛打短柄壁球,但是這幾年來,他經(jīng)常與那些比他好一點(diǎn)點(diǎn)的球員競爭,期間他大多數(shù)是被擊敗的,這讓他很困擾。他覺得如果別人只是比他好一點(diǎn)點(diǎn)他應(yīng)該不會(huì)輸這么多?;蛟S是他對自己的實(shí)力評價(jià)過高,又或許是對別人的實(shí)力評價(jià)過低。又或者是游戲本身的性質(zhì),能力上的小差異會(huì)導(dǎo)致球場上的不平衡比賽。編一個(gè)計(jì)算機(jī)程序來模擬短柄壁球的某些方面。PART3分析和規(guī)格說明3分析和規(guī)格說明短柄壁球是在兩名球員之間使用球拍在四壁球場上打球的運(yùn)動(dòng)。3分析和規(guī)格說明比賽開始時(shí),一名選手將球擊出:這被稱為“發(fā)球”選手交替擊球,使其保持比賽狀態(tài),這是一個(gè)“回合”當(dāng)其中一名選手未能有效擊球時(shí),對打結(jié)束輸家是發(fā)球選手,則發(fā)球權(quán)轉(zhuǎn)給另一名選手發(fā)球選手贏得了這一回合,則會(huì)得1分選手只能在自己發(fā)球時(shí)得分,第一名得到15分的選手贏得比賽。擊球失誤的選手輸?shù)暨@一回合3分析和規(guī)格說明在模擬中,選手的能力水平將由選手在發(fā)球時(shí)贏得回合的概率來表示。程序?qū)⒋蛴〗Y(jié)果摘要將提示用戶輸入兩名選手的發(fā)球回合得分概率用這些概率模擬多局短柄壁球比賽3分析和規(guī)格說明輸入:該程序先提示并獲取兩名選手(稱為“選手A”和“選手B”)的發(fā)球回合得分概率。然后程序提示并獲取要模擬的比賽局?jǐn)?shù)。輸出:該程序?qū)⑻峁┮幌盗械某跏继崾?,如:A贏得比賽的概率是多少?B贏得比賽的概率是多少?一共模擬多少場比賽?3分析和規(guī)格說明游戲模擬:500A贏:268(53.6%)B贏:232(46.4%)注意:所有輸入都被假定為合法的數(shù)值,不需要錯(cuò)誤或有效性檢查。在每次模擬比賽中,都是選手A先發(fā)球。PART4偽隨機(jī)數(shù)4偽隨機(jī)數(shù)偽隨機(jī)數(shù)發(fā)生器從某個(gè)“種子”值開始工作。該值被送入一個(gè)函數(shù)以產(chǎn)生“隨機(jī)”數(shù)字。下次需要一個(gè)隨機(jī)數(shù)時(shí),將當(dāng)前值反饋到該函數(shù)中以產(chǎn)生一個(gè)新的數(shù)字。通過仔細(xì)選擇的函數(shù),得到的值序列基本上是隨機(jī)的。一切都取決于生成函數(shù)和種子的值。4偽隨機(jī)數(shù)Python提供了一個(gè)庫模塊,其中包含一些有用的函數(shù)來生成偽隨機(jī)數(shù)。該模塊中的函數(shù)根據(jù)模塊加載的日期和時(shí)間推導(dǎo)出初始種子值,因此每次運(yùn)行程序時(shí)都會(huì)獲得不同的種子值。randrangerandom
重要函數(shù)4偽隨機(jī)數(shù)>fromrandomimport*>>>randrange(1,6)2>>>randrange(1,6)1>>>randrange(1,6)1>>>randrange(5,105,5)20>>>randrange(5,105,5)70>>>randrange(5,105,5)70>>>randrange(5,105,5)75從給定范圍中選擇一個(gè)偽隨機(jī)整數(shù)4偽隨機(jī)數(shù)>>>fromrandomimport*>>>random()0.7635543105304049>>>random()0.31164370051447243>>>random()0.7039672847873445>>>random()0.5959989547801257用于生成偽隨機(jī)浮點(diǎn)值4偽隨機(jī)數(shù)假設(shè)選手的發(fā)球回合得分概率是0.70。if<playerwinsserve>:score=score+14偽隨機(jī)數(shù)ifrandom()<prob:score=score+1假設(shè)生成一個(gè)0~1之間的隨機(jī)值。區(qū)間(0,1)的70%正好在0.7的左邊。所以70%的時(shí)間隨機(jī)數(shù)將小于0.7,而其他30%的次數(shù)將大于等于0.7。一般來說,如果prob表示選手獲勝的概率,則random()<prob就成功地表示了正確的概率。PART5自頂而下的設(shè)計(jì)5自頂而下的設(shè)計(jì)一種成熟的解決復(fù)雜問題的技術(shù)稱為“自頂向下”。從總問題開始,嘗試用較小的問題來表達(dá)解決方案問題變得很小,以至于它們可以輕松得到解決依次使用相同的技術(shù),攻克每個(gè)較小的問題把所有的小塊都拼回來,大功告成,得到一個(gè)程序PART6頂層設(shè)計(jì)6頂層設(shè)計(jì)打印介紹獲取輸入:probA,probB,n用probA和probB模擬n局短柄壁球比賽打印playerA和playerB的獲勝報(bào)告輸入處理輸出遵循模式:6頂層設(shè)計(jì)打印介紹:defmain():printIntro()
6頂層設(shè)計(jì)從用戶獲取輸入:probA,probB,n:defmain():printIntro()probA,probB,n=getInputs()6頂層設(shè)計(jì)用probA和probB模擬n局短柄壁球比賽:調(diào)用函數(shù)simNGames進(jìn)行模擬比賽需要模擬的場n模擬使用怎樣的probA和probB的值6頂層設(shè)計(jì)用probA和probB模擬n局短柄壁球比賽:defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)6頂層設(shè)計(jì)defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)打印playerA和playerB的獲勝報(bào)告:PART7關(guān)注點(diǎn)分離7關(guān)注點(diǎn)分離defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)7關(guān)注點(diǎn)分離我們已經(jīng)指定了執(zhí)行這些任務(wù)的函數(shù)名稱、參數(shù)和預(yù)期返回值。這些信息稱為函數(shù)的“接口”或“簽名”。唯一關(guān)注的是,如果給出比賽局?jǐn)?shù)和兩個(gè)概率,它必須返回每名選手獲勝的正確局?jǐn)?shù)。main函數(shù)只關(guān)心每個(gè)(子)函數(shù)“做什么”。7關(guān)注點(diǎn)分離圖9.1短柄壁球模擬的一級結(jié)構(gòu)圖7關(guān)注點(diǎn)分離在設(shè)計(jì)的每個(gè)層次上,接口告訴我們下層的哪些細(xì)節(jié)很重要,其他東西都可以暫時(shí)忽略確定某些重要特征并忽略其他細(xì)節(jié)的一般過程稱為“抽象”可以將自頂向下設(shè)計(jì)的整個(gè)過程視為發(fā)現(xiàn)有用抽象的系統(tǒng)方法PART8第二層設(shè)計(jì)第二課時(shí)defprintIntro():print("這個(gè)程序模擬了選手A和選手B之間的短柄壘球游戲,每個(gè)選手")
print("在發(fā)球階段的得分可能性由一個(gè)概率(0和1之間的數(shù)字)來表示,")
print("總是選手A先發(fā)球。")8第二層設(shè)計(jì)8第二層設(shè)計(jì)defgetInputs():#返回三個(gè)參數(shù)probA,probB和na=float(input("A贏得發(fā)球的概率為多少?"))
b=float(input("B贏得發(fā)球的概率是多少?"))
n=int(input("一共模擬多少場比賽?"))
returna,b,n函數(shù)中的變量是該函數(shù)的局部變量。提示輸入獲取三個(gè)值,返回給主程序。PART9設(shè)計(jì)simNGames9設(shè)計(jì)simNGames初始化A和B的勝利場數(shù)為0循環(huán)n次模擬比賽如果A贏A的勝場叫1elseB的勝場加1基本思想是模擬n局比賽,并記錄每名選手的勝利局?jǐn)?shù)。defsimNGames(n,probA,probB):#模擬n次比賽返回winsA和winsBwinsA=0winsB=0foriinrange(n):9設(shè)計(jì)simNGames9設(shè)計(jì)simNGames下面模擬一句短柄壘球比賽。更新結(jié)構(gòu)圖以反映這些決定采用一個(gè)simOneGame函數(shù)來表示一場比賽以他們的成績?yōu)檩敵?,讓simOneGame返回兩名球員的最終成績9設(shè)計(jì)simNGames圖9.2短柄壁球模擬的二級結(jié)構(gòu)圖9設(shè)計(jì)simNGamesdefsimNGames(n,probA,probB):winsA=winsB=0foriinrange(n):scoreA,scoreB=simOneGame(probA,probB)ifscoreA>scoreB:winsA=winsA+1else:winsB=winsB+1returnwinsA,winsBPART10第三層設(shè)計(jì)10第三層設(shè)計(jì)對短柄壁球規(guī)則的邏輯進(jìn)行編碼:如何記錄誰在發(fā)球呢?我要解決simOneGame問題!需要記錄得分知道是誰在發(fā)球用存儲(chǔ)“A”或“B”的字符串變量10第三層設(shè)計(jì)初始化scores為0選手"A"發(fā)球游戲沒結(jié)束時(shí)一直循環(huán):模擬任何一個(gè)正在發(fā)球的球員的發(fā)球更新游戲狀態(tài)返回scores10第三層設(shè)計(jì)defsimOneGame(probA,probB):scoreA=0scoreB=0erving="A"while<condition>:10第三層設(shè)計(jì)只要比賽沒結(jié)束,就需要繼續(xù)循環(huán)這個(gè)條件到底是什么?將細(xì)節(jié)隱藏在另一個(gè)函數(shù)gameOver中,如果比賽結(jié)束,則返回True,否則返回False通過查看分?jǐn)?shù)來判斷游戲是否結(jié)束10第三層設(shè)計(jì)圖9.3短柄壁球模擬的第三層結(jié)構(gòu)圖10第三層設(shè)計(jì)defsimOneGame(probA,probB):scoreA=0scoreB=0serving="A"whilenotgameOver(scoreA,scoreB):如果A在發(fā)球,那么我們需要使用A的概率,并且根據(jù)發(fā)球的結(jié)果,更新A的分?jǐn)?shù),或?qū)l(fā)球更改為B。10第三層設(shè)計(jì)ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"10第三層設(shè)計(jì)ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"else:ifrandom()<probB:scoreB=scoreB+1else:serving="A"10第三層設(shè)計(jì)defsimOneGame(probA,probB):scoreA=0scoreB=0serving="A"whilenotgameOver(scoreA,scoreB):ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"else:ifrandom()<probB:scoreB=scoreB+1else:serving="A"returnscoreA,scoreBPART11整理完成11整理完成defgameOver(a,b):#a和b表示一場壁球游戲的得分#如果游戲結(jié)束,則返回True,否則返回Falsereturna==15orb==1511整理完成fromrandomimportrandomdefmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)
defprintIntro():
print("這個(gè)程序模擬了選手A和選手B之間的短柄壘球游戲,每個(gè)選手")
print("在發(fā)球階段的得分可能性由一個(gè)概率(0和1之間的數(shù)字)來表示,")
print("總是選手A先發(fā)球。")11整理完成defgetInputs():#返回三個(gè)參數(shù)probA,probB和na=float(input("A贏得發(fā)球的概率為多少?"))
b=float(input("B贏得發(fā)球的概率是多少?"))
n=int(input("一共模擬多少場比賽?"))
returna,b,n
defsimNGames(n,probA,probB):winsA=winsB=0foriinrange(n):scoreA,scoreB=simOneGame(probA,probB)ifscoreA>scoreB:winsA=winsA+1else:winsB=winsB+1returnwinsA,winsB11整理完成defsimOneGame(probA,probB):serving="A"scoreA=0scoreB=0whilenotgameOver(scoreA,scoreB):ifserving=="A":ifrandom()<probA:scoreA=scoreA+1else:serving="B"else:ifrandom()<probB:scoreB=scoreB+1else:serving="A"returnscoreA,scoreB11整理完成defgameOver(a,b):#a和b表示一場壁球游戲的得分
#如果游戲結(jié)束,則返回True,否則返回Falsereturna==15orb==15
defprintSummary(winsA,winsB):#打印選手的勝利場數(shù)即概率.
n=winsA+winsBprint("\n模擬游戲:",n)print("A贏:{0}({1:0.1%})".format(winsA,winsA/n))print("B贏:{0}({1:0.1%})".format(winsB,winsB/n))
if__name__=='__main__':main()PART12設(shè)計(jì)過程總結(jié)12設(shè)計(jì)過程總結(jié)自頂向下的設(shè)計(jì)實(shí)戰(zhàn):從結(jié)構(gòu)圖的最高層開始,一路向下。在每個(gè)層次上,我們從總算法開始,然后逐漸將它提煉為精確的代碼。這種方法有時(shí)稱為“逐步求精”。將算法表示為一系列較小的問題用較小問題的接口來表示該算法,從而描述算法的細(xì)節(jié)為每個(gè)小問題開發(fā)一個(gè)接口對每個(gè)較小的問題重復(fù)此過程PART13自底向上的實(shí)現(xiàn)13自底向上的實(shí)現(xiàn)當(dāng)我們有一段完整代碼時(shí),即使我們再小心,但當(dāng)我們測試驗(yàn)證時(shí),還是有時(shí)可能會(huì)對結(jié)果有些失望。PART14單元測試14單元測試圖9.4短柄壁球模擬的第三層結(jié)構(gòu)圖14單元測試>>>gameOver(0,0)False>>>gameOver(5,10)False>>>gameOver(15,3)True>>>gameOver(3,15)True14單元測試>>>simOneGame(.5,.5)(13,15)>>>simOneGame(.5,.5)(15,11)>>>simOneGame(.3,.3)(15,11)>>>simOneGame(.3,.3)(11,15)>>>simOneGame(.4,.9)(4,15)>>>simOneGame(.4,.9)(1,15)>>>simOneGame(.9,.4)(15,3)>>>simOneGame(.9,.4)(15,0)>>>simOneGame(.4,.6)(9,15)>>>simOneGame(.4,.6)(6,15)當(dāng)概率相等時(shí),分?jǐn)?shù)接近。當(dāng)概率相差較大時(shí),比賽就是一邊倒。14單元測試我們可以繼續(xù)這樣的部分實(shí)現(xiàn),將組件添加到代碼中,同時(shí)測試每個(gè)組件。軟件工程師稱這個(gè)過程為“單元測試”。獨(dú)立測試每個(gè)函數(shù)更容易發(fā)現(xiàn)錯(cuò)誤。當(dāng)你測試整個(gè)程序的時(shí)候,有可能一切順利。PART15模擬結(jié)果15模擬結(jié)果假設(shè)Denny贏球的概率為55%,比他強(qiáng)一點(diǎn)的選手贏球概率為60%,我們模擬1000次,運(yùn)行結(jié)果如下:這個(gè)程序模擬了選手A和選手B之間的短柄壘球游戲,每個(gè)選手在發(fā)球階段的得分可能性由一個(gè)概率(0和1之間的數(shù)字)來表示,總是選手A先發(fā)球。A贏得發(fā)球的概率為多少?0.55B贏得發(fā)球的概率是多少?0.6一共模擬多少場比賽?1000
模擬游戲:1000A贏:389(38.9%)B贏:611(61.1%)當(dāng)相差很小時(shí),Denny獲勝的概率大概為三分之一。所以Denny輸?shù)牟辉?。PART16其他設(shè)計(jì)技術(shù)16其他設(shè)計(jì)技術(shù)自頂向下的設(shè)計(jì)是一種非常強(qiáng)大的程序設(shè)計(jì)技術(shù),但并不是創(chuàng)建程序的唯一方法。PART17原型與螺旋式開發(fā)17原型與螺旋式開發(fā)另一種設(shè)計(jì)方法是從程序或程序組件的簡單版本開始,然后嘗試逐漸添加功能,直到滿足完整的規(guī)格說明。初始的樸素版本稱為“原型”。原型通常會(huì)導(dǎo)致一種“螺旋式”開發(fā)過程。設(shè)計(jì)、實(shí)現(xiàn)并測試一個(gè)原型新功能被設(shè)計(jì)、實(shí)現(xiàn)和測試在開發(fā)過程中,完成許多小循環(huán),原型逐漸擴(kuò)展為最終的程序17原型與螺旋式開發(fā)例:如何開發(fā)短柄壁球模擬。問題的本質(zhì)在于模擬一個(gè)短柄壁球的比賽。我們可能就從simOneGame函數(shù)開始。進(jìn)一步簡化,的原型可以假設(shè)每名選手有一半對一半的機(jī)會(huì)贏得每一分,并且只比賽30回合。這需要考慮問題的關(guān)鍵,即處理得分和換發(fā)球。17原型與螺旋式開發(fā)fromrandomimportrandomdefsimOneGame():scoreA=0scoreB=0serving="A"foriinrange(30):ifserving=="A":ifrandom()<.5:scoreA=scoreA+1else:serving="B"else:ifrandom()<.5:scoreB=scoreB+1else:serving="A"print(scoreA,scoreB)
if__name__==’__main__’:simOneGame()17原型與螺旋式開發(fā)101020...777817原型與螺旋式開發(fā)初始原型。比賽30回合,發(fā)球者總是有50%的獲勝機(jī)率。打印出每次發(fā)球后的分?jǐn)?shù)。添加兩個(gè)參數(shù),表示兩名選手的不同概率。比賽直到其中一名選手得到15分。此時(shí),我們有了能工作的一局比賽的模擬。構(gòu)建完整的程序。添加交互式輸入和格式漂亮的結(jié)果報(bào)告。擴(kuò)展進(jìn)行多局比賽。輸出是每名選手贏得的比賽數(shù)量。階段1階段3階段4階段2階段5PART18設(shè)計(jì)的藝術(shù)18設(shè)計(jì)的藝術(shù)要注意的是,螺旋式開發(fā)不是自頂向下設(shè)計(jì)的替代品。相反,它們是互補(bǔ)的方法。在設(shè)計(jì)原型時(shí),你仍然會(huì)使用自頂向下的技術(shù)。設(shè)計(jì)沒有“唯一正確的方式”。事實(shí)上,良好的設(shè)計(jì)與科學(xué)一樣是一個(gè)創(chuàng)造性的過程。事后可以對設(shè)計(jì)細(xì)致地分析,但是沒有生成設(shè)計(jì)的硬性規(guī)則。課程目標(biāo)小結(jié)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山西華澳商貿(mào)職業(yè)學(xué)院《臨床檢驗(yàn)儀器》2023-2024學(xué)年第二學(xué)期期末試卷
- 濟(jì)南護(hù)理職業(yè)學(xué)院《嵌入式課程設(shè)計(jì)》2023-2024學(xué)年第二學(xué)期期末試卷
- 臨床免疫學(xué)檢驗(yàn)課件 第3章 免疫原和抗血清的制備學(xué)習(xí)資料
- 西安海棠職業(yè)學(xué)院《隸書》2023-2024學(xué)年第一學(xué)期期末試卷
- 江蘇農(nóng)牧科技職業(yè)學(xué)院《硬筆書法》2023-2024學(xué)年第一學(xué)期期末試卷
- 鹽城工業(yè)職業(yè)技術(shù)學(xué)院《工商管理級學(xué)碩》2023-2024學(xué)年第二學(xué)期期末試卷
- 二零二五版資金監(jiān)管委托協(xié)議樣本
- 二零二五全新美食城檔口出租協(xié)議
- 二零二五版學(xué)生托人接送免責(zé)協(xié)議書范文
- 游戲開發(fā)回顧與展望
- 幼兒園教育評估指南解讀
- 模擬雨的形成課件
- 多維數(shù)據(jù)循環(huán)嵌套分析-全面剖析
- 數(shù)學(xué)全等三角形教學(xué)設(shè)計(jì) 2024-2025學(xué)年北師大版數(shù)學(xué)七年級下冊
- 《旅游策劃實(shí)務(wù)》課件-《秦嶺北望 千古》長安西安五天四晚親子家庭定制游方案
- 事故隱患內(nèi)部報(bào)告獎(jiǎng)勵(lì)制度1
- 建設(shè)單位保證安全生產(chǎn)措施方案
- 2025年新音樂節(jié)明星藝人歌手演出場費(fèi)報(bào)價(jià)單
- 2025年人保應(yīng)聘考試試題及答案
- 新視野大學(xué)英語(第四版)讀寫教程2(思政智慧版) 教案 Unit 5 Striving for financial health
- 幼兒園獲獎(jiǎng)公開課:大班科學(xué)活動(dòng)《茶》課件
評論
0/150
提交評論