`

Ti5外卡赛模拟

 
阅读更多

         前天一时兴起, 想用计算机模拟Ti5外卡赛和正赛来看看最后的结果如何,这样就能完成小金本的预测~ 现在记录一下一些有趣的东西。

        外卡赛4只队伍CDEC, Vega, MVP 和 Archon, 问题的关键是如何模拟一场比赛的胜负。我最初的想法是查下有没有人研究过每支战队的MMR值与胜率之间的关系, 但是没有找到类似的结论。退而求其次, 我决定用MMR值作为一个基准,然后利用近3个月来战队之间相互战绩进行调整, 具体方案如下:

        http://www.joindota.com/en/edb/teams  这个使用points值作为战队排名的依据, 同时点开每支战队,可以查看近期的对战情况, 打开每场比赛还能看到双方交手胜负,比如Secret 的points 是34779, EG的points是33485, 那么Secret 对 EG的基础胜率就是 , EG对Secret的胜率则与之相反。 然后http://www.joindota.com/en/matches/162345-evil-geniuses-vs-team-secret 这里记录了双方相互战绩为Secret为70%胜率。 那么我们最终的胜率定为 winrate["Secret"]["EG"] = alpha * 实际胜率 + (1 - alpha) * 基础胜率

这里alpha由自己确定, 我设为0.65。 如果alpha> 0.5 则实际战绩比重更大, 反之基础胜率比重更大。

        当然我具体做的时候并不精确, 其一我没有找到一个网站能够提供给我战队之间近3个月的相互战绩。 在dotamax我能查到各个战队的比赛情况, 但是我只能手工统计,这样太麻烦, 我就采用了joindata里面现成的数据, 但不知道这些交手战绩是什么时候的~。 其二是有些队伍之间比赛次数很少, 相互战绩并不能具体体现双方实力,但我还是按同样的公式进行加权平均。

       对于外卡赛4只队伍,确实找不到相互战绩。。。所以直接使用points作为最终的胜率,当然这很不精确, 我就试试看有什么结果~4只战队的points如下:

       

points = {"CDEC"    : 31462,
          "Vega"    : 30157,
          "MVP"     : 29431,
          "Archon"  : 23050 }

 

赛制是这样的, CDEC和Vega一组, MVP和Archon一组。 两组胜者在进行一轮比赛,胜者是外卡赛第一。两组败者进行一轮比赛, 败者是外开赛第四, 然后剩下两只队再争夺2,3名,所有比赛均为BO3。 由于我要完成小金本的预测,所以我统计不同的排名次序,看看出现最多的情况是什么,但是结果很出乎我的意料.............我进行了100万次循环, 出现前三多的排名情况竟然是这样的:

       

 

         第一名竟然是points第三的MVP,并且出现较多的两种情况都是MVP居榜首, 我就瞬间凌乱了....正常来说最强的队出现第一的次数应该也是最多的吧,但是模拟的结果完全不是这样的。。。 一时想不通,我就把它放着了,直到今天我和室友说起这事的时候,他给了我一个很好的解释~

         首先我们看看具体模拟时候的胜率: 

         'MVP': {'MVP': -1, 'CDEC': 0.48332320627986797, 'Vega': 0.4939081694300866, 'Archon': 0.5607934300032392}
         这是MVP对战各只队伍的胜率,可以看到按照我们的假设,其实MVP, CDEC, Vega之间实力差距并不大。 那么在BO3中获胜的胜率又有多少呢?

        MVP vs CDEC :  0.483*0.483 + 0.483 * (1-0.483) *0.483 +  (1-0.483) * 0.483 * 0.483 = 0.475

        MVP vs Vega :  类似的0.491

        MVP  vs Archon:  0.591

        CDEC vs Vega : 0.516

        好,再次基础上考虑1000000次模拟,对于CDEC vs Vega的情况, CDEC 有 516000次进入决赛, Vega有484000次进入决赛。 而对于MVP vs Archon, MVP有591000次可能进入决赛。 这里我们发现MVP进入决赛的次数远远大于CDEC, Vega两队。 所以即使MVP在最后决胜的胜率偏低,有49.1% 和 47.5%,但是由于它进入决赛的次数比另外两队多,最终模拟出来的结果MVP得第一的次数就是最多的了...........很简单吧

        好的,总结一下:

        (1) 这里有违反直觉的地方存在, 胜率高的队伍在大量重复模拟的情况下得第一的次数竟然有可能比胜率偏低的队伍少, 原因是两只强队分入了死亡之组,而另一只稍弱的队伍稳稳地可以进入决赛, 在大量模拟的情况下,稍弱的队伍利用偏多的决赛次数弥补了胜率的不足。

        (2) 我想用大量模拟的结果完成小金本名次预测这个方案本身不对, 因为在单次比赛中,显然按各队胜率从高往低依次为前四的概率显然是最高的,但是在大量统计的情况下却不是这样的。。。建议预测的话就按照实力强弱来排即可,最多也就24种情况,大家分分工总会对的

        (3) 其实我也对正赛做了简单的模拟, 模拟次数是500万次, 想知道前六排名, 而出现最多的情况是这些:

      可以看到每种情况出现的次数是很少的。。总共好像有150多万种可能吧,所以从500w的量级来看这个数量也很少, 但是无一例外的是Secret都是第一。。。。当然这只是模拟的结果,实际情况千变万化~不过第一种情况有4只中国队前六也很不错啦, IG意外的比VG和EG还厉害。

      (4) 运气真的是实力的一部分,还要看临场发挥啊、适应情况,不过这些都很难说清,期望中国队能取得好成绩了!

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 24 03:49:03 2015

@author: Mihawk
"""

import random

points = {"CDEC"    : 31462,
          "Vega"    : 30157,
          "MVP"     : 29431,
          "Archon"  : 23050 }

name = points.keys()
winrate = {}

for i in name:
    winrate[i] = {}
    
for i in name:
    for j in name:
        if i != j:
            winrate[i][j] = points[i]*1.0 / (points[i] + points[j])
        else:
            winrate[i][j] = -1

def gamePlayWin(team1, team2):
    """ 三局两胜 """
    win = 0
    for i in range(3):
        if (random.random() < winrate[team1][team2]):
            win = win + 1
    if win >= 2:
        return True
    else:
        return False
    
def simulate():
    """ "CDEC" vs "Vega" """  
    if (gamePlayWin("CDEC", "Vega")):
        (A1Win, A1Lose)  = ("CDEC", "Vega")
    else:
        (A1Win, A1Lose)  = ("Vega", "CDEC")
    
    """ "MVP" vs "Archon" """
    if (gamePlayWin("MVP", "Archon")):
        (B1Win, B1Lose)  = ("MVP", "Archon")
    else:
        (B1Win, B1Lose)  = ("Archon", "MVP")
    
    """ 胜者组决赛 """
    if (gamePlayWin(A1Win, B1Win)):
        (A2Win, A2Lose)  = (A1Win, B1Win)
    else:
        (A2Win, A2Lose)  = (B1Win, A1Win)
    
    """ 败者组半决赛 """
    if (gamePlayWin(A1Lose, B1Lose)):
        (B2Win, B2Lose)  = (A1Lose, B1Lose)
    else:
        (B2Win, B2Lose)  = (B1Lose, A1Lose)
    
    """ 败者组决赛 """
    if (gamePlayWin(A2Lose, B2Win)):
        (B3Win, B3Lose)  = (A2Lose, B2Win)
    else:
        (B3Win, B3Lose)  = (B2Win, A2Lose)
     
    return "1    " + A2Win +"\n2    " + B3Win + "\n3    " + B3Lose + "\n4    " + B2Lose
    
    """
    # 最后排名 
    print("1    " + A2Win)
    print("2    " + B3Win)
    print("3    " + B3Lose)
    print("4    " + B2Lose)
    """
    
result = {}
for i in range(1000000):
    res = simulate()
    if (result.has_key(res)):
        result[res] = result[res] + 1
    else:
        result[res] = 1

final = sorted(result.items(), key = lambda d:d[1], reverse=True)
for i in range(5):
    print(final[i][0]),
    print(final[i][1])
        

          
          

 

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 24 04:43:37 2015

@author: Mihawk
"""

points = {"CDEC"    : 31462,
          "CG"      : 29834,
          "IG"      : 32528,
          "LGD"     : 33226,
          "Navi"    : 30746,
          "Fnatic"  : 28179,
          "C9"      : 32613,
          "Secret"  : 34789,
          "MVP.P"   : 29431,
          "Ehome"   : 30642,
          "EG"      : 33495,
          "Empire"  : 31768,
          "VG"      : 33111,
          "Newbee"  : 30526,
          "VP"      : 32187,
          "MVP.H"   : 30032}
          
name = points.keys()
winrate = {}
alpha = 0.65

for i in name:
    winrate[i] = {}
    
for i in name:
    for j in name:
        if i != j:
            winrate[i][j] = points[i]*1.0 / (points[i] + points[j])
        else:
            winrate[i][j] = -1

# 进行胜率调整
def interploate(team1, team2, actual):
    winrate[team1][team2] = alpha * actual + (1 - alpha) * winrate[team1][team2] 
    winrate[team2][team1] = alpha * (1 - actual) + (1 - alpha) * winrate[team2][team1]  

interploate("CDEC", "LGD", 0.29)
interploate("CDEC", "VG", 0.38)
interploate("CDEC", "IG", 0.44)
interploate("CDEC", "Secret", 0.2)
interploate("CDEC", "Ehome", 0.57)
interploate("IG", "LGD", 0.57)
interploate("IG", "Ehome", 0.71)
interploate("IG", "LGD", 0.57)
interploate("IG", "Secret", 0.0)
interploate("IG", "C9", 0.50)
interploate("IG", "EG", 0.75)
interploate("IG", "Fnatic", 0.8)
interploate("LGD", "Empire", 0.50)
interploate("LGD", "Navi", 0.44)
interploate("LGD", "Secret", 0.0)
interploate("Navi", "VP", 0.71)
interploate("Navi", "IG", 0.36)
interploate("Navi", "CDEC", 0.50)
interploate("Navi", "Secret", 0.0)
interploate("Fnatic", "Secret", 0.2)
interploate("Fnatic", "C9", 0.8)
interploate("Fnatic", "VG", 0.2)
interploate("Fnatic", "Secret", 0.2)
interploate("Fnatic", "VP", 0.5)
interploate("C9", "EG", 0.5)
interploate("C9", "VP", 0.7)
interploate("C9", "VG", 0.33)
interploate("C9", "Secret", 0.13)
interploate("C9", "Newbee", 0.17)
interploate("C9", "Ehome", 0.67)
interploate("C9", "Empire", 0.67)
interploate("Secret", "EG", 0.7)
interploate("Secret", "VP", 0.78)
interploate("Secret", "EG", 0.7)
interploate("Secret", "Empire", 1.0)
interploate("Secret", "Ehome", 1.0)
interploate("MVP.P", "MVP.H", 0.5)
interploate("MVP.P", "EG", 0.25)
interploate("Ehome", "Newbee", 0.6)
interploate("Ehome", "VG", 0.0)
interploate("Ehome", "Empire", 0.8)
interploate("Ehome", "LGD", 0.0)
interploate("EG", "VP", 0.62)
interploate("EG", "VG", 0.64)
interploate("Empire", "VP", 0.77)
interploate("Empire", "VG", 0.6)
interploate("Empire", "Newbee", 1.0)
interploate("VG", "VP", 0.2)
interploate("VG", "Newbee", 0.65)
interploate("VG", "LGD", 0.59)
interploate("Newbee", "IG", 0.41)
interploate("Newbee", "LGD", 0.70)
interploate("Newbee", "CDEC", 0.67)

groupA = ["CDEC", "CG", "IG", "LGD", "Navi", "Fnatic", "C9", "Secret"]
groupB = ["MVP.P", "Ehome", "EG", "Empire", "VG", "Newbee", "VP", "MVP.H"]
import random

def gamePlay(team1, team2):
    win1 = 0
    for i in range(2):
        if (random.random() < winrate[team1][team2]):
            win1 = win1 + 1
    if win1 == 0:
        return (0, 3)
    elif win1 == 1:
        return (1, 1)
    else:
        return (3, 0)

# 小组赛
def group(teamname):
    point = {}
    for team in teamname:
        point[team] = 0
    
    for team1 in teamname:
        for team2 in teamname:
            if team1 < team2:
                (point1, point2) = gamePlay(team1, team2)
                point[team1] = point[team1] + point1
                point[team2] = point[team2] + point2
    #print(sorted(point.items(), key = lambda d:d[1], reverse = True))
    res = sorted(point.items(), key = lambda d:d[1], reverse = True)
    UB = [res[i][0] for i in range(4)]
    LB = [res[i+4][0] for i in range(4)]    
    return (UB, LB)

def gamePlayWin(team1, team2):
    """ 三局两胜 """
    win = 0
    for i in range(3):
        if (random.random() < winrate[team1][team2]):
            win = win + 1
    if win >= 2:
        return True
    else:
        return False

def gamePlayWin5(team1, team2):
    """ BO5 """
    win = 0
    for i in range(5):
        if (random.random() < winrate[team1][team2]):
            win = win + 1
    if win >= 3:
        return True
    else:
        return False

def gamePlayWin1(team1, team2):
    """ BO1 """
    if (random.random() < winrate[team1][team2]):
        return True
    else:
        return False
    
def simulate():
    (A1UB, A1LB) = group(groupA)
    (B1UB, B1LB) = group(groupB)
    
    round11 = [A1UB[0], B1UB[1], B1UB[0], A1UB[1]]
    round12 = [0, 0, 0, 0]
    
    if winrate[A1UB[0]][B1UB[2]] > winrate[A1UB[0]][B1UB[3]]:
        round12[0] = B1UB[2]
        round12[3] = B1UB[3]
    else:
        round12[0] = B1UB[3]
        round12[3] = B1UB[2]
    
    if winrate[B1UB[0]][A1UB[2]] > winrate[B1UB[0]][A1UB[3]]:
        round12[2] = A1UB[2]
        round12[1] = A1UB[3]
    else:
        round12[2] = A1UB[3]
        round12[1] = A1UB[2]
    
    A1Win = [i for i in range(4)]
    A1Lose = [i for i in range(4)]
    A2Win = [i for i in range(2)]
    A2Lose = [i for i in range(2)]
    
    """ 胜者组 """
    for i in range(4):
        if gamePlayWin(round11[i], round12[i]):
            (A1Win[i], A1Lose[i]) = (round11[i], round12[i])
        else:
            (A1Win[i], A1Lose[i]) = (round12[i], round11[i])
    
    for i in range(2):
        if gamePlayWin(A1Win[2*i], A1Win[2*i+1]):
            (A2Win[i], A2Lose[i]) = (A1Win[2*i], A1Win[2*i+1])
        else:
            (A2Win[i], A2Lose[i]) = (A1Win[2*i+1], A1Win[2*i])
    
    if gamePlayWin(A2Win[0], A2Win[1]):
        (A3Win, A3Lose) = (A2Win[0], A2Win[1])
    else:
        (A3Win, A3Lose) = (A2Win[1], A2Win[0])
    
    
    """ 败者组 """
    round21 = [A1LB[0], B1LB[1], B1LB[0], A1LB[1]]
    round22 = [0, 0, 0, 0]
    
    if winrate[A1LB[0]][B1LB[2]] > winrate[A1LB[0]][B1LB[3]]:
        round22[0] = B1LB[2]
        round22[3] = B1LB[3]
    else:
        round22[0] = B1LB[3]
        round22[3] = B1LB[2]
    
    if winrate[B1LB[0]][A1LB[2]] > winrate[B1LB[0]][A1LB[3]]:
        round22[2] = A1LB[2]
        round22[1] = A1LB[3]
    else:
        round22[2] = A1LB[3]
        round22[1] = A1LB[2]
    
    B1Win = [i for i in range(4)]
    B2Win = [i for i in range(4)]
    B3Win = [i for i in range(2)]
    B4Win = [i for i in range(2)]
    B4Lose = [i for i in range(2)]
    
    for i in range(4):
        if gamePlayWin1(round21[i], round22[i]):
            B1Win[i] = round21[i]
        else:
            B1Win[i] = round22[i]
    
    for i in range(4):
        if gamePlayWin(A1Lose[i], B1Win[i]):
            B2Win[i] = A1Lose[i]
        else:
            B2Win[i] = B1Win[i]
    
    for i in range(2):
        if gamePlayWin(B2Win[2*i], B2Win[2*i+1]):
            B3Win[i] = B2Win[2*i]
        else:
            B3Win[i] = B2Win[2*i+1]
    
    for i in range(2):
        if gamePlayWin(B3Win[i], A2Lose[1-i]):
            (B4Win[i], B4Lose[i]) = (B3Win[i], A2Lose[1-i]);
        else:
            (B4Win[i], B4Lose[i]) = (A2Lose[1-i], B3Win[i])
    
    if gamePlayWin(B4Win[0], B4Win[1]):
        (B5Win, B5Lose) = (B4Win[0], B4Win[1])
    else:
        (B5Win, B5Lose) = (B4Win[1], B4Win[0])
    
    
    if gamePlayWin(B5Win, A3Lose):
        (B6Win, B6Lose) = (B5Win, A3Lose)
    else:
        (B6Win, B6Lose) = (A3Lose, B5Win)
        
    if gamePlayWin5(B6Win, A3Win):
        (B7Win, B7Lose) = (B6Win, A3Win)
    else:
        (B7Win, B7Lose) = (A3Win, B6Win)
    
    res = "1    "+B7Win+"\n2    "+B7Lose+"\n3   "+B6Lose
    res = res + "\n4    "+B5Lose+"\n5   "+B4Lose[0]+"\n6    "+B4Lose[1]
    return res

iterations = 5000000
result = {}
for i in range(iterations):
    print(i)
    res = simulate()
    if (result.has_key(res)):
        result[res] = result[res] + 1
    else:
        result[res] = 1

writelog = open("D:\\log.txt", "wb")

final = sorted(result.items(), key = lambda d:d[1], reverse=True)

for i in range(10):
    writelog.write(final[i][0])
    writelog.write("\n"+str(final[i][1]) + "\n")
    writelog.write("########################################\n")
writelog.close()

 
 

  • 大小: 799 Bytes
  • 大小: 2.3 KB
  • 大小: 3.9 KB
分享到:
评论
1 楼 xuyi1994 2015-07-28  
大神请收下我的膝盖  

相关推荐

    Dota2TI5互动指南UI界面(重生前版本)

    包括2015 Dota2 TI5互动指南上线UI界面( 重生前版本),本人刀粉一枚,特来报到!

    1678845411906ti5.zip

    很抱歉,根据您提供的信息,"1678845411906ti5.zip" 是一个压缩文件的名称,而描述部分同样仅是文件名的重复,并没有提供任何具体的内容或上下文。标签为空,也无法提供额外的信息。压缩包子文件的文件名称列表只给...

    Ti5BASIC.h

    Ti5BASIC.h

    基于C++核心的ti5arm竞技游戏设计源码学习项目

    本项目是一个基于C++核心的ti5arm竞技游戏设计源码学习项目,共包含466个文件,涉及多种编程语言。主要文件类型包括126个make文件、119个cmake文件、35个Python脚本、29个内部文件以及少量其他类型文件,如stamp、...

    电子政务-可低温烧结微波介电陶瓷LiBa3-xSrxSb3Ti5O21及其制备方法.zip

    例如,"可低温烧结微波介电陶瓷LiBa3-xSrxSb3Ti5O21及其制备方法"是电子政务资料中涉及到的一个关键知识点,它深入到电子设备和通信技术的基础材料研究。 微波介电陶瓷是电子政务领域中不可或缺的一部分,尤其在...

    微尺度Zr52.5Cu17.9Ni14.6Al10Ti5非晶合金弯曲断裂性能的研究

    微尺度Zr52.5Cu17.9Ni14.6Al10Ti5非晶合金弯曲断裂性能的研究,王晓磊,江峰,本文采用原位悬臂梁弯曲试验研究了微尺度Zr52.5Cu17.9Ni14.6Al10Ti5(Vit105)非晶合金试样的弯曲断裂行为。采用聚焦离子束加工技术制备...

    纳米晶Li4 Ti5O12薄膜射频磁控溅射合成与表征 (2014年)

    采用射频磁控溅射并结合超高真空热处理工艺在不锈钢基底上制备出了纳米晶Li4 Ti5O12薄膜.利用X射线衍射(XRD)、场发射扫描电子显微镜(FESEM)考察退火温度对薄膜结构、形貌的影响.并通过恒流充放电技术初步考察薄膜...

    Higgsed 5d T N理论的拓扑顶点

    我们使用拓扑顶点分析了希格斯分支中5d T N理论的分区函数的计算。 该理论是通过(p,q)5谱网实现的,其双重描述可以通过在某些局部非扭转式Calabi-Yau三倍谱上的M理论压缩来给出。 我们明确显示了如何将拓扑顶点...

    Ba3Ti5Nb6-xTaxO28陶瓷的结构与介电性能 (2009年)

    采用传统的固相合成法制备Ba3Ti5Nb6-xTaxO28(0≤x≤0.67)微波介质陶瓷,研究了Ta对Ba3TiNb6O28陶瓷结构与微波介电性能的影响。随Ta含量的增加,Ba3Ti5Nb6-xTaO28陶瓷先为Ba3 Ti5Nb6O28单相;当x增大到0.5时,则...

    ti5x_android:适用于Android的TI-58CTI-59计算器模拟器

    在标签中提到的"emulator",指的是这个应用是一个模拟器,它可以模拟真实硬件的行为,使得Android设备能够运行原本专为TI-58C和TI-59设计的软件。"calculator"标签明确了这是关于计算器的应用,而"android-...

    The New Binary Antimonide Ti5Sb8

    The New Binary Antimonide Ti5Sb8 Synthesis and Crystal Structure of the Novel Layered Manganese Oxides Ca2MnGaO5�δ and Sr2MnGaO5�δ A. M. Abakumova, M. G. Rozovaa, A. M. Alekseevaa, M. V. ...

    新型二元锑化物 Ti5Sb8

    The New Binary Antimonide Ti5Sb8 Synthesis and Crystal Structure of the Novel Layered Manganese Oxides Ca2MnGaO5�δ and Sr2MnGaO5�δ A. M. Abakumova, M. G. Rozovaa, A. M. Alekseevaa, M. V. ...

    电子束表面合金化制备Ti5Si3/TiAl复相合金改性层 (2004年)

    ### 电子束表面合金化制备Ti5Si3/TiAl复相合金改性层 #### 一、研究背景与目的 随着航空航天等高科技领域的发展,对于轻质高强度材料的需求日益增加。TiAl合金因其优异的性能(如低密度、高比强度、良好的高温力学...

    Ni1.5Ti5Nb014光催化剂的结构特征及性质 (2009年)

    由高温固相法制备K3TisNb014,并通过离子交换获得Ni1.5Ti5Nb014采用XRD,UV-vis-DRS,SEM等技术对所制备样品进行表征通过红外光谱技术考察样品对甲烷气中甲硫醇的吸附性能与光催化氧化性能结果表明,Ni2+交换K+后,钦妮酸...

    表面粗糙度对Zr52.5Cu17.9Ni14.6Al10Ti5 块体非晶合金塑性的影响 (2012年)

    将Zr52.5Cu17.9Ni14.6Al10Ti5 (Vit105)块体非晶合金棒用水砂纸和抛光膏打磨到不同粗糙度,研究表面粗糙度对试样压缩变形行为的影响。结果表明,随着试样表面粗糙度的降低,屈服强度并没有明显变化,但压缩塑性从2.3%...

    轧制对Zr50Cu18Ni17Al10Ti5块体非晶合金热稳定性和硬度的影响 (2013年)

    采用差热扫描量热仪和维氏显微硬度计研究了塑性变形对Zr50Cu18ni17Al10Ti5块体非晶舍金热稳定性和硬度的影响。结果表明,随着变形量的增加,玻璃化转变温度(Tg)呈现明显的下降趋势;而晶化开始温度(Tx),晶化峰值...

Global site tag (gtag.js) - Google Analytics