栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

体育竞技分析

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

体育竞技分析


目录

一、自顶向下设计:

      1.顶层设计:

自项向下设计中最重要的是项层设计。以体育竞技分析为例,可以从问题的IPC  描述开始。大多数程序都可以将IPO描述直接用到程序结构设计中,体育竞技分析  从用户处得到模拟参数,最后输出结果。下面是一个基础设计的4个步骤。  

 步骤1:打印程序的介绍性信息。
步骤2:获得程序运行需要的参数,即probA、probB、ne
步骤3:利用球员A和B的能力值probA和probB,模拟n次比赛  步骤4:输出球员A和B获胜比赛的场次及概率。
这个基础设计从IPO描述获得,可以作为自顶向下设计的项层设计。
步骤1:输出一些介绍信息,针对提升用户体验十分有益。下面是这个步骤的Python  代码,顶层设计一般不写出具体代码,仅给出函数定义,其中,printIntro()函数打  印一些必要的说明。

 def main():
     printIntro()


步骤2:获得用户输入。通过函数将输入语句及输入格式等细节封装或隐藏,只需要假设程序如果调用了getInputs()函数即可获取变量probA、probB和n的值。这个函数必须为主程序返回这些值,截至第2步,全部代码如下,

def main():
    printIntro()
    probA, probB, n = getInputs()


步骤3:需要使用probA、probB模拟n场比赛。此时,可以采用步骤2的类似  方法,设计一个simNGames()函数来模拟n场比赛,并返回结果。按照体育竞技问  题的要求,该函数需要模拟比赛,并给出球员A和球员B赢得比赛的结果。截止步  骤3,程序的Python代码如下:

def main():
       printIntro()
       probA, probB, n = getInputs()
       winsA. winsB = simNGamesl(n, ProbA, probB)

步骤4:输出结果,设计思想类似,仍然只规划功能和函数,代码如下:

 

def main() ;
    PrintIntro()
    probA, probB, n = getInputs()
    winsA, winsB = simNGames (n,probA, probB)
    PrintSummary (winsA, winsB)

至此,体育竞技分析问题的程序框架已经清晰,但这仅是框架,main0)函 新没有做什么.原问题被划分为了4个独立的丽数: pintntro0、getlnputsO、simnNCG数和printSuummary)。. 这些的数的名称、输入参数和预期返回值都已经确定。这个分解过程十分有益,因为它让程序员在这步不必 关心具体细节而专心专虑程序个分构设计。

      2.第n层设计:

经过顶层设计,main()函数成为体育竞技分析的顶层结构,上述设计可以表示为下图,其中每层按照从左至右的顺序执行,每个函数用一个矩形表示,连接两个矩形的线表示上面函数对下面函数的调用关系。在信息流方面,箭头和注释表示输入和输出

 

 每层设计中,参数和返回值如何设计是重点,其他细节可以智时忽略。确定事件重要特征而忽略其他细节过程称为抽象。抽象是一种基本设计方法,自顶向下的设计过程可以看作是发现功能并抽象功能的过程。自顶向下设计的第二阶段是实现或进一步抽象第2层函数。
printlntro()函数应该输出一个程序介绍,这个功能的python代码如下,这个函数由Python基本表达式组合,增加或改变程序结构。

def printIntro():
    print("这个个程序模报两个选手A和B的莫中竞技比赛")
    print("程序运行行需要入和B的能力值的某种竞技比赛 (以0到1之间的小数表示) ")

getInputs()函数根据提示得到3个需要返回主程序的值,代码如下:

def getInputs():
    a = eval(input("请输入选手A的能力值(0-1):"))
    b = eval(input("请输入选手B的能力值(0-1):"))
    n = eval(input("模拟比赛的场次:"))
    return a, b, n

 simNGameson函数是整个程序的核心,其基本思路是模拟n场比赛,并跟踪记录每个球员赢得了多少比赛。模拟n场比赛”直观感受像个计数循环,而跟踪记录获胜场次更像计数过程。这是一个相当直观且租粒度的设计,类似顶层设计,其Python代码如下:
 

def simNGmes(n, probA, probB) :
    winsA, winsB= 0,0
    for i in range(n):
        scoreA,coreB = simoneGame (probA, probB)
        if scoreA > scoreB:
               winsA += 1
        else:
               winsB += 1
    return winsA, winsB

