Questo è un problema di colorazione del grafico .
Ricorda che una colorazione del grafico è un'assegnazione di un colore ai vertici di un grafico in modo tale che nessun vertice che condivida un bordo abbia lo stesso colore. In particolare, i vertici (astratti) del grafico sono i poligoni. Due vertici sono collegati con un bordo (non orientato) ogni volta che si intersecano (come poligoni). Se prendiamo una soluzione al problema - che è una sequenza di (diciamo k ) raccolte disgiunte dei poligoni - e assegniamo un colore unico a ciascuna raccolta nella sequenza, allora avremo ottenuto un k -colore del grafico . È desiderabile trovare un piccolo k .
Questo problema è piuttosto difficile e rimane irrisolto per grafici arbitrari. Prendi in considerazione una soluzione approssimativa semplice da codificare. Un algoritmo sequenziale dovrebbe fare. L'algoritmo Welsh-Powell è una soluzione avida basata su un ordine decrescente dei vertici per grado. Tradotto nella lingua dei poligoni originali, prima ordina i poligoni in ordine decrescente del numero di altri poligoni che si sovrappongono. Lavorando in ordine, dai al primo poligono un colore iniziale. In ogni passaggio successivo, prova a colorare il poligono successivo con un colore esistente: ovvero, scegli un colore che non lo siagià utilizzato da nessuno dei vicini di quel poligono. (Esistono molti modi per scegliere tra i colori disponibili; prova quello che è stato meno utilizzato oppure scegline uno a caso.) Se il prossimo poligono non può essere colorato con un colore esistente, creane uno nuovo e coloralo con quello.
Una volta ottenuta una colorazione con un piccolo numero di colori, esegui zonalstats colore per colore: per costruzione, hai la garanzia che non si sovrappongano due poligoni di un determinato colore.
Ecco il codice di esempio in R
. (Il codice Python non sarebbe molto diverso.) Innanzitutto, descriviamo le sovrapposizioni tra i sette poligoni mostrati.
edges <- matrix(c(1,2, 2,3, 3,4, 4,5, 5,1, 2,6, 4,6, 4,7, 5,7, 1,7), ncol=2, byrow=TRUE)
Cioè, i poligoni 1 e 2 si sovrappongono, e così fanno i poligoni 2 e 3, 3 e 4, ..., 1 e 7.
Ordina i vertici in ordine decrescente:
vertices <- unique(as.vector(edges))
neighbors <- function(i) union(edges[edges[, 1]==i,2], edges[edges[, 2]==i,1])
nbrhoods <- sapply(vertices, neighbors)
degrees <- sapply(nbrhoods, length)
v <- vertices[rev(order(degrees))]
Un algoritmo di colorazione sequenziale (grezzo) utilizza il primo colore disponibile non ancora utilizzato da nessun poligono sovrapposto:
color <- function(i) {
n <- neighbors(i)
candidate <- min(setdiff(1:color.next, colors[n]))
if (candidate==color.next) color.next <<- color.next+1
colors[i] <<- candidate
}
Inizializza le strutture dati ( colors
e color.next
) e applica l'algoritmo:
colors <- rep(0, length(vertices))
color.next <- 1
temp <- sapply(v, color)
Dividi i poligoni in gruppi in base al colore:
split(vertices, colors)
L'output in questo esempio utilizza quattro colori:
$`1`
[1] 2 4
$`2`
[1] 3 6 7
$`3`
[1] 5
$`4`
[1] 1
Ha suddiviso i poligoni in quattro gruppi non sovrapposti. In questo caso la soluzione non è ottimale ({{3,6,5}, {2,4}, {1,7}} è un tricolore per questo grafico). In generale, tuttavia, la soluzione che ottiene non dovrebbe essere troppo male.