我希望能夠創建3個(非負的)隨機數,總和爲1,然後重複一遍又一遍。生成3個總和爲1的隨機數R
基本上我試圖在許多試驗中將東西分成三個隨機部分。
雖然我知道
A = runif(3,0,1)
我在想,我可以使用1-A作爲下一次運行,如果最大,但似乎凌亂。
但這些當然不算一個。任何想法,明智的stackoverflow-ers?從
我希望能夠創建3個(非負的)隨機數,總和爲1,然後重複一遍又一遍。生成3個總和爲1的隨機數R
基本上我試圖在許多試驗中將東西分成三個隨機部分。
雖然我知道
A = runif(3,0,1)
我在想,我可以使用1-A作爲下一次運行,如果最大,但似乎凌亂。
但這些當然不算一個。任何想法,明智的stackoverflow-ers?從
只是隨機的2個數字(0,1),如果假設其a
和b
然後你有:
rand1 = min(a, b)
rand2 = abs(a - b)
rand3 = 1 - max(a, b)
此外,你必須重複生成第二個數字,如果一個== b ...(應該是非常罕見的情況下) – ddzialak
@user so a = 0.85 ,b = 0.99那麼你得到的數字是:0.85,0.14,0.01(對於我來說這些都是非常好的,從0..1開始的3個隨機數) – ddzialak
由此產生的分佈似乎並不完全無關緊要:http://www.jstor。 org/discover/10.2307/2983572?uid = 2129&uid = 2&uid = 70&uid = 4&sid = 21100849643501 and later paper can be free access http://doc.utwente.nl/70657/1/Sleutel67random.pdf – Christian
我想這取決於你想上的數字是什麼分佈,但在這裏是一種方式:只要你想
diff(c(0, sort(runif(2)), 1))
使用replicate
獲得儘可能多套:
> x <- replicate(5, diff(c(0, sort(runif(2)), 1)))
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 0.66855903 0.01338052 0.3722026 0.4299087 0.67537181
[2,] 0.32130979 0.69666871 0.2670380 0.3359640 0.25860581
[3,] 0.01013117 0.28995078 0.3607594 0.2341273 0.06602238
> colSums(x)
[1] 1 1 1 1 1
這個問題涉及的問題可能比最初看起來更微妙。查看以下後,你可能要仔細考慮您正在使用這些數字來表示流程:
## My initial idea (and commenter Anders Gustafsson's):
## Sample 3 random numbers from [0,1], sum them, and normalize
jobFun <- function(n) {
m <- matrix(runif(3*n,0,1), ncol=3)
m<- sweep(m, 1, rowSums(m), FUN="/")
m
}
## Andrie's solution. Sample 1 number from [0,1], then break upper
## interval in two. (aka "Broken stick" distribution).
andFun <- function(n){
x1 <- runif(n)
x2 <- runif(n)*(1-x1)
matrix(c(x1, x2, 1-(x1+x2)), ncol=3)
}
## ddzialak's solution (vectorized by me)
ddzFun <- function(n) {
a <- runif(n, 0, 1)
b <- runif(n, 0, 1)
rand1 = pmin(a, b)
rand2 = abs(a - b)
rand3 = 1 - pmax(a, b)
cbind(rand1, rand2, rand3)
}
## Simulate 10k triplets using each of the functions above
JOB <- jobFun(10000)
AND <- andFun(10000)
DDZ <- ddzFun(10000)
## Plot the distributions of values
par(mfcol=c(2,2))
hist(JOB, main="JOB")
hist(AND, main="AND")
hist(DDZ, main="DDZ")
不錯,我是考慮繪製結果,但你已經做到了。有趣的是,看到這些解決方案顯然沒有一個能夠直觀地理解人們喜歡的東西。同樣有趣的是,在這些情節中,你無法真正看到DDZ根據手段做了正確的事情,而AND甚至沒有做到這一點。 – Christian
當你想隨機生成添加到1號(或某些其他值),那麼你應該看看Dirichlet Distribution。
有一個在gtools
包的rdirichlet
功能和運行RSiteSearch('Dirichlet')
帶來了不少點擊率是很容易導致你的工具這樣做(和它是不是很難代碼手工無論是簡單的狄氏分佈)。
這個問題和提出的不同解決方案讓我很感興趣。我對建議的三種基本算法做了一些測試,並對產生的數字產生了多少平均值。
choose_one_and_divide_rest
means: [ 0.49999212 0.24982403 0.25018384]
standard deviations: [ 0.28849948 0.22032758 0.22049302]
time needed to fill array of size 1000000 was 26.874945879 seconds
choose_two_points_and_use_intervals
means: [ 0.33301421 0.33392816 0.33305763]
standard deviations: [ 0.23565652 0.23579615 0.23554689]
time needed to fill array of size 1000000 was 28.8600130081 seconds
choose_three_and_normalize
means: [ 0.33334531 0.33336692 0.33328777]
standard deviations: [ 0.17964206 0.17974085 0.17968462]
time needed to fill array of size 1000000 was 27.4301018715 seconds
的時間測量與一粒鹽被視爲他們可能會更受Python的內存管理不是通過算法本身的影響。我懶得用timeit
正確地做。我在1GHz Atom上做了這個,這就解釋了爲什麼花了這麼長時間。
無論如何,choose_one_and_divide_rest是Andrie建議的算法和他/她自己的問題海報(AND):您在[0,1]中選擇一個值a,然後在[a,1]中選擇一個值,你留下了什麼。它加起來只有一個,但這就是它,第一個分裂是另外兩個分裂的兩倍。人們可能已經猜到了很多...
choose_two_points_and_use_intervals是ddzialak接受的答案(DDZ)。在區間[0,1]中需要兩個點,並使用由這些點創建的三個子區間的大小作爲三個數字。像魅力一樣工作,手段都是1/3。
choose_three_and_normalize是Anders Gustafsson和Josh O'Brien(JOB)的解決方案。它只是在[0,1]中生成三個數字,並將它們歸一化爲1的總和。在我的Python實現中工作得更好一些,出人意料地快了一點。方差比第二種解決方案稍低。
你有它。不知道這些解決方案對應的beta版本的分佈情況,或者我在評論中提到的相應論文中的哪些參數集,但也許其他人可以弄清楚。
是否可以在生成後重新規範化隨機數? –
如何生成2個隨機數a和b?那麼a + b + c = 1 => c = 1-(a + b) –
並且如果a和b之和大於1? – mmann1123