Чи думали ви використовувати ланцюжок Маркова ? Це фактично "ймовірнісний стільниковий автомат", забезпечуючи тим самим бажану випадковість. Замість того, щоб прописати нове покоління з точки зору місцевих сусідів існуючого покоління, він визначає розподіл ймовірностей для нового покоління. Такий розподіл можна оцінити з, скажімо, часових послідовностей зображень одного і того ж або подібних областей.
Інтуїтивно ця модель говорить про те, що клітина не обов’язково здійснюватиме перехід від лісового до нелісового (або навпаки ), але шанси на те, що вона зробить перехід, залежать від земельного покриву безпосередньо навколо неї. Він може працювати з декількома класами покриття, складною конфігурацією мікрорайонів і навіть бути узагальненим, щоб "запам'ятати" недавню історію розвитку земельного покриву.
Переходи можуть бути реалізовані за допомогою операторів Map Algebra, що робить цей метод практичним у будь-яких растрових GIS, навіть у тих, що не мають прямого або швидкого доступу до даних рівня клітин. Використання 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
пакет? У ньому багато інструментів для роботи з растровими (noo, rly?) Даними.