求解四只鴨子在同一半圓池塘的概率,答案令人震驚!
之前老早就看過這個問題了。當時隨便解了解,感覺概率是1/2,然后就過去了。
正好互動媒體老師要可視化概率論問題,我就做了這個。
老規矩,先說一下思路
思路:暴力測試
先是隨機在圓內放四個點,然后判斷這四個點是否在同一半圓,如果是的話就記錄下來。如此循環。
然后最后的概率就是同一半圓的次數/測試總次數。
當然啦,這個答案肯定不是個精確值。但如果測試次數足夠大的話,答案就無限逼近正確答案。
隨機放點
這個模型最重要的部分就是隨機放點!。
網上看了幾種思路,都覺得不行。自己想了一個。
我覺得效果還行(非常完美)
大致思路是這樣的,先是隨機取點所在的弧度。這個毋庸置疑,非常隨機(0,2PI);
然后取點所在的半徑。大概想法就是微積分的方法。大概就是sqrt(點所在半徑的面積/總面積)*圓的半徑。
下面是代碼。比較簡單,就不說明了
//返回一個2維向量,x為點的弧度,y為點的半徑
function randomPointOfCircle(r)
{
theta=random(0,TWO_PI);
circleArea=PI*r*r;
pointArea=random(0,circleArea);
randomR=sqrt(pointArea/circleArea)*r;
circlePoint= createVector(theta, randomR);
return circlePoint;
}
判斷是否為同一半圓
這個就更簡單了。大概就是看他們弧度之間的弧度差。如果最大的弧度差<PI,就證明不在同一圓內
//pointList點的弧度的list
function pointsInHalfCircle(pointList,num)
{
pointList=sort(pointList,num);
maxTheta=TWO_PI-(pointList[num-1]-pointList[0]);//第一個和最后一個
for(let i=0;i<num-1;i++)
{
maxTheta=max(maxTheta,pointList[i+1]-pointList[i]);
}
console.log(maxTheta);
if(maxTheta<PI)
{
return false;
}
return true;
}
注意!因為圓的的弧度是(0,2PI)。如果按照順時針方向來算弧度差的話,那么最后一個和第一個之間的差,還要用2PI來減。
結果
我就測試了兩千多次,如果測試次數更多的話,可能結果還會變異變。
鼠標滾輪:改變測試頻率。
鼠標點擊:暫停
有人嗎,有人吱一聲。送代碼!