2010-11-05 72 views
0

可悲的是,儘管在範圍中使用了統一整數,但在編程中使用隨機數並不是很有經驗。所以我不得不對這個話題提出疑問。連續分佈的指數衰減類隨機分佈和離散化

問題1(更具體的):

我根據類似於「指數衰減」的曲線的概率分佈尋找一種方式來選擇的數組元素(動態大小,但已知的)http://en.wikipedia.org/wiki/Exponential_decay)。 含義:我希望選擇第一個元素而不是其他元素。我想要一個單調遞減函數(在減少像在許多衆所周知的概率分佈一樣減少,如伽馬分佈)。

也許幾何分佈是我可以使用的東西?但是,然後我需要回答我的第二個問題,即關於將此分佈擴展到數組索引的問題。

當然,選擇最後一個元素而不是第一個的雙重方法當然也可以。

問題2(更普遍): 是否有任何實現的一個概念,這將擴大我任何連續隨機分配到一個給定的陣列範圍(包括離散化)?

示例:使用高斯正態分佈,結果始終是某個數組中的有效索引(意思是:中間元素是首選)。

難道這(link text)是像我想用的東西?

平臺和庫: 我編程C++和使用的boost ::隨機庫的時刻(link text),但我願意使用類似的GSL庫或其他質量庫。

還有一個心願: 我會使用一些質量庫,而不是一些快速和骯髒的custom_functions喜歡的方式。

謝謝!

+1

我不明白你的問題1.指數衰減是其中的任何元素有一定的時間間隔內衰減的相同的固定可能性。優先選擇數組中的第一個元素似乎與其他數據無關?你究竟想要完成什麼? – 2010-11-05 18:08:59

+0

爲什麼你不想使用boost :: random? (它似乎有你所要求的) – log0 2010-11-05 18:28:23

+0

@Alf:我提到指數衰減只是爲了描述我想要的概率分佈曲線。如果我將一個數組作爲指數衰減曲線的x軸,那麼y軸應該是這個數組元素被選中的概率 – sascha 2010-11-05 21:59:01

回答

1

我認爲把這個問題分成兩個步驟是一個很好的開始。首先,如果你有一個離散的概率分佈,那麼從這個分佈中繪製的問題就不那麼糟糕了。隨機增強有這樣做的方法。向下滾動這個page加權骰子的例子。它會從給定的概率分佈中返回一個整數。你可以使用這個整數來選擇你感興趣的數組中的元素。

你的問題的第二部分是如何從連續概率分佈如exponential變成離散分佈,如使用什麼提升的例子。有幾種方法可以去這裏,但是因爲你說你想要一條像「指數衰減」的曲線,我會嘗試解釋一個快速而簡單的實現,我們正在犧牲一些統計嚴謹性。

這裏的想法是從一組離散點的連續分佈中抽樣,然後調整這些點(歸一化),使它們和爲一。下面是用於指數分佈的代碼。

double expDist(int x, double lambda) 
{ 
    return(lambda*exp(-lambda*x)); 
} 

//code to sample from this distribution 
int i,numElements //where numElements has the number of elements in the array you wish to draw from. 
vector<double> output; 
double sum,temp 
sum=0; 
for(i=0;i<numElements;i++) 
{ 
    temp=expDist(i,0.5); //substitute any value you want for lambda in the second argument 
    output.push_back(temp); 
    sum+=temp; 
} 
//after having sampled at all the points we need to divide each element in the array by the variable sum so that the sum of the values in the array is equal to 1 and thus a valid probability distribution 
for(i=0;i<numElements;i++) 
{ 
    output[i]/=sum; 
} 

您可以再喂輸出變量進入Boost庫加權骰子例子,它應該滿足您的需求。這種離散採樣和歸一化矢量的一般方法可用於許多不同類型的分佈。

+0

非常感謝您的想法,您的鏈接(特別是dice_example;我在幾個月前看到過,沒有看到任何應用程序)和您的代碼。我會嘗試。 – sascha 2010-11-05 22:12:52

2

Q1)它聽起來像你要找的是一個exponential distribution。 Boost庫附帶exponential distribution generator

Q2)這聽起來像是你想創建一個histogram。在你的網站的例子中,設置你的數組中間區域的bin來表示元素更接近你從分佈中繪製的正常隨機值的平均值。如果您沒有足夠的關於分配性質的信息,則需要從感興趣的分配中收集具有代表性的樣本,並將其存儲在另一個陣列中。使用樣本的最小值和最大值,然後可以創建另一個數組以計算每個元素中有多少個採樣元素。合理的經驗法則是,如果您有n個樣本,則應該有sqrt(n)個元素。

更新:如果Tryer正確地指出,如果您在創建直方圖之前未將分佈的元素保存到第二個數組中,則需要找到某些處理已建立的元素之外的元素的方法。

+0

Argh。我錯過了指數分佈。我確信,這個發行版不是在boost :: random中。但你是對的,它是。 – sascha 2010-11-05 22:08:11

2

您的Q2:「例子:使用高斯正態分佈,結果總是某個數組中的有效索引(意思是:中間元素是首選)。」

除非我誤解這是不正確的。理論上,遵循正態分佈的隨機變量可以取值範圍(-infinity,infinity)。因此,除非您截斷異常值並強制將外部的隨機變量值(例如+/- 3標準偏差)偏移到+/- 3rd標準偏差值,否則無法強制將正態分佈強制到有限網格上。

+2

這會截斷可能值的0,03%。這是負擔得起的。 – Andrey 2010-11-05 18:49:10

4

一般規則是在統一分佈中選擇您的數字,然後應用函數將它們轉換爲您想要的分佈。您應用的函數是您希望隨機數落入的函數的逆函數。

如果要隨機數與f(x)成比例的概率,然後從均勻分佈中選取一個隨機數,你,並應用f^-1(u)這就是你的新號碼。

所以,如果你希望你的隨機數與概率比例會被選中,EXP(-x),那麼你選擇一個均勻分佈的隨機數,並利用它的LN:

double x=ln(rand()); 

應該給你隨機數字的概率分佈爲exp(-x)。

注意:我不是說rand()是一個很好用的函數,你需要研究好的隨機數生成器的細節。但假設你有一個好的隨機數發生器,這是一個很好的解決方案。

編輯:忘了一個減號:

double x=-ln(rand()); 

是正確的答案。

1

我想你是不是尋找一個指數分佈,因爲指數分佈假設的無限數量的元素,因此得到您的序列的最後一個元素的偏差。

什麼適合你的問題是一個Beta distribution與阿爾法< 1和β> 1

+0

謝謝。我會仔細看看的。 – sascha 2010-11-06 15:35:42