计算球队在联赛中排名的概率

Calculate probability of a team ranking inside a league

这个项目的目标是计算每支球队进入前 6 名的概率(剩余的场景,即每支球队在剩余比赛中获胜或输掉但仍然进入前 6 名)所以我制作了一个 3D 列表以输入比赛历史(打过的比赛,我们知道结果)问题是我不知道如何计算球队排名的概率,因为它也取决于其他球队我想找到一个公式或代码来解决它

class Team:
    def __init__(self, name, pos):
       self.name = name
       self.pos = pos
       self.w = 0
       self.l = 0
       self.score = ""

    def upd_score(self, history):
        # check the rows
        for match in history[self.pos]:
            if match == ["w"]:
                self.w += 1
            elif match == ["l"]:
                self.l += 1
        # check the columns
        for match in history:
            if match[self.pos] == ["l"]:
                self.w += 1
            elif match[self.pos] == ["w"]:
                self.l += 1
        self.score = f"{self.w} - {self.l}"

    def get_score(self):
        print(f"the score is {self.score} ")

RGE = Team("RGE", 1)
VIT = Team("VIT", 2)
G2 = Team("G2", 3)
MSF = Team("MSF", 4)
AST = Team("AST", 5)
MAD = Team("MAD", 6)
FNC = Team("FNC", 7)
SK = Team("SK", 8)
XL = Team("XL", 9)
BDS = Team("BDS", 10)


MATCH_HISTORY = [
    [["X"], [RGE], [VIT], [G2], [MSF], [AST], [MAD], [FNC], [SK], [XL], [BDS]],
    [[RGE], ["X"], ["w"], ["w"], ["l"], [""], [""], [""], [""], [""], [""]],
    [[VIT], ["w"], ["X"], [""], [""], [""], [""], [""], [""], [""], [""]],
    [[G2], ["w"], [""], ["X"], [""], [""], [""], [""], [""], [""], [""]],
    [[MSF], ["w"], [""], [""], ["X"], [""], [""], [""], [""], [""], [""]],
    [[AST], ["l"], [""], [""], [""], ["X"], [""], [""], [""], [""], [""]],
    [[MAD], ["w"], [""], [""], [""], [""], ["X"], [""], [""], [""], [""]],
    [[FNC], ["l"], [""], [""], [""], [""], [""], ["X"], [""], [""], [""]],
    [[SK], ["w"], [""], [""], [""], [""], [""], [""], ["X"], [""], [""]],
    [[XL], ["w"], [""], [""], [""], [""], [""], [""], [""], ["X"], [""]],
    [[BDS], ["w"], [""], [""], [""], [""], [""], [""], [""], [""], ["X"]],
]

# SCORE UPDATING
RGE.upd_score(MATCH_HISTORY)
VIT.upd_score(MATCH_HISTORY)
G2.upd_score(MATCH_HISTORY)
MSF.upd_score(MATCH_HISTORY)
AST.upd_score(MATCH_HISTORY)
MAD.upd_score(MATCH_HISTORY)
FNC.upd_score(MATCH_HISTORY)
SK.upd_score(MATCH_HISTORY)
XL.upd_score(MATCH_HISTORY)
BDS.upd_score(MATCH_HISTORY)

计算分数:如果球队在胜利行中,我将输入“w”,如果球队在列中,我将在不能获胜的情况下输入“l”和“X”被填补(球队不能与自己比赛)

顺便说一句,我还是个初学者,所以如果有优化我的代码的方法,请告诉我,如果你有建议,最好解释一下,或者 link 给我一些可以帮助的东西

对于一个团队获胜的基本概率,您可以使用他们的胜利来弥补他们的总损失。 self.w / (self.w + self.l) 要计算团队排名的(同样是非常基本的)概率,只需计算出所有团队的概率并将它们从高到低排序即可。例如

# teams is an array containing instances of your teams
team_win_probs = []

for team in teams:
    team_win_probs.append((team.name, team.w / (team.w + team.l)))

team_win_probs.sort(key=lambda p: p[1], reverse=True) # the lambda gets the second elements of the tuple

在这里,我使用了一个元组来耦合球队名称和球队获胜概率,并在 list 的排序参数 key 中使用了一个 lambda 来从 tuple 并根据它排序。

希望对您有所帮助:)

我喜欢这个想法并且忍不住去做,所以这是代码

基本上它会遍历所有尚未完成的比赛存在的所有可能性,并计算前 N 名的每支球队的统计数据(您可以在代码中更改)

唯一的问题是可能性的数量是 2^undone_matches 并且它很快就变高了,所以你不能 运行 程序超过 15 个未完成的匹配...

另一种可能性是不是递归地而是用概率数学来做,但我太懒了 xD

PS: 现在程序不处理分数相等,取相同分数的第一队,如果你愿意,我让你处理:)

import copy

