布豐用投針實驗估計了 π 值,那麼用什麼簡單方法可以估計自然對數的底數 e 的值?
今天不是七夕嘛...那我就設計個有關情侶的實驗好了...
===================================================
大街上去邀請n對情侶,也就是2n個人
這個實驗是指數收斂的,n不需要太大,算下來差不多大於5就行...
然後準備2n張座椅編上號,讓他們玩搶座位遊戲,規定男女座位號之和越低得分越高...
重複實驗多輪,然後頒獎...(估摸著至少30,你可以分多次頒獎)
===================================================
說了這麼多...那麼和 到底有啥關係呢?
記錄每次是否所有的情侶座位都沒有相鄰.
這件事情發生的概率趨近於 !
PS:不要糾結倒數...布豐投針不也是 嘛...畢竟這倆常數都大於1啊...
-----------------------------------------------------------------------------------------
比如我們有四隊情侶,設 表示第 對情侶相鄰的概率.
那麼可以算得:
-----------------------------------------------------------------------------------------
一般的,根據容斥原理:
Mathematica說這個化簡是 ...於是顯然極限為1/e...我不認識這種軟體.......
Forget it...我們用夾逼法來證明一下..
設:
我們知道:
同樣的:
綜上所述,根據夾逼準則,
=========================================================
祝看到答案的情侶們七夕快樂!!
今天不是七夕嘛...那我就設計個有關燒情侶的實驗好了...
===================================================
大街上去邀請n對情侶,隨便幾個排成一排
這個實驗今天應該人手是夠的,你看街邊那些排隊吃飯的,當然n越大越好啦...
然後排隊隨機報數,要求0~1之間。
之後依次相加,每次和超過一,打開爐門,燒了,記錄燒了幾人,計數器清零。
再從零開始加,又超過1了,打開爐門,燒了,記錄燒了幾人,計數器清零。
。。。
。。。
直到結束,統計平均每次燒幾人,就好了。
===================================================
說了這麼多...那麼和 到底有啥關係呢?
平均每次燒人e個。。。
-----------------------------------------------------------------------------------------
至於為什麼,FFF團的自己算吧...
看
Approximating the number $e$ through computer simulation - mathematical background
Approximate $e$ using Monte Carlo Simulation
-----------------------------------------------------------------------------------------
有情人不難,做有情人不易,祝好!
一副牌有52張,按順序標上 號,然後洗牌
如果不存在正整數 使得從上面數第 張牌剛好是第 號,那麼稱這副牌被「完全洗亂」
多次洗牌,統計有多少次是「完全洗亂」
記總共有 次洗牌,其中有 次被「完全洗亂」,那麼就有
牌的張數越多, 的期望越接近 ,洗的次數越多, 越接近自己的期望
用蒙特卡洛方法模擬一下洗10000次牌得到的結果,估得
import random
l = range(52)
p = q = i = 0
while i &< 10000: random.shuffle(l) for index, c in enumerate(l): if index + 1 == c: p += 1 break else: p += 1 q += 1 i += 1 print float(p)/float(q) # 2.70124257158
其原理是因為 ( 的泰勒展開取 )
我們用 表示這副牌總牌數,讓 表示所有從上數第 張剛好是 號的 幅牌的集合,讓 代表「這副牌是 的子集」這個事件。
那麼至少有一張牌在自己的位置上的排列數是 種
因為 ,我們得到
由容斥原理,我們得到
所以這副牌被「完全洗亂」的概率
顯然 越大,這個概率越接近
PS:
上面有人提到了利用泊松分布,我覺得也是一個可行的方案。
可以蹲在車站記錄每10分鐘來了多少次車,來車的數量
Recall一下泊松分布的公式
在車站蹲 個10分鐘,記 為「總共來了 次車的10分鐘」的數量
讓 ,
任何一個 都是對 的估計,
然後可以把 求個平均,得到 的估計
Update:
剛想到了另外一種方法,設
因為 ,我們可以用Monte Carlo演算法估算這個積分。
隨機變數 和 落在 曲線下方的概率
如果生成 組 ,其中 組滿足 ,
那麼因為 ,就有
一群人每人寫一張卡片,卡片上是自己的名字。把卡片收上去,打亂次序,再隨機地發給每一個人。每個人拿到的都不是自己卡片的概率趨近於 . 多做幾次這個實驗,用頻率代替概率,求倒數,就可以了。跟布豐投針實驗估算 挺像的。放上推導過程。
設有 個人,每人拿到的都不是自己卡片的情況總共有 種可能性, 滿足這樣的遞推公式,
.
於是每個人拿到的都不是自己的卡片的概率是 , 滿足這樣的遞推公式,
很容易得到
.
可以把 重新寫成
於是就有
取極限,得到
.
證明完畢。
可以寫個程序用蒙特卡洛模擬一下。C++ 代碼如下。
#include &
#include &
#include &
#include &
#include &
using namespace std;
struct Map 測試結果: 用了300個樣本,充分打亂卡片次序,重複試驗100次,得到的結果是 ,大約可以精確到小數點後3位。 —————————————————————————————————— 更新: 最近在學習Scala, 再放一個Scala版本的程序。我很意外地發現,對這個程序而言,Scala並不比C++慢. class MonteCarlo def this(sampleNumber: Int) = 用程序中的參數,得到的結果是 e = 2.7......... 2.7以後的數字依賴於所使用的隨機數的seed. Monte Carlo演算法很難把 算到很高的精度,這跟使用的程序語言無關。
{
vector&
vector&
Map(){}
Map(int n)
{
assert(n &> 0);
for (int i = 0; i &< n; ++i)
{
key.push_back(i);
value.push_back(i);
}
}
void setN(int n)
{
key.clear();
value.clear();
for (int i = 0; i &< n; ++i)
{
key.push_back(i);
value.push_back(i);
}
}
};
class E
{
private:
Map map;
int n;
public:
E(){}
explicit E(int n)
{
map.setN(n);
this-&>n = n;
}
static int random(int n)
{
assert(n &> 0);
return rand()%n;
}
void shuffle()
{
for (int i = 0; i &< n; ++i)
{
int index = random(n);
int temp = map.value[i];
map.value[i] = map.value[index];
map.value[index] = temp;
}
}
void shuffle(int shuffleTimes)
{
for (int i = 0; i &< shuffleTimes; ++i)
{
shuffle();
}
}
bool noneMatched() const
{
for (int i = 0; i &< n; ++i)
{
if (map.key[i] == map.value[i]) return false;
}
return true;
}
double sweep()
{
int N = 1000;
int count = 0;
int shuffleTimes = 40;
for (int i = 0; i &< N; ++i)
{
shuffle(shuffleTimes);
if (noneMatched()) count++;
}
return float(count)/float(N);
}
static double mean(const vector&
{
assert(myVector.size() &> 0);
double s = 0.0;
for (int i = 0; i &< myVector.size(); ++i)
{
s = s + myVector[i];
}
return s/float(myVector.size());
}
static double sigma(const vector&
{
assert(myVector.size() &> 1);
double mu = mean(myVector);
double s = 0.0;
for (int i = 0; i &< myVector.size(); ++i)
{
s = s + (myVector[i] - mu)*(myVector[i] - mu);
}
return sqrt(s/float(myVector.size()-1));
}
double getFrequency()
{
vector&
int sweepTimes = 100;
for (int i = 0; i &< sweepTimes; ++i)
{
double f = sweep();
cout &<&< i &<&< " " &<&< sweepTimes &<&< " " &<&< f &<&< endl;
frequencies.push_back(f);
}
return mean(frequencies);
}
double getEulerConstant()
{
return 1.0/getFrequency();
}
};
int main(int argc, char **argv)
{
int sampleNumber = 300;
E machine(sampleNumber);
cout &<&< machine.getEulerConstant() &<&< endl;
return 0;
}
import scala.collection.mutable.ArrayBuffer
import scala.util.Random
{
private var key: ArrayBuffer[Int] = new ArrayBuffer[Int]()
private var value: ArrayBuffer[Int] = new ArrayBuffer[Int]()
private var sampleNumber: Int = 0
private var frequency: ArrayBuffer[Double] = new ArrayBuffer[Double]()
private var sweepTimes: Int = 0
private var shuffleTimes:Int = 0
private var binNumber = 0
{
this()
this.sampleNumber = sampleNumber
for (i &<- 0 until sampleNumber)
{
this.key.append(i)
this.value.append(i)
}
this.sweepTimes = 1000
this.shuffleTimes = 40
this.binNumber = 100
}
def setSweepTimes(sweepTimes: Int): Unit = {
this.sweepTimes = sweepTimes
}
def setShuffleTimes(shuffleTimes: Int): Unit = {
this.shuffleTimes = shuffleTimes
}
def setBinNumber(binNumber: Int): Unit =
{
this.binNumber = binNumber
}
def shuffle(): Unit = {
val random = new Random()
for (i &<- 0 until sampleNumber)
{
val index: Int = random.nextInt(sampleNumber)
var temp: Int = value(i)
value(i) = value(index)
value(index) = temp
}
}
def shuffle(shuffleTimes: Int): Unit =
{
for (i &<- 0 to shuffleTimes-1)
{
this.shuffle()
}
}
def noneMatched():Boolean = {
for (i &<- 0 to sampleNumber - 1)
{
if (value(i) == key(i)) return false
}
return true
}
def sweep(): Double =
{
var count = 0
for (i &<- 0 to sweepTimes-1)
{
this.shuffle(shuffleTimes)
if (noneMatched())
{
count = count + 1
}
}
return count.toDouble/sweepTimes.toDouble
}
def monteCarlo(): Unit =
{
for (i &<- 0 to binNumber-1)
{
var f: Double = this.sweep()
frequency.append(f)
println(i + " " + binNumber + " " + f)
}
}
def getMeanFrequency():Double = {
var sum = 0.0
this.monteCarlo()
for (f &<- frequency)
{
sum = sum + f
}
return sum/frequency.size.toFloat
}
def getEulerConstant():Double = {
return 1.0/this.getMeanFrequency()
}
}
object Euler
{
def main(args: Array[String])
{
var sampleNumber = 30
val monteCarlo: MonteCarlo = new MonteCarlo(sampleNumber)
monteCarlo.setSweepTimes(2000)
monteCarlo.setBinNumber(200)
println("Euler constant e = " + monteCarlo.getEulerConstant())
}
}
我感覺直接計算來得快,畢竟階乘收斂不是蓋的
跟以前科學家驗證硬幣概率的方法類似,朝地上撒幣。
撒了N多幣之後,硬幣除了為正或反,還會有一些立在地上。假設有n個幣立在地上,就把所有的硬幣隨機均分為n份。數一數有多少份裡面沒有任何硬幣立著。這個份數大約是n/e。關鍵是n和N/n都不能太小。如果你不想撒幣,還可以換成氪金抽卡,硬幣立起相當於抽到你想要的卡。如果提前知道概率為p,還可以每1/p次為一組,記錄有否成功。一組全失敗的概率大約是1/e。以下內容截取自馬丁·加德納的科普讀物《意料之外的絞刑和其他數學娛樂》
謝邀!今天不是七夕嘛,看著那些情侶在秀恩愛你讓我們如何有心情回答問題呢?所以容我們FFF團先燒死幾對,我再告訴你,最簡單的方法就是直接計算啊,1+1+1/2+1/6+1/24+……1/n!(感謝@拉格朗 提醒,修正錯誤)很快就能達到你要的精度。估計圓周率的那個實驗也是,直接計算級數比買幾千根針再一遍一遍投要簡單的多,還精確的多。投針試驗也需要兩個人合作,單身狗們就不要想了。其實,想想七夕節一對對情侶一起和睦做實驗的場景,意外的很美麗。
瘋狂地存錢取錢存錢取錢
- 設定一個數字 x,最好滿足 x &> 20 ; 設定一個實驗次數 X,譬如 X = 1000000
- 初始計數 c = 0
- 選一對情侶,重複 x 次 { 女方隨機抽取一個在 [1,x] 之間的數字,令男方猜測該數字 },若男一次也沒有猜中, c 加 1
- 重複 3. 的實驗 X 次
- 得到 e 的估算數值
註:設定 X 為 1000000,x 為 100,某次運行模擬,代碼給出的結果是 2.7302
用這個: 服從某一個泊松分布 ,則概率:
。且 。
只是可能要去公交站台或食堂了。
這個必須強答一發了每次說給小夥伴聽對方都似懂非懂的樣子,我自以為說的很通俗易懂啊……我現在高一升高二的暑假,(雖然已經上課快一個月了),這個小小的發現是我在一年前,上高一軍訓後不久,一節無聊的晚自習發現的。不知道你們有沒有想過一個問題,設銀行年利率為1,本金為1,一年後你連本帶利將收穫2元但如果以半年算,利率為0.5,每半年利滾利算一次,一年後很顯然要多於2元,事實上是(1+1/2)∧2=2.25元如果以月利率1/12算,結果是(1+1/12)∧12,事實上要大於2.25以利滾利的周期作為自變數,得到函數y=(1+1/x)∧x當時就有一種神奇的預感了……在書上看過e,只記得數值2.71828……果然,這個函數單調遞增,我回家用計算器算了一下,總是無限逼近e以上
商店賣東西,覺著想漲點價。
比方說要求漲價的比率合起來不能大於1,但是漲價的策略可以分很多次進行。我可以第一次漲50%,第二次又漲50%,合起來就是1…但怎麼能漲到價格最高??取一個很大的n,漲n次,每次漲1/n。這是e一個實際點的例子是降價。
商店發出公告,表示近期要降價多次,降價比達100%。總降價量最低的降價策略:取一個很大的n, 每次降當前的1/n,降n次。這是1/e一個好玩點的例子有這樣一種魔法,根據消耗的魔力百分比,會增加當前被施法者的所有屬性以相同的百分比。那麼在一個施法者的輔助下,被施法者的屬性最多提升到原先的e倍。我來說一個有意思的實驗。
七夕節到了,小明給女神小紅表白,成功抱得美人歸~情侶嘛,一般都要干那個不可描述的事情的。一天一次?感覺太頻繁了;兩天一次?感覺太少了。小紅和小明就想了一個辦法:晚上到底啪不啪,用概率決定,規則如下:每天晚上啪啪的概率等於:1/(1+連續啪啪天數)
例如,他們已經連續啪啪5天了,這天晚上啪啪的概率就是1/6,如果運氣好,又啪啪了,我們說這是以概率1/6決定的啪啪;如果他們哪天晚上沒有啪啪,連擊天數就清零了,那麼按照公式第二天晚上必定啪啪,這是以概率1決定的啪啪。
我們來算一下他們平均多少天啪啪一次吧~假設他們有N天晚上沒有啪啪(N很大)
那麼有N次啪啪是以概率1決定的。那麼有N/2次啪啪是以概率1/2決定的。(N/2是期望,之後同理)那麼有N/6次啪啪是以概率1/3決定的。..........總的啪啪天數:N+N/2+N/6+N/24....我們知道這個和是 N乘e總天數是N(1+e)所以平均1+1/e天啪啪一次我不會告訴你我就是這個小明N個人,每個人有一個專屬伴侶。每個人隨機盲選一個,沒人選到自己原配的概率是1/e。
有n個不同的數,做n次有放回的抽樣實驗。沒有被抽到的概率是(1-1/n)^n。取對數後令x=1/n,即nln(1-1/n)=ln(1-1/n)/(1/n)=ln(1-x)/x,當n趨於正無窮的時候x趨於0。利用洛必塔法則可以求得結果為1/(x-1)=-1。所以最終可以知道數字沒有被抽到的概率為1/e,剩下只要統計沒被抽到的數字的比例就行了。
泰勒展開式
推薦閱讀: