Вы думали об использовании цепи Маркова ? По сути, это «вероятностный клеточный автомат», обеспечивающий желаемую случайность. Вместо того, чтобы предписывать новое поколение в терминах локальных соседей существующего поколения, оно определяет распределение вероятностей для нового поколения. Это распределение можно оценить, скажем, по временным последовательностям изображений одинаковых или похожих областей.
Интуитивно понятно, что эта модель говорит, что ячейка не обязательно будет осуществлять переход от покрытых лесами к не покрытым лесом (или наоборот ), но шансы, что это сделает переход, зависят от земного покрова, непосредственно окружающего ее. Он может обрабатывать несколько классов укрытий, сложные конфигурации окрестностей и даже обобщаться, чтобы «помнить» недавнюю историю эволюции растительного покрова.
Переходы могут быть реализованы с помощью операторов алгебры карт, что делает этот метод практически применимым в любой растровой ГИС, даже в тех, которые не имеют прямого или быстрого доступа к данным на уровне ячеек. Использование R делает это еще проще.
Например, рассмотрим эту начальную конфигурацию только с двумя классами, белым и черным:
Чтобы проиллюстрировать, что может произойти, я создал параметризованную модель (не основанную на каких-либо данных), в которой переход к черному происходит с вероятностью 1 - q ^ k, где k - среднее число черных клеток в окрестности 3 на 3 (k = 0, 1/9, 2/9, ..., 1). Когда либо q мало, либо большая часть окрестности уже черная, новая ячейка будет черной. Вот четыре независимых моделирования десятого поколения для пяти значений q в диапазоне от 0,25 до 0,05:
Очевидно, что эта модель имеет многие характеристики ЦС, но она также включает в себя случайный эффект, полезный для изучения альтернативных результатов.
Код
Следующее реализует моделирование в R
.
#
# Make a transition from state `x` using a kernel having `k.ft` as
# its Fourier transform.
#
transition <- function(x, k.ft, q=0.1) {
k <- zapsmall(Re(fft(k.ft * fft(x), inverse=TRUE))) / length(x)
matrix(runif(length(k)) > q^k, nrow=nrow(k))
}
#
# Create the zeroth generation and the fft of a transition kernel.
#
n.row <- 2^7 # FFT is best with powers of 2
n.col <- 2^7
kernel <- matrix(0, nrow=n.row, ncol=n.col)
kernel[1:3, 1:3] <- 1/9
kernel.f <- fft(kernel)
set.seed(17)
x <- matrix(sample(c(0,1), n.row*n.col, replace=TRUE, prob=c(599, 1)), n.row)
#
# Prepare to run multiple simulations.
#
y.list <- list()
parameters <- c(.25, .2, .15, .1, .05)
#
# Perform and benchmark the simulations.
#
i <- 0
system.time({
for (q in parameters) {
y <- x
for (generation in 1:10) {
y <- transition(y, kernel.f, q)
}
y.list[[i <- i+1]] <- y
}
})
#
# Display the results.
#
par(mfrow=c(1,length(parameters)))
invisible(sapply(1:length(parameters),
function(i) image(y.list[[i]],
col=c("White", "Black"),
main=parameters[i])))
raster
пакет? У него много инструментов для работы с растровыми (ну, ладно?) Данными.