class Team:
    def __init__(self, name):
       self.name = name
       self.w = 0
       self.l = 0

    def init_scores(self, MH):
        for rowIndex in range(0, len(MH[0])):
            if MH[rowIndex][0] == self.name:
                index = rowIndex
        for columnIndex in range(0, len(MH[0])):
            result = MH[columnIndex][index]
            if result == "w":
                self.l += 1
            elif result == "l":
                self.w += 1
                
        for columnIndex in range(0, len(MH[0])):
            if MH[0][columnIndex] == self.name:
                index = columnIndex
        for rowIndex in range(0, len(MH[0])):
            result = MH[index][rowIndex]
            if result == "w":
                self.w += 1
            elif result == "l":
                self.l += 1
    
            
    def toString(self):
        r  = "| " + self.name.ljust(9) + "|\n"
        r += "|" + "----------" + "|\n"
        r += "| w: " + str(self.w).ljust(6) + "|\n"
        r += "| l: " + str(self.l).ljust(6) + "|\n"
        return r
    
    def getScore(self):
        return [self.name, self.w]
        
        
def createAllPossibilities(MH, topN, results):
    coo = emptyCellExist(MH)
    if coo[0] >= 0:
        cp1 = copy.deepcopy(MH)
        cp1[coo[0]][coo[1]] = "w"
        createAllPossibilities(cp1, topN, results)
        cp2 = copy.deepcopy(MH)
        cp2[coo[0]][coo[1]] = "l"
        createAllPossibilities(cp2, topN, results)
    else:
        Teams = []
        Teams.append(Team("RGE"))
        Teams.append(Team("VIT"))
        Teams.append(Team("G2"))
        Teams.append(Team("MSF"))
        Teams.append(Team("AST"))
        Teams.append(Team("MAD"))
        Teams.append(Team("FNC"))
        Teams.append(Team("SK"))
        Teams.append(Team("XL"))
        Teams.append(Team("BDS"))
        
        for t in Teams:
            t.init_scores(MH)
            
        scores = []
        for t in Teams:
            scores.append(t.getScore())
        
        for n in range(topN):
            best = 0
            index = -1
            for t in range(len(scores)):
                if best < scores[t][1]:
                    best = scores[t][1]
                    index = t
            scores[index][1] = 0
            #print(scores)
            results[index] += 1
            

def emptyCellExist(MH):
    for row in range(len(MH[0])):
        for cell in range(len(MH[0])):
            if MH[row][cell] == "":
                return [row, cell]
    return [-1, -1]



# current score
MATCH_HISTORY = [   ["X",   "RGE", "VIT", "G2", "MSF", "AST", "MAD", "FNC", "SK", "XL", "BDS"],
                    ["RGE", "X",   "w",   "w",  "l",   "l",   "w",   "l",   "l",  "w",  ""],
                    ["VIT", "w",   "X",   "l",  "w",   "l",   "w",   "l",   "w",  "w",  ""],
                    ["G2",  "w",   "l",   "X",  "w",   "w",   "l",   "l",   "w",  "w",  ""],
                    ["MSF", "w",   "l",   "v",  "X",   "w",   "w",   "l",   "w",  "w",  ""],
                    ["AST", "l",   "l",   "l",  "l",   "X",   "l",   "l",   "l",  "",  ""],
                    ["MAD", "w",   "l",   "v",  "w",   "l",   "X",   "l",   "l",  "",  ""],
                    ["FNC", "l",   "l",   "l",  "w",   "l",   "l",   "X",   "w",  "",  ""],
                    ["SK",  "w",   "l",   "w",  "l",   "w",   "w",   "l",   "X",  "",  ""],
                    ["XL",  "w",   "l",   "w",  "w",   "l",   "l",   "w",   "w",  "X",  ""],
                    ["BDS", "w",   "l",   "w",  "w",   "l",   "w",   "w",   "l",  "",  "X"]]

# top teams must be top X
topN = 6

# count the number of matches done and left to do
matchesDone = 0
matchesLeft = 0
for row in MATCH_HISTORY:
    for cell in row:
        if cell == "w" or cell == "l":
            matchesDone += 1
        elif cell == "":
            matchesLeft += 1
print("matches done : " + str(matchesDone))
print("matches left to do : " + str(matchesLeft))
print("that's " + str(pow(2, matchesLeft)) + " possibilities\n")

if matchesLeft > 20:
    print("that's way to much for me")
else:
    # if the number of matches left to do is low enought, then start calculating the probabilities
    results = [0 for a in range(len(MATCH_HISTORY[0]))]
    createAllPossibilities(MATCH_HISTORY, topN, results)
    
    print(MATCH_HISTORY[0][1:])
    for a in range(len(results)):
        results[a] /= (pow(2, matchesLeft)*topN)
        results[a] = int(results[a]*1000)/10
    print(results)
    

while 1:
    pass