我最近开始和 Julia 一起玩,我目前正在对二维晶格上的一些随机过程进行蒙特卡罗模拟。每个站点都有一些相关的激活率(平均每秒它“做某事”的次数),我们可以假设它是近似恒定的。晶格位点的激活顺序是相关的,因此我们需要一种随机选择一个特定位点的方法,其概率与激活率成正比。
sample(sites,weights(rates))
从包中看起来StatsBase
正是我正在寻找的东西,但是通过测试我的代码结构(没有逻辑,只有循环和 RNG),结果证明它sample()
与站点数量成线性关系。这意味着总体上我的运行时间像 N^(2+2) 一样缩放,其中 N 在我的二维晶格的边长中(一个因子为 2 来自总活动率的增加,另一个来自 的缩放sample()
)。
现在,总活动率的增加是不可避免的,但我认为“随机选择权重”方法的缩放比例可以改进。更具体地说,应该能够实现与站点数量的对数缩放(而不是线性)。例如考虑以下功能(请原谅糟糕的编码)
function randompick(indices,rates)
cumrates = [sum(rates[1:i]) for i in indices]
pick = rand()*cumrates[end]
tick = 0
lowb = 0
highb = indis[end]
while tick == 0
mid = floor(Int,(highb+lowb)/2)
midrate = cumrates[mid]
if pick > midrate
lowb = mid
else
highb = mid
end
if highb-lowb == 1
tick = 1
end
end
return(highb)
end
因为我们在每一步中将“可挑选”站点的数量减半,所以需要 n 步才能从 2^n 中挑选一个特定站点(因此是对数缩放)。但是,在其当前状态下,它的速度比缩放实际上randompick()
要慢得多。sample()
有没有办法将此方法简化为可以与之竞争sample()
并因此利用改进的缩放比例的形式?
编辑:也计算cumrates
像 N^2 这样的比例,但这可以通过rates
在整个代码中以正确的(累积)形式使用来解决。