求一個數學公式:要求生成一個可控制分布的隨機數?
比如:生成一個隨機值 rand (範圍是 1-100)。rand中出現小的值概率很高,但大的值的概率很低。希望大神給一個具體的公式。隨機值用rand替代就行。最好可以用代碼實現,比如PHP Python等,謝謝!
給定一個累積分布函數( cumulative distribution function, CDF),只要能求出其反函數,就能把均勻分布的隨機數映射至。這稱為 Inverse transform sampling。
Random sampling (numpy.random)
numpy.random 已經實現了從定義好的分布中抽樣的函數,比如beta(a, b[, size]) Draw samples from a Beta distribution.
binomial(n, p[, size]) Draw samples from a binomial distribution.
chisquare(df[, size]) Draw samples from a chi-square distribution.
dirichlet(alpha[, size]) Draw samples from the Dirichlet distribution.
exponential([scale, size]) Draw samples from an exponential distribution.
f(dfnum, dfden[, size]) Draw samples from an F distribution.
gamma(shape[, scale, size]) Draw samples from a Gamma distribution.
geometric(p[, size]) Draw samples from the geometric distribution.
gumbel([loc, scale, size]) Draw samples from a Gumbel distribution.
假設樓主取的是1-100的整數,100的概率比99大一倍,99比98大一倍,那麼按1 為基準,總和SUM= 1+2+ 4 + 2^99 =2^100-1那麼 隨機取rand(1,SUM), 如果在2^30-1到2^31範圍之間,那麼就是取到30。簡單的公式是log(rand(1,SUM))/log2
舍選法。不用特別擔心計算次數:
獻一下丑,有錯誤勞煩指出!
恰好做畢設碰到了這個問題,與大家分享下。
假設我們獲得了每個值的概率,然後對每個值的概率進行累加,將每次累加結果統一放在一個數軸上表示。我們取10個值來說明問題,如下圖:
[i]表示第i個值,橫坐標軸(0-0.1)就代表 [1]的概率;(0.5-0.75)代表第 [7]的概率;(0-0.75)代表 [1]到 [7]的概率累加和。
接下來,比如說在matlab里,使用rand()函數,產生一個範圍為0-1均勻分布的隨機數,假如圖中產生的數為0.65,它落在(0.5-0.75)這個區間,而這個區間代表著 [7]的概率。於是,我們判定將 [7]拿出來作為本次按概率篩選的結果。
附matlab的代碼
%其中max_column值的個數,prob代表每個
%值的概率,prob_array代表概率累加和 %largest_cumulative_prob代表概率累加最大值for j=1:max_column -1
prob_array(j+1) = prob_array(j)+prob(j);endlargest_cumulative_prob=prob_array(max_column);
%largest_cumulative_prob和prob_array需要做%歸一化,代碼里沒有做
choice = rand() * largest_cumulative_prob;
low = 1;
high = max_column;while (high&>(low+1)) middle = (high+low)/2; middle = floor(middle); if (choice &> prob_array(middle)) low = middle; else high = middle;end
end%最後取出low作為本次篩選結果%這裡就不解釋了,其思想和上面圖中一樣的 這個方法適用於離散的數,對於連續的數我還不清楚怎麼處理,個人猜想可能會用到概率密度?望大神解答!看過一點ndndsim的源碼。裡面生成zipf分布的方法很有趣。希望能給題主參考。給定累積分布函數和範圍比如是1-50。算出累計分布函數在1到50函數值存在數組裡。然後用一個均勻分布 生成一個隨機數。然後依次和五十個分布函數值比較。返回下標。當然返回下標這一點可以隨要求變化。
100/rand(1,100)
rand(1,rand(1,rand(1,100)))這樣你看行不行
推薦閱讀:
※Python的for使用問題?
※怎麼樣算是學會一門編程語言?
※你們開始是如何學習編程的?
※看代碼千行,不如手寫一行,是否在理?為何?
※通過什麼可以了解一個程序員/黑客的真實水平?