题目描述:
足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能。
假设有甲、乙、丙、丁四个球队。根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表:
甲 乙 丙 丁
甲 - 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万次模拟,计算出甲队夺冠的概率。
题目分析:
这个题目是通过多次试验的结果出现的频率,来模拟事件发生的概率;
比赛的分组一共有3种情况:
1. 甲乙一组,丙丁一组
2. 甲丙一组,乙丁一组
3. 甲丁一组,乙丙一组
其中,每一种情况,甲都可能获胜,也就有相应的获胜概率;
理想状态下,这三种情况,发生的概率是一样的也就是1/3;
我们可以由此得到一个理想状态下的甲获胜的概率,
我们将概率表定义为一个4×4的数组,则:
p1 = 1.0/3 * a[0][1] *(a[2][3] * a[0][2] + a[3][2] * a[0][3]);
p2 = 1.0/3 * a[0][2]*(a[1][3] * a[0][1] + a[3][1] * a[0][3]);
p3 = 1.0/3 * a[0][3]*(a[1][2] * a[0][1] + a[2][1] * a[0][2]);
p = p1+p2+p3 = 0.076
所以我们通过10万次模拟的结果应该在0.076附近
程序代码:
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
double a[4][4]={{1,0.1,0.3,0.5},{0.9,1,0.7,0.4},
{0.7,0.3,1,0.2},{0.5,0.6,0.8,1}};
double fun2(double p1,int m,int n)//另一组比赛和第二轮比赛结果
{
double p2 = a[m][n];
double p3 = a[0][m];
double t2 = a[n][m];
double t3 = a[0][n];
double p = p1*(p2*p3+t2*t3);
return p;
}
double fun1(int n)
{
double p1 = a[0][n];//第一次比赛,甲获胜的概率
switch(n)
{
case 1:
return fun2(p1,2,3);break;
case 2:
return fun2(p1,1,3);break;
case 3:
return fun2(p1,1,2);break;
}
}
int main()
{
srand(time(0));//改变程序运行时随机数的值
int num = 100000;
double sum =0;
for(int i=0;i<num;i++)
{
sum += fun1(rand()%3+1);
}
cout<<sum/num<<endl;
}
因为是概率事件,程序每次输出的结果都不一样,但都在0.076左右
第二遍做的时候,做了一些简化:
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int main()
{
float a[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};
float p[3];
//甲乙——丙丁
p[0]=a[0][1]*(a[2][3]*a[0][2]+a[3][2]*a[0][3]);
//甲丙——乙丁
p[1]=a[0][2]*(a[1][3]*a[0][1]+a[3][1]*a[0][3]);
//甲丁——乙丙
p[2]=a[0][3]*(a[1][2]*a[0][1]+a[2][1]*a[0][2]);
srand(time(0));
float sum=0;
for(int i=0;i<10000;i++)
{
int r = rand()%3;
sum += p[r];
}
float pi = sum/10000;
cout<<pi<<endl;
}