Czy myślałeś o użyciu łańcucha Markowa ? Jest to faktycznie „probabilistyczny automat komórkowy”, zapewniając w ten sposób pożądaną losowość. Zamiast zalecać nowe pokolenie w kategoriach lokalnych sąsiadów istniejącego pokolenia, określa rozkład prawdopodobieństwa dla nowego pokolenia. Rozkład ten można oszacować, powiedzmy, na podstawie sekwencji czasowych obrazów tego samego lub podobnego obszaru.
Intuicyjnie ten model mówi, że komórka niekoniecznie dokona przejścia z zalesionej na nieleśną (lub odwrotnie ), ale szanse, że sprawi, że przejście będzie zależeć od pokrycia terenu bezpośrednio wokół niego. Może obsługiwać wiele klas pokrycia, złożone konfiguracje dzielnic, a nawet zostać uogólniony, aby „zapamiętać” najnowszą historię ewolucji pokrycia terenu.
Przejścia można zaimplementować za pomocą instrukcji Map Algebra, co czyni tę metodę możliwą do zastosowania w dowolnym systemie GIS opartym na rastrze, nawet bez bezpośredniego lub szybkiego dostępu do danych na poziomie komórki. Używanie R sprawia, że jest to jeszcze łatwiejsze.
Rozważmy na przykład tę konfigurację początkową zawierającą tylko dwie klasy, białą i czarną:
Aby zilustrować, co może się zdarzyć, stworzyłem sparametryzowany model (nie oparty na żadnych danych), w którym przejście do czerni występuje z prawdopodobieństwem 1 - q ^ k, gdzie k jest średnią liczbą czarnych komórek w sąsiedztwie 3 na 3 (k = 0, 1/9, 2/9, ..., 1). Gdy q jest małe lub większość sąsiedztwa jest już czarna, nowa komórka będzie czarna. Oto cztery niezależne symulacje dziesiątej generacji dla pięciu wartości q w zakresie od 0,25 do 0,05:
Oczywiście model ten ma wiele cech charakterystycznych CA, ale zawiera także efekt losowy przydatny do badania alternatywnych wyników.
Kod
Poniżej zaimplementowano symulację w 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
paczkę? Ma wiele narzędzi do pracy z danymi rastrowymi (noo, rly?).