Il s'agit d'un problème de coloration de graphique .
Rappelez-vous qu'un coloriage de graphe est une affectation d'une couleur aux sommets d'un graphe de telle sorte qu'aucun deux sommets qui partagent un bord n'auront également la même couleur. Plus précisément, les sommets (abstraits) du graphique sont les polygones. Deux sommets sont connectés avec une arête (non orientée) chaque fois qu'ils se croisent (sous forme de polygones). Si nous prenons une solution au problème - qui est une séquence de (disons k ) collections disjointes des polygones - et attribuons une couleur unique à chaque collection de la séquence, alors nous aurons obtenu un k- coloriage du graphique . Il est souhaitable de trouver un petit k .
Ce problème est assez difficile et reste non résolu pour les graphiques arbitraires. Considérez une solution approximative simple à coder. Un algorithme séquentiel devrait faire l'affaire. L'algorithme Welsh-Powell est une solution gourmande basée sur un ordre décroissant des sommets par degré. Traduit dans la langue des polygones d'origine, triez d'abord les polygones dans l'ordre décroissant du nombre d'autres polygones qu'ils chevauchent. En travaillant dans l'ordre, donnez au premier polygone une couleur initiale. À chaque étape successive, essayez de colorer le polygone suivant avec une couleur existante: c'est-à-dire, choisissez une couleur qui n'est pasdéjà utilisé par l'un des voisins de ce polygone. (Il existe plusieurs façons de choisir parmi les couleurs disponibles; essayez soit celle qui a été la moins utilisée, soit choisissez-en une au hasard.) Si le polygone suivant ne peut pas être coloré avec une couleur existante, créez une nouvelle couleur et coloriez-la avec celle-ci.
Une fois que vous avez réalisé une coloration avec un petit nombre de couleurs, effectuez zonalstats couleur par couleur: par construction, vous êtes assuré qu'il n'y a pas deux polygones d'une couleur donnée qui se chevauchent.
Voici un exemple de code dans R
. (Le code Python ne serait pas très différent.) Premièrement, nous décrivons les chevauchements entre les sept polygones montrés.
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)
Autrement dit, les polygones 1 et 2 se chevauchent, tout comme les polygones 2 et 3, 3 et 4, ..., 1 et 7.
Triez les sommets par degré décroissant:
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 algorithme de coloration séquentielle (brut) utilise la première couleur disponible qui n'est pas déjà utilisée par un polygone se chevauchant:
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
}
Initialisez les structures de données ( colors
et color.next
) et appliquez l'algorithme:
colors <- rep(0, length(vertices))
color.next <- 1
temp <- sapply(v, color)
Divisez les polygones en groupes selon la couleur:
split(vertices, colors)
La sortie de cet exemple utilise quatre couleurs:
$`1`
[1] 2 4
$`2`
[1] 3 6 7
$`3`
[1] 5
$`4`
[1] 1
Il a divisé les polygones en quatre groupes qui ne se chevauchent pas. Dans ce cas, la solution n'est pas optimale ({{3,6,5}, {2,4}, {1,7}} est un tricolore pour ce graphique). En général, la solution qu'il obtient ne devrait cependant pas être trop mauvaise.