蒙特卡罗法求圆周率,哪位大侠能详细解释下。

花满留香 2011-05-02 09:29:21
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

bool toss()
{
double x=0.0,y=0.0;
double sign=((double)rand()/RAND_MAX);
double size=((double)rand()/RAND_MAX);
if(sign>0.5)
x=size;
else
x=-size;

sign=((double)rand()/RAND_MAX);
size=((double)rand()/RAND_MAX);
if(sign>0.5)
y=size;
else
y=-size;

double z=sqrt(x*x+y*y);

if(z>1)
return false;
else return ture;
}

double ratio(int num)
{
int i,sum=0;
srand((unsigned)time(0));
for(i=0;i<num;i++)
{
if(toss()==1)
sum++;
}

return (double)sum/(double)num;
}

double MonteCarloPi(int num)
{
return ratio(num)*4;
}

void main()
{
double pi=MonteCarloPi(10000);
printf("PI=%f\n",pi);
}

函数的嵌套调用,求高手解读。
...全文
929 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xhwubai 2012-10-28
  • 打赏
  • 举报
回复
请教下,圆的面积不是pi乘以半径的平方吗?圆的半径为1,那么圆的面积就是pi啊,怎么成了“2*PI*2”?

[Quote=引用 6 楼 的回复:]
原理是这样的:
假设有一个圆半径为1,直径为2,则面积为2*PI*2,可推出PI为圆面积的1/4,则以圆心为原点画个平面坐标,第一象限内圆的面积自然是1/4,第一象限内扇形的外切正方形的面积,边长为1,则面积为1,现在往这个正方形内射飞镖,则这些飞镖有些会落于四分之一圆内,假设共射飞镖n个,落入圆内的飞镖有c个,则依比例来算,
PI=4*c/n
这是用概率来求的,如果投的镖足够多,则结果会越……
[/Quote]
SuperFC 2011-05-02
  • 打赏
  • 举报
回复
AnYidan 2011-05-02
  • 打赏
  • 举报
回复
lz 要先明白“蒙特卡罗法求圆周率”的想法,之后再看程序
贪食蛇男 2011-05-02
  • 打赏
  • 举报
回复
画板真难使……
贪食蛇男 2011-05-02
  • 打赏
  • 举报
回复
原理是这样的:
假设有一个圆半径为1,直径为2,则面积为2*PI*2,可推出PI为圆面积的1/4,则以圆心为原点画个平面坐标,第一象限内圆的面积自然是1/4,第一象限内扇形的外切正方形的面积,边长为1,则面积为1,现在往这个正方形内射飞镖,则这些飞镖有些会落于四分之一圆内,假设共射飞镖n个,落入圆内的飞镖有c个,则依比例来算,
PI=4*c/n
这是用概率来求的,如果投的镖足够多,则结果会越接近真实的PI。
yuchangsheng 2011-05-02
  • 打赏
  • 举报
回复
蒙特卡罗算法的原理是:考虑一个正方形和它的内切圆,

在正方形内随机取一点,其落在圆内的概率应该是二者(圆和方)的面积比。

概率 = pai*r*r/2r*2r = pai/4
pai = 概率 * 4
qq120848369 2011-05-02
  • 打赏
  • 举报
回复
这叫随机算法.
花满留香 2011-05-02
  • 打赏
  • 举报
回复
RAND_MAX我也不知道是什么。。。
merlinfang 2011-05-02
  • 打赏
  • 举报
回复
刚又想起来了,*4是因为正方形的面积是4,所以圆的面积就是概率*4了。
merlinfang 2011-05-02
  • 打赏
  • 举报
回复
这个是基于概率的算法,这里的思想就是得到圆的面积,然后半径为1,圆的面积就是PI了。

toss表示随机一个点,如果在圆内,返回true,ratio就是在圆内的概率了。
RAND_MAX是什么?后面的*4难以解释了。
Philister 2011-05-02
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 macrojj 的回复:]

足够多的随机点才能确定。

如果我有10000个随机点在正方形里 那么随机点落在内切圆的概率是 圆/正方形 面积比。

该圆的面积是 r=0.5, r^2PI/1= 落在园内的点/ 所有点

PI 就出来了 4× 落在园内的点/ 所有点
[/Quote]
++
macrojj 2011-05-02
  • 打赏
  • 举报
回复
足够多的随机点才能确定。

如果我有10000个随机点在正方形里 那么随机点落在内切圆的概率是 圆/正方形 面积比。

该圆的面积是 r=0.5, r^2PI/1= 落在园内的点/ 所有点

PI 就出来了 4× 落在园内的点/ 所有点
昵称很不好取 2011-05-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 hiroyukki 的回复:]

画板真难使……

[/Quote]
yuchangsheng 2011-05-02
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

typedef enum {false, true} qboolean;
qboolean toss()
{
double x=0.0,y=0.0,z=0.0;
double sign=((double)rand()/RAND_MAX); // 根据sign的值确定x,y的正负
double size=((double)rand()/RAND_MAX);
if(sign>0.5)
x=size;
else
x=-size;

sign=((double)rand()/RAND_MAX);
size=((double)rand()/RAND_MAX);
if(sign>0.5)
y=size;
else
y=-size;

z=sqrt(x*x+y*y);

if(z>1) // 确定点是不是在内切圆内
return false;
else
return true;
}

double ratio(int num)
{
int i,sum=0;
srand((unsigned)time(0)); // 设置初始随机数

for(i=0;i<num;i++)
{
if(toss()==1)
sum++; // 在内切圆内的有多少个
}

return (double)sum /(double)num;
}

double MonteCarloPi(int num)
{
return ratio(num)*4;
}

void main()
{
double pi=MonteCarloPi(10000);
printf("PI=%f\n",pi);
system ("PAUSE");
}
我给关键的注释一下

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