布丰实验
法国数学家布丰(1707-1788)最早设计了投针试验。
这一方法的步骤是:
1) 取一张白纸,在上面画上许多条间距为a的平行线。
2) 取一根长度为l(l≤a) 的针,随机地向画有平行直线的纸上掷n次,观察针与直线相交的次数,记为m。
3)计算针与直线相交的概率.
18世纪,法国数学家布丰提出的“投针问题”,记载于布丰1777年出版的著作中:“在平面上画有一组间距为a的平行线,将一根长度为l(l≤a)的针任意掷在这个平面上,求此针与平行线中任一条相交的概率。”
布丰本人证明了,这个概率是:
(其中π为圆周率)!
布丰惊奇地发现:有利的扔出与不利的扔出两者次数的比,是一个包含π的表示式.如果针的长度等于a/2,那么扔出的概率为1/π.扔的次数越多,由此能求出越为精确的π的值。
认真学过概率论的都知道这个实验是有理论依据的,换句话说理论上它确实可以求出π的近似值,只要重复实验的次数足够多,误差就会足够小!
我相信如果用计算机大量重复模拟这次实验的话,一定会得到更好的结果.
首先有一个随机生成角度的代码.模拟这跟针每次落下后的与水平方向上的随机的夹角.
然后实现让这根针随机落在平面上.
用两随机点(A,B)确定这一跟针的位置.(随机点A负责确定针中心的位置),随机点B随机出现在以A为圆心的半径为L/4的园内.将两者确定的直线的斜率记录下来,利用公式画出该直线.
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <cmath>
#include <graphics.h>
#include<conio.h>
#include <windows.h>
#include <stdio.h>
int main()
{
initgraph(1000, 1000); //建立窗口
line(0, 0, 1000, 0); //划线
line(0, 200, 1000, 200); //划线
line(0, 400, 1000, 400); //划线
line(0, 600, 1000, 600); //划线
line(0, 800, 1000, 800); //划线
line(0, 1000, 1000, 1000); //划线
double l = 50;
srand(time(NULL)); //在计算机随机数列中找到一个与该时刻有关的点
double p = 1, c1 = 0, c2 = 0;
int count = 10000;
while (count--)
{
double x0, y0;
x0 = rand() % 1001;
y0 = rand() % 1001;
double x1, y1;
x1 = x0 + rand() % 101 - 50;
y1 = y0 + rand() % 101 - 50;
if ((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) > 2500)
continue;
double m = atan((y1 - y0) / (x1 - x0));
line(x0 - l * cos(m), y0 - l * sin(m), x0 + l * cos(m), y0 + l * sin(m));
c2++;
double b1 = y0 - l * sin(m), b2 = y0 + l * sin(m);
if (b1 < b2)
{
if (0 >= b1 && 0 <= b2)
++c1;
else if (200 >= b1 && 200 <= b2)
++c1;
else if (400 >= b1 && 400 <= b2)
++c1;
else if (600 >= b1 && 600 <= b2)
++c1;
else if (800 >= b1 && 800 <= b2)
++c1;
else if (1000 >= b1 && 1000 <= b2)
++c1;
}
else
{
if (0 >= b2 && 0 <= b1)
++c1;
else if (200 >= b2 && 200 <= b1)
++c1;
else if (400 >= b2 && 400 <= b1)
++c1;
else if (600 >= b2 && 600 <= b1)
++c1;
else if (800 >= b2 && 800 <= b1)
++c1;
else if (1000 >= b2 && 1000 <= b1)
++c1;
}
p = c2 / c1;
int P = p*100000;
char s[16] = {0};
_itoa_s(P,s,10);
size_t len = strlen(s) + 1;
size_t converted = 0;
wchar_t* WStr;
WStr = (wchar_t*)malloc(len * sizeof(wchar_t));
mbstowcs_s(&converted, WStr, len, s, _TRUNCATE);
clearrectangle(125, 180, 200, 200);
Sleep(1);
outtextxy(125, 180, WStr);
}
std::cout << p << std::endl
<< c1 << std::endl
<< c2 << std::endl;
return 0;
}`

仅精确到了小数点后一位...,考虑到C++的随机是伪随机,或许可以"体谅"一下.不过,个人觉得文章开头部分列出的科学家们的实验结果有待考察正确与否!