用蒙特卡罗方法计算五人传球问题
2015-01-26 01:57
357 查看
蒙特卡罗方法百度解释http://baike.baidu.com/link?url=XwVnK6P_gip61_P9RzC9u6T4KQP5hmoZIvx57XBM66hPBONRRl3-yAwldGr3orFe
问题描述:
有A B C D E 五个人,围成一圈,开始球在A的手上,然后由A向与自己相邻的两边的某一人传球,然后要求计算球被传十次,最后又回到A手中的概率。
如上图所示,A只能把球传给B或者E,其几率是相同的。
对每个人来说把球传给左边或者右边的人的几率都是相同的,且为1/2;
这样我们便可以用这样的公式来计算出最后的结果:
分母是指每轮传球每个人都有两种传球可能性
分子中的2是指可以通过传球沿着一个顺序转两圈的方式,使球到达A的手中;
后面的组合公式是指每轮传十次球,必须做到五次是传给右边的人,五次传给左边的人,才能最终到达A的手中。这样做出来的结果是254/1024=0.248;
然后回到我们的重点上来,如何能够用蒙特卡罗方法解决这个题目。
首先要建立模型,即要模仿真人传球的过程。
每一次传球的时候都看做是随机的,那么让机器产生一个随机数,根据随机数的大小来分配球传递的方向,这样便可以解决随机性问题,
然后在充分多的数量之后便可以根据能够到达A的次数总和L除以总数N,求出概率。这里的N 取1000000次就可以,对计算机来说,1000000次也是很快就做完的。
具体实现代码如下:
通过代码实现,结果也约等于0.248,说明通过蒙特卡罗方法计算出来的数据为真。
在很多难以用简单公式计算的时候可以采用蒙特卡罗算法计算。
问题描述:
有A B C D E 五个人,围成一圈,开始球在A的手上,然后由A向与自己相邻的两边的某一人传球,然后要求计算球被传十次,最后又回到A手中的概率。
如上图所示,A只能把球传给B或者E,其几率是相同的。
对每个人来说把球传给左边或者右边的人的几率都是相同的,且为1/2;
这样我们便可以用这样的公式来计算出最后的结果:
分母是指每轮传球每个人都有两种传球可能性
分子中的2是指可以通过传球沿着一个顺序转两圈的方式,使球到达A的手中;
后面的组合公式是指每轮传十次球,必须做到五次是传给右边的人,五次传给左边的人,才能最终到达A的手中。这样做出来的结果是254/1024=0.248;
然后回到我们的重点上来,如何能够用蒙特卡罗方法解决这个题目。
首先要建立模型,即要模仿真人传球的过程。
每一次传球的时候都看做是随机的,那么让机器产生一个随机数,根据随机数的大小来分配球传递的方向,这样便可以解决随机性问题,
然后在充分多的数量之后便可以根据能够到达A的次数总和L除以总数N,求出概率。这里的N 取1000000次就可以,对计算机来说,1000000次也是很快就做完的。
具体实现代码如下:
#include<iostream> #include<cstring> #include<cstdlib> #include<ctime> //利用蒙特卡罗方法 //目的:计算 p=L/N; //L: 球回到A手中的次数 //N: 充分多的次数,这里取值1000000 // A-B-C-D-E-A,从A开始 using namespace std; int factory(); //每轮传十次球的模仿过程 int main() { srand(time(NULL));//用时间做种子 int count=0;//记录回到A的数量 for(int i=0;i<1000000;i++)//循环1000000次 { count+=factory(); } double rate=1.0*count/1000000.0; cout<<"rate= "<<rate<<endl; return 0; } int factory() { //建立五元数组,模仿五个人, //每次让球所在的位置为1,其余为零 int test[5]={1,0,0,0,0};//test[0]代表A int q=0; for(int i=0;i<10;i++) { q=rand()%10+1;//生成1-10的随机数 //q<=5 go left //q>5 go right for(int j=0;j<5;j++) { if(test[j]==1)//the ball current place { if(q<=5) { if(j==0)test[4]=1,test[0]=0; else test[j]=0,test[j-1]=1; } else { if(j==4)test[0]=1,test[4]=0; else test[j]=0,test[j+1]=1; } break; } } } if(test[0]==1)return 1;//最终回到A返回1 return 0; }
通过代码实现,结果也约等于0.248,说明通过蒙特卡罗方法计算出来的数据为真。
在很多难以用简单公式计算的时候可以采用蒙特卡罗算法计算。
相关文章推荐
- excel 复制公式计算结果问题的解决方法
- 计算统计-Chap6 推断统计的蒙特卡罗方法 (3)蒙特卡罗方法
- 概论-组合最优化问题、计算复杂性和启发式算法概念(现代优化计算方法)
- 递归的定义以及递归的示例(计算阶乘、计算斐波那契数、递归二分查找、回文串递归方法解决、汉诺塔问题、递归选择排序问题)
- C++回文数及素数问题计算方法
- 关于无线数据传输中产生的流量的一些计算方法以及问题!
- 一个风控计算负载过高到mysql主从拆分暴露的各种设计复杂性问题以及解决方法总结
- java 金额计算,商业计算 double不精确问题 BigDecimal,Double保留两位小数方法
- 用蒙特卡罗方法计算圆周率的近似值,java程序
- STM32F4学习笔记2——自建库函数整合FFT计算遇到的问题及解决方法
- 动态规划:0-1背包问题(使用迭代方法,避免重复计算)
- 合同计算问题的计算公式与计算方法
- 关于datepart计算weekday时多一天引起的问题及解决方法
- 问题:C#根据生日计算属相;结果:C#实现根据年份计算生肖属相的方法
- Openstack 问题总结之:计算节点上网络访问慢的解决方法
- 计算统计-Chap6 推断统计的蒙特卡罗方法 (1)引言
- 关于datepart计算weekday时多一天引起的问题及解决方法
- 队列应用银行排队问题模拟:计算客户的平均停留时间和等待时间以及每个客户的时间信息,两种方法实现
- 用蒙特卡罗方法计算区域面积以matlab实现
- 评分预测问题计算方法