夺冠概率

足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能。

    假设有甲、乙、丙、丁四个球队。根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表:

    甲  乙  丙  丁  

甲   -  0.1 0.3 0.5

乙 0.9  -   0.7 0.4

丙 0.7  0.3 -   0.2

丁 0.5  0.6 0.8 -

    数据含义:甲对乙的取胜概率为0.1,丙对乙的胜率为0.3,...

    现在要举行一次锦标赛。双方抽签,分两个组比,获胜的两个队再争夺冠军。(参见【1.jpg】)

请你进行10万次模拟,计算出甲队夺冠的概率。

p = 1 - 甲输的概率 
  
甲输的话,有两种情况: 
1:甲在第一轮中就输了 
2:甲在晋级后,决赛中输了 
  
假设 甲 先和 X 对决,则另两组是 Y 和 Z 对决 
其中 Y 和 Z 对决有两种情况发生:要么Y赢,要么Z赢 
所以综合上述讨论,可以算出甲输的概率是: 
  
P(X, 甲) + P(甲,X)*P(Y, Z)*P(Y, 甲) + P(甲,X)*P(Z, Y)*P(Z, 甲) 
  
即甲赢的概率是 1 减去上诉结果。 
10万数据模拟可以得到甲赢的概率大约0.076。 
验算:甲换成乙丙丁后分别算出四个数据,相加为1.0 
#include <cstdio> 
 #include <stdlib.h> 
 #include <time.h> 
 #define COUNT 100000 
  
 const int g = 0; 
  
 double P[4][4] = {{0, 0.1, 0.3, 0.5}, 
     {0.9, 0, 0.7, 0.4}, 
     {0.7, 0.3, 0, 0.2}, 
     {0.5, 0.6, 0.8, 0} 
 }; 
  
  
 int main() 
 { 
     srand((unsigned)time(NULL)); 
     double sum = 0.0; 
  
     for(int k = 1; k <= COUNT; k++) 
     { 
         int x = g, y = g, z = g; 
         while(x == g) x = rand() % 4; 
         //while(y==g || y==x) y=rand()%4;        //此处的生成y的方法和下面的方法有轻微差异 
         for(int ii = 0; ii < 4 && (ii == g || ii == x); )++ii; //约有0.001的浮动,推荐用下面这个方法 
         y = ii; 
         for(int i = 0; i < 4 && (i == g || i == x || i == y); )++i; 
         z = i; 
         double r = 1 - (P[x][g] + P[g][x] * (P[y][z] * P[y][g] + P[z][y] * P[z][g])); 
         sum += r; 
     } 
     printf("%lf\n", sum / COUNT); 
  
     return 0; 
 }
原文地址:https://www.cnblogs.com/hxsyl/p/3059908.html