唐苦尽吧 关注:134贴子:21,054

【技术贴2】剑道期末淘汰赛模拟···

只看楼主收藏回复


吴老头镇楼···


IP属地:美国1楼2012-12-19 22:13回复
    就黄图哥那个破网速还跟我抢2L?!
    如果我抢赢了,请大家给我点掌声···
    老规矩,不准插楼···


    IP属地:美国2楼2012-12-19 22:14
    收起回复
      首先声明剑道淘汰赛规则:
      全班一共男生20名,分为两个半区,一个半区12人,另一个半区8人,每个半区决出一名选手进入最后的决赛,由于比标准的16人要多出了4人,所以编号为0-7号的选手非常不幸,如果要想进入决赛必须比赛4轮,而编号为8-19号的选手要想进入决赛只需比赛3轮:
      一共4个人进入最后的半决赛,分别对应涂鸦中的35号,32号,33号,34号,最后决出冠亚军各1名,季军2名···

      每两位选手之间进行比赛,先击中对方2剑的为胜者,进入下一轮。


      IP属地:美国3楼2012-12-19 22:26
      回复
        接下来看看如果我们要对整个比赛过程进行模拟需要哪些假设:
        1. 为了计算方便,假设每位选手在每场比赛发挥水平无明显差异,比如说类似有选手特别擅长打决赛因此在决赛中会超水平发挥的情况不予考虑,这样我们就可以简单的通过预测每一场比赛的胜负来递推整个淘汰赛的所有比赛。
        2. 每个选手有各自不同的战斗值(即后文的ability,简称abi),水平最高的选手战斗值设为100,水平第二高的选手为75,接下来两个并列65(因为季军有两位),剩下的16人战斗值服从从60到30的等差数列,公差为2。(为什么第一名比后面高那么多?因为那个棒子太NB了)
        3. 每个人在每场比赛中的每一剑都会有着随机的发挥,但是不会偏离原有战斗值太远,因此我们假设每个人每一剑的随机战斗值为【原有战斗值*(0.9-1.1)】,也就是说在某一剑中水平最高的选手可能发挥110的战斗值,也可能发挥90的战斗值,而最渣渣的选手可能发挥33的战斗值,也可能发挥27的战斗值。
        4. 接着我们假设每一剑的胜负与两人战斗值的差有关,于是我假设击中率:
        P1=战斗值之差/100+0.5,比如前两名选手交锋,第一名发挥了105的战斗值,第二名发挥了 80的战斗值,那么这一剑第一名击中第二名的概率为(105-80)/100+0.5=0.75,而第二名击中第一名的概率为0.25。如果是第一名与最后一名交锋,假设第一名发挥最差的90战斗值,最后名爆发发挥了33的战斗值,则第一名击中最后一名的概率为1.07>1,意思就是说“屌丝就别TM指望着逆袭了”
        5. 由第4步我们已经计算出了每一剑的击中概率,那么比赛一共需要击中对方两剑,假设每一剑之间是独立的,也就是说第一名可以在第一剑发挥95的战斗值而在第二剑发挥110的战斗值,这样我们就可以由第4步的每一剑的概率推出整场比赛获胜的概率。
        6. 已知每场比赛获胜的概率,接下来我们要做的就是随机把20名选手随机安排在20个不同的位置,然后按照前面步骤进行模拟,知道得出冠军就行了···


        IP属地:美国4楼2012-12-19 22:44
        收起回复
          假设完毕,接下来就是具体的模拟了:
          让我们一步步来,先对一场比赛进行模拟,这里我选择的是战斗值100的第一名和战斗值75的第二名的比赛:
          左边是代码,右边是结果显示(我一共模拟了3场比赛,都是第一名获胜):
          The 1 sword:代表这是这场比赛的第一剑
          A.sta表示第一名在这一剑中发挥的战斗值,B.sta表示第二名在这一剑中发挥的战斗值
          swordman1 get one sword表示根据前面计算的概率,随机模拟出这一剑是第一名得分了
          The winner is:swordman1表示整场比赛结束,第一名获得了胜利


          IP属地:美国5楼2012-12-19 22:49
          回复
            只从上面3场比赛中看不出什么概率来,于是我进行了50000次的模拟,计算A战胜B的概率:

            由左下角的代码可以看到,我是用战斗值为100的第一名和战斗值为60的第五名进行比赛,每次用50000场比赛来模拟,一共模拟5次,第一名获胜的概率分别为97.15%,97.17%,96.94%,
            97.19%.97.19%,
            接着我用不同的对手进行模拟,每次模拟都进行50000场比赛,一共模拟5次,把5次中的最高获胜率和最低获胜率填入下表:

            由对角线可以看出,能力值相同的人之间的比赛获胜率基本为50%,至少验证了没有在代码的模拟部分出现错误。
            第一名战胜第二名,第三名的概率分别为84.5%,94%左右,我觉得还是很符合实际的,因为棒子真的太NB了···
            第二名战胜第三名的概率为64.7%左右,以此类推,这个模拟结果还是可以接受的,与预期的现实的比赛胜率比较接近。因此我们不对前面模拟比赛胜负的方法和假设进行修改。


            IP属地:美国6楼2012-12-19 23:01
            回复
              OK,写到这里我们已经把对一场比赛的模拟写完了,接下来我们要做的就是用我们之前写的代码来模拟整个淘汰赛的过程:
              首先我们给所有选手命名(swordman1-20),并赋予战斗值(结果显示在右边)


              IP属地:美国7楼2012-12-19 23:03
              回复
                于是,我们已经把整场比赛模拟完了,但是还是说明不了什么问题,你看,第2号第一轮就被淘汰了···
                接着我们只需要小小得改一下代码,就可以看看究竟每位选手获得前几名的概率是多大了···

                我们对整个淘汰赛进行10000次模拟,分别统计每1位选手获得冠军,亚军,季军的次数,以及进入前4的总数(注意季军有两位哟,所以是前4)


                IP属地:美国10楼2012-12-19 23:17
                回复
                  最后得到结果如下,以第一号选手为例:
                  取得冠军8408次,亚军548次,季军402次,进入前四9358次,是不是很有趣呀···


                  IP属地:美国11楼2012-12-19 23:18
                  回复
                    整个模拟过程就这样结束了,我们成功的拿到了11L所示的一张表,把每一格里的个数除以
                    10000就可以得到一张概率表,也可以说是一张先验表,真正值得发挥的地方现在才开始:
                    比如我想计算,本屌丝在这次比赛中得了第二名,那么我其实真的是排名前四的概率是多少呢?很容易想到的就是贝叶斯公式:
                    假设没有比赛,排名任何位置的概率都是一样的,也就是说P(前4)=0.2 P(非前4)=0.8
                    而如果我是前4,得到第二名的概率是P(第2|前4)=(548+2198+1280+1267)/40000=0.1323
                    而如果我不是前4,得到第二名的概率是P(第2|非前4)=4707/160000=0.0294
                    那么根据贝叶斯公式,在这次比赛中我获得了第2名,那么我其实是前4名的概率是多少呢?
                    P(前4|第2)=(0.2*0.1323)/(0.2*0.1313+0.8*0.0294)=0.529
                    也就是说其实我还是有将近一半的概率是走狗屎运才得亚军的···
                    那么,亲爱的读者们,你们还能从这张先验概率表中得到一些什么有用的信息呢?
                    开动自己的脑筋哟···


                    IP属地:美国12楼2012-12-19 23:29
                    回复
                      最后我们再回过头来看看假设,哪些地方可以改进得更逼真,或者说更有趣呢?
                      1. 我们假设每一剑的发挥是在【战斗值*(0.9-1.1)】中平均分布的,而现实情况可能是
                      【战斗值+αN(0,1)】,在尾巴加一个正态分布噪音
                      2. 我们假设一场比赛中每一剑是独立的,但其实可能拿下第一剑的人会发挥更自如,因此在第二剑中战斗值进有加成。
                      3. 可能某些人会有些特殊技能,比如我们可以假设排名前4的选手都有0.2的概率在某一剑中无视对方战斗值而直接秒杀对手,有趣吧···
                      4. 我们还可以假设选手分为蛮力型,扮猪吃虎型(吴老头原话,一直没弄懂什么意思),计谋型,而各种类型之间会存在相克的关系,可以从战斗值的加成体现出来
                      5. ···
                      读者们,发挥你们的想象力吧!怎么才能让模拟更逼真,更好玩呢?


                      IP属地:美国13楼2012-12-19 23:42
                      收起回复
                        OK,写完了
                        @Love柳似伊 吧主你觉得怎么样,技术贴,申精···


                        IP属地:美国14楼2012-12-19 23:48
                        回复
                          补充一下,有些参数是由最后的输入决定的,
                          比如1号选手,2号选手,3&4号选手,5号选手的战斗值,以及5号选手之后等差数列的公差,和一共要比赛循环的次数···


                          IP属地:美国16楼2012-12-20 02:02
                          回复