Dies ist ein Problem beim Färben von Grafiken .
Denken Sie daran, dass eine Diagrammfärbung eine Zuordnung einer Farbe zu den Scheitelpunkten eines Diagramms ist, sodass keine zwei Scheitelpunkte, die eine Kante gemeinsam haben, dieselbe Farbe haben. Insbesondere sind die (abstrakten) Eckpunkte des Graphen die Polygone. Zwei Eckpunkte werden immer dann mit einer (ungerichteten) Kante verbunden, wenn sie sich schneiden (als Polygone). Wenn wir eine Lösung für das Problem finden - das eine Folge von (sagen wir k ) disjunkten Sammlungen der Polygone ist - und jeder Sammlung in der Folge eine eindeutige Farbe zuweisen, haben wir eine k- Färbung des Graphen erhalten . Es ist wünschenswert, ein kleines k zu finden .
Dieses Problem ist ziemlich schwierig und bleibt für beliebige Graphen ungelöst. Stellen Sie sich eine ungefähre Lösung vor, die einfach zu codieren ist. Ein sequentieller Algorithmus sollte reichen. Der Welsh-Powell-Algorithmus ist eine gierige Lösung, die auf einer absteigenden Reihenfolge der Eckpunkte nach Grad basiert. Sortiert in die Sprache der ursprünglichen Polygone, sortieren Sie die Polygone zunächst in absteigender Reihenfolge nach der Anzahl der anderen Polygone, die sie überlappen. Geben Sie dem ersten Polygon eine Anfangsfarbe. Versuchen Sie in jedem Schritt, das nächste Polygon mit einer vorhandenen Farbe zu färben. Wählen Sie also eine Farbe aus, die nicht vorhanden istbereits von einem der Nachbarn dieses Polygons verwendet. (Es gibt viele Möglichkeiten, zwischen den verfügbaren Farben zu wählen. Probieren Sie entweder die am wenigsten verwendete oder eine zufällig ausgewählte Farbe aus.) Wenn das nächste Polygon nicht mit einer vorhandenen Farbe gefärbt werden kann, erstellen Sie eine neue Farbe und färben Sie sie damit.
Wenn Sie eine Färbung mit einer kleinen Anzahl von Farben erreicht haben, führen Sie Zonenstatistiken Farbe für Farbe durch: Durch die Konstruktion wird garantiert, dass sich keine zwei Polygone einer bestimmten Farbe überlappen.
Hier ist Beispielcode in R
. (Python-Code wäre nicht viel anders.) Zunächst beschreiben wir Überlappungen zwischen den sieben gezeigten Polygonen.
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)
Das heißt, die Polygone 1 und 2 überlappen sich, ebenso wie die Polygone 2 und 3, 3 und 4, ..., 1 und 7.
Sortieren Sie die Eckpunkte nach absteigendem Grad:
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))]
Ein (roher) sequentieller Farbalgorithmus verwendet die früheste verfügbare Farbe, die noch nicht von einem überlappenden Polygon verwendet wird:
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
}
Initialisieren Sie die Datenstrukturen ( colors
und color.next
) und wenden Sie den Algorithmus an:
colors <- rep(0, length(vertices))
color.next <- 1
temp <- sapply(v, color)
Teilen Sie die Polygone nach Farben in Gruppen auf:
split(vertices, colors)
Die Ausgabe in diesem Beispiel verwendet vier Farben:
$`1`
[1] 2 4
$`2`
[1] 3 6 7
$`3`
[1] 5
$`4`
[1] 1
Es hat die Polygone in vier nicht überlappende Gruppen unterteilt. In diesem Fall ist die Lösung nicht optimal ({{3,6,5}, {2,4}, {1,7}} ist für dieses Diagramm dreifarbig). Im Allgemeinen sollte die Lösung jedoch nicht schlecht sein.