代码中设计了simneGame0函数,用于模拟场一场比赛, 这个函数需要知道每个球员的概率,返回两个球员的最终得分,下图8给出了这个设计对整体结构的更新。

 接下来需要实现simOneGame0函数。为了模拟一场比赛, 需要根据比赛规则来编写代码,两个球员A和B持续对攻直至比赛结束。可以采用无限循环结构直到比赛结束条件成立。同时,需要跟踪记录比赛得分,保留发球局标记, 总之, 尽可能详细地模拟比赛过程。在模拟比赛的循环中,需要考虑单一的发球权和比分问题,通过随机数和概率,可以确定发球方是否赢得了比分(randomO< prob)。如果球员A发球,那么需要使用A的概率,接着根据发球结果,更新是球员A得分还是将球权交给球员B。该函数的代码如下:

def simoneGame (probA ,probB):
    scoreA, scoreB = 0,0
    serving = "A"
    while not gameover(acoreA, scoreB) :
          if serving "A"
             if random() < probA:
                  scoreA += 1
             else:
                  serving= "B"
     else :
           if random () < probB :
              scoreB += 1
            else :
                  serving= "A"
     return scoreA, scoreB

这里进一步设计了gameOver()函数,用来表示一场比赛结束的条件, 对于不同体育比赛结束条件可能不同,封装该函数有助于简化根据不同规则修改函数的代价,提高代码可维护性。gameOver()函数跟踪分数变化并在比赛结束时返回True,未结束则返回False。然后继续循环的其余部分。下图是程序新的结构图。

 根据比赛规则,当任意一个球员分数达到15分时比赛结束。gameOver()函数实现代码如下:

def gameOver(a,b):
    return a==15 or b==15

 最后是printSummary()函数,其python代码如下:

def printSummary(winsA,winsB):
    n = winsA + winsB
    print("竞技分析开始,共模拟{}场比赛".format(n))
    print("选手A获胜{}场比赛,占比{:0.1%}".format(winsA,winsA/n))
    print("选手B获胜{}场比赛,占比{:0.1%}".format(winsB,winsB/n))

全部实现代码如下:

​
from random import random
def printIntro():
    print("这个个程序模报两个选手A和B的莫中竞技比赛")
    print("程序运行行需要入和B的能力值的某种竞技比赛 (以0到1之间的小数表示) ")
def getInputs():
    a = eval(input("请输入选手A的能力值(0-1):"))
    b = eval(input("请输入选手B的能力值(0-1):"))
    n = eval(input("模拟比赛的场次:"))
    return a, b, n
def simNGmes(n, probA, probB) :
    winsA, winsB= 0,0
    for i in range(n):
        scoreA,scoreB = simoneGame (probA, probB)
        if scoreA <= scoreB:
               winsB += 1
        else:
               winsA += 1
    return winsA, winsB
def gameOver(a,b):
    return a==15 or b==15
def simoneGame (probA ,probB):
    scoreA, scoreB = 0,0
    serving = "A"
    while not gameOver(scoreA, scoreB) :
          if serving == "A":
             if random() < probA:
                  scoreA += 1
             else:
                  serving= "B"
     else :
           if random () < probB :
              scoreB += 1
            else :
                  serving= "A"
    return scoreA, scoreB
def printSummary(winsA,winsB):
    n = winsA + winsB
    print("竞技分析开始,共模拟{}场比赛".format(n))
    print("选手A获胜{}场比赛,占比{:0.1%}".format(winsA,winsA/n))
    print("选手B获胜{}场比赛,占比{:0.1%}".format(winsB,winsB/n))
def main()
    PrintIntro()
    probA,probB,n=getInputs()
    winsA,winsB=simNGames(n, probA, probB)
    PrintSummary(winsA,winsB)
main()
​


​

最后再回到体育竞技分析问题,通过模拟方法分析球员之间能力的微小差异带来的比赛结果不同,是否会产生能力差别小却导致比赛结果一边倒的现象? 假设A在发球局赢得了45%比赛,而他的对手B发球局比他多赢了55%。结果显示,尽管能力上只有很小的差距(5%), 但是A大约需要经历3场比赛才能赢一场,他赢得一场3 局或5局的比赛机会十分渺茫。进一一步地,可以将这个程序扩展为羽毛球、乒乓球、网球等多种模式,可以找到体育竞技规律。当然,深入探讨竞技规律的前提是参赛选手水平差别不大,所发现的规律将有助于弥补短板,类似中国男足与巴西男足的竞技规律是没必要探讨的。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/339355.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号