Я недавно начал играть с Джулией, и сейчас я работаю над моделированием Монте-Карло некоторого случайного процесса на двумерной решетке. Каждый сайт имеет некоторую ассоциированную скорость активации (количество раз, когда он в среднем "что-то" делает в секунду), которую мы можем считать приблизительно постоянной. Порядок, в котором сайты решетки активируют , имеет значение, поэтому нам нужен метод случайного выбора одного конкретного сайта с вероятностью, пропорциональной его скорости активации .
Похоже, что sample(sites,weights(rates))
из пакета StatsBase
- это именно то, что я ищу, НО из тестирования моей структуры кода (без логики, только циклы и ГСЧ), получается, что sample()
линейно масштабируется с количество сайтов. Это означает, что в целом мое время выполнения масштабируется как N ^ (2 + 2), где N - длина стороны моей 2-мерной решетки (один фактор 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
в правильной (накопительной) форме по всему коду.