給定以下演算法,如果隨機輸入值u小于(累積)prob向量中的某個預定義概率,則從預定義列舉中回傳一個值
val <- 1:5
prob <- c(1/3,1/30,2/15,7/30,4/15)
u <- runif(1)
if (u<prob[1])
{
x=val[1]
} else if(u<prob[1] prob[2])
{
x=val[2]
} else if(u<prob[1] prob[2] prob[3])
{
x=val[3]
} else if (u<prob[1] prob[2] prob[3] prob[4])
{
x=val[4]
} else
x=val[5]
}
有沒有辦法讓這一切更有效率?我無法弄清楚如何以不同的方式做到這一點。
uj5u.com熱心網友回復:
另一種方法是使用findInterval. 例如
val <- 1:5
prob <- c(1/3,1/30,2/15,7/30,4/15)
u <- runif(1)
val[findInterval(u, cumsum(c(0, prob)))]
這也適用于任意數量的值
u <- runif(1000)
val[findInterval(u, cumsum(c(0, prob)))]
uj5u.com熱心網友回復:
我不知道這是否是關于演算法的具體問題,或者您是否想更快地解決問題。
sample(val, size = 1, prob = prob)肯定會比您的解決方案更快,但我不知道內部演算法是否從根本上比您的更好(例如在操作計數方面)。
查看C 源代碼,您可以看到該演算法與您的演算法相似,只是它預先計算累積概率以避免重復添加(并將元素排列為降序 - 我認為這是為了數值穩定性而不是效率)。
(這是用于帶替換的采樣;不帶替換的代碼看起來非常相似,除了洗掉先前采樣值的機制使它更復雜一些)
uj5u.com熱心網友回復:
您可以使用cumsum和which:
set.seed(3)
u <- runif(1)
#[1] 0.702374
val[which(u < cumsum(prob))[1]]
#[1] 4
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/529916.html
標籤:r
上一篇:從R中的行總數計算百分比
