您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > AI人工智能 > python课件Chapter09-ch
1模拟与设计2模拟•我们目前掌握的工具已经足以解决一些有意思的问题.–有意思是指:如果不设计实现计算机算法,该问题是很难或不可能解决的.•模拟:用计算机为实际问题建模,从而提供非如此不能获得的信息.–这是解决实际问题的强大技术,每天都在应用:•天气预报•设计飞机•制作电影特效•......3美式壁球基本知识•球,球拍,场地•一人发球开始比赛•然后两人交替击球(称为一个rally)•当一人未能击出合法球,则输掉本rally;–发球方输则交换发球权;–发球方赢则得1分.•先得15分者赢1局.4壁球程序规格说明•球技水平:用球员作为发球方时的获胜概率来模拟.•程序规格说明输入:两个球员的水平,模拟比赛局数.输出:两球员各自的获胜局数及比例.5随机数•模拟的是不确定性事件:每回合输赢是随机的.–这类模拟也称为MonteCarlo算法•如何用确定性的计算机模拟非确定性?–用函数生成随机数(实际上是伪随机数).•从种子值开始,计算出一个“随机”数;•如果还需要,就用上一个随机数反馈给生成函数,生成下一个随机数.–Python库random提供了一些伪随机数生成函数:•randrange():生成指定范围内的一个整数•random():生成[0,1)间的一个浮点数Python随机函数6伪随机数-整数•每次调用randrange函数产生一个伪随机整数fromrandomimportrandrangerandrange(1,6)5randrange(1,6)3randrange(1,6)2randrange(1,6)5randrange(1,6)5randrange(1,6)5randrange(1,6)47伪随机数-浮点数fromrandomimportrandomrandom()0.79432800912898816random()0.00049858619405451776random()0.1341231400816878random()0.98724554535361653random()0.21429424175032197random()0.23903583712127141random()0.729183288434089198用random模拟输赢•设发球人获胜概率是prob•程序中显然需要这样的代码:if发球者胜了本回合:score=score+1–并且要使该条件为真的情况占prob•用random函数模拟:ifrandom()prob:score=score+1prob1–probprob109自顶向下设计•对复杂问题常采用自顶向下设计:–将对一般问题的解决方案用若干个较小问题来表达.–再对较小问题用同样的方法分解.–直至小问题很容易求解.–将所有小问题的解合并,就得到大问题的解.10顶层设计•基本算法:–介绍程序功能–取得输入:probA,probB,n–利用probA和probB模拟n局比赛–输出结果报告•基本程序defmain():printIntro()probA,probB,n=getInputs()winsA,winsB=simNGames(n,probA,probB)printSummary(winsA,winsB)11分离关注•SeparationofConcerns(SoC):将计算机程序分解成不同部分,各部分功能重叠越少越好.–一个关注是指程序中的一个兴趣点或焦点.•好处:–允许多人独立开发系统的不同部分–便于重用–确保系统可维护性–易于增加新功能–使系统易理解–......12结构图•模拟壁球问题的程序被分成了四个关注:–为每个关注定义了函数的接口(interface)或称特征(signature).•即函数名,参数,返回值的信息–高层设计时只须关心函数的接口,而非函数的实现.•用结构图(或称模块层次图)表示:13抽象•在设计的每一层,接口指明了需要下一层的哪些细节;其他可暂时忽略.•抽象:确定某事物的重要特性并忽略其他细节的过程.•抽象是基本的设计工具.•自顶向下设计的整个过程可视为发现有用的抽象的系统化方法.14第二层设计•两个简单函数defprintIntro():printThisprogramsimulatesagameofracquetballprint’betweentwoplayerscalledAandB.’printTheabilitiesofeachplayerisindicatedbyaprintprobability(anumberbetween0and1)thatprinttheplayerwinsthepointwhenserving.PlayerAprintalwayshasthefirstserve.“defgetInputs():#RETURNSthreesimulationparametersprobA,probBandna=input(Whatistheprob.playerAwinsaserve?)b=input(Whatistheprob.playerBwinsaserve?)n=input(Howmanygamestosimulate?)returna,b,n15第二层设计(续)•设计simNGames()winsA和winsB初始化为0循环n次模拟一局ifplayerA胜:winsA加1else:winsB加1defsimNGames(n,probA,probB):winsA=winsB=0foriinrange(n):scoreA,scoreB=simOneGame(probA,probB)ifscoreAscoreB:winsA=winsA+1else:winsB=winsB+1returnwinsA,winsB16第三层设计•simOneGame:整个模拟程序的关键.–是个不确定循环:不断进行回合较量,直至一局结束–需要两个累积器:记分–需要一个二值累积器:记录发球方得分初始化为0发球方置为A当本局未结束就循环:模拟一次发球修改比赛状态返回比分17第三层设计(续)•结束条件用函数gameOverdefsimOneGame(probA,probB):scoreA=0scoreB=0serving=AwhilenotgameOver(scoreA,scoreB):ifserving==A:ifrandom()probA:scoreA=scoreA+1else:serving=Belse:ifrandom()probB:scoreB=scoreB+1else:serving=A“returnscoreA,scoreBreturnscoreA,scoreB18第三层设计(续)•函数gameOverdefgameOver(a,b):#aandbrepresentscoresforaracquetballgame#RETURNStrueifthegameisover,falseotherwise.returna==15orb==15•函数printSummarydefprintSummary(winsA,winsB):#Printsasummaryofwinsforeachplayer.n=winsA+winsBprint\nGamessimulated:,nprintWinsforA:%d(%0.1f%%)%(winsA,float(winsA)/n*100)printWinsforB:%d(%0.1f%%)%(winsB,float(winsB)/n*100)•完整程序:rball.py–运行之,看看技术的小差距是否导致大胜负差?–试一试:修改成模拟多局制比赛.19设计过程小结•自顶向下,逐步求精–将算法表达为一系列较小问题–为每个小问题设计一个(函数)接口–用各小问题的接口细化算法–对各小问题重复此过程20自底向上实现•从结构图的底层开始实现,逐级向上.•每完成一个模块,进行单元测试.–这也是分离关注,使debug更容易21单元测试•我们从gameOverfunction开始•importrballrball.gameOver(0,0)Falserball.gameOver(5,10)Falserball.gameOver(15,3)Truerball.gameOver(3,15)True•我们测试gameOver的所有关键的反馈信息:–输入参数0,0时,游戏结束为False–输入参数5,10时,无人到15分,游戏结束为False–输入参数15,3或3,15时,任一人到15分,游戏结束为True22单元测试•我们看过gameOver的测试情况,我们可以返到simOneGame.simOneGame(.5,.5)(11,15)simOneGame(.5,.5)(13,15)simOneGame(.3,.3)(11,15)simOneGame(.3,.3)(15,4)simOneGame(.4,.9)(2,15)simOneGame(.4,.9)(1,15)simOneGame(.9,.4)(15,0)simOneGame(.9,.4)(15,0)simOneGame(.4,.6)(10,15)simOneGame(.4,.6)(9,15)23单元测试•当概率是相等时,分数相差不大•当概率相差较大,游戏溃败•以这种方式测试每个组件称之单元测试•独立测试每个函数使之更容易发现错误,会使测试整个程序进行的更顺畅24其他设计技术•原型技术(prototyping):从程序的一个简单版本开始,逐步增加功能,直至完全满足程序规格.–初始的简单版本称为原型(prototype).•原型技术导致螺旋式开发过程:原型的设计,实现,测试新功能的设计,实现,测试……•适合情况:对程序功能不熟悉,难以按自顶向下设计方法给出完整设计.25例:壁球模拟程序的原型•simOneGame()–固定水平五五开–固定比赛30个rallyfromrandomimportrandomdefsimOneGame():scoreA=0scoreB=0serving=Aforiinrange(30):ifserving==A:ifrandom().5:scoreA=scoreA+1else:serving=Belse:ifrandom().5:scoreB=scoreB+1else:serving=AprintscoreA,scoreBsimOneGame()000101…2728283838383838383939495926例:对原型的扩展•增加两个参数:选手的技术水平•改成完成一局比赛(一方先得15分)•完成多局比赛,统计各人获胜局数•增加交互式输入,格式化输出27设计的艺术•螺旋式开发与自顶向下设计是互补的方法.–如:原型可使用自顶向下设计•好的软件设计者会使用多种设计技术.•通过实践才能学会软件设计.•什么是最好的建议?•实践,实践,再实践!
本文标题:python课件Chapter09-ch
链接地址:https://www.777doc.com/doc-1916401 .html