Hai pensato di usare una catena Markov ? Questo è effettivamente un "automa cellulare probabilistico", fornendo così la casualità desiderata. Invece di prescrivere la nuova generazione in termini di vicini locali della generazione esistente, specifica una distribuzione di probabilità per la nuova generazione. Tale distribuzione può essere stimata, ad esempio, da sequenze temporali di immagini della stessa area o simili.
Intuitivamente, questo modello afferma che una cellula non effettuerà necessariamente una transizione da forestale a non forestale (o viceversa ), ma le possibilità che questa transizione dipenda dalla copertura del terreno immediatamente circostante. Può gestire più classi di copertura, configurazioni complesse di quartieri e persino essere generalizzato per "ricordare" la storia recente dell'evoluzione della copertura del suolo.
Le transizioni possono essere implementate usando le istruzioni Map Algebra, il che rende questo metodo praticabile in qualsiasi GIS basato su raster, anche quelli senza accesso diretto o rapido ai dati a livello di cella. L'uso di R rende ancora più semplice.
Ad esempio, considera questa configurazione iniziale con solo due classi, bianco e nero:
Per illustrare cosa può accadere, ho creato un modello con parametri (non basato su alcun dato) in cui la transizione al nero avviene con probabilità 1 - q ^ k dove k è il numero medio di cellule nere all'interno del vicinato 3 per 3 (k = 0, 1/9, 2/9, ..., 1). Quando q è piccolo o la maggior parte del quartiere è già nero, la nuova cella sarà nera. Ecco quattro simulazioni indipendenti della decima generazione per cinque valori di q che vanno da 0,25 a 0,05:
Evidentemente questo modello ha molte delle caratteristiche di una CA ma include anche un effetto casuale utile per esplorare risultati alternativi.
Codice
Di seguito implementa la simulazione in 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
pacchetto? Ha molti strumenti per lavorare con dati raster (noo, rly?).