Este es un problema de coloración gráfica .
Recuerde que un color de gráfico es una asignación de un color a los vértices de un gráfico de tal manera que no haya dos vértices que compartan un borde también tendrán el mismo color. Específicamente, los vértices (abstractos) del gráfico son los polígonos. Dos vértices están conectados con un borde (no dirigido) cada vez que se cruzan (como polígonos). Si tomamos alguna solución al problema, que es una secuencia de (digamos k ) colecciones disjuntas de los polígonos, y asignamos un color único a cada colección en la secuencia, entonces habremos obtenido una k- coloración del gráfico . Es deseable encontrar una pequeña k .
Este problema es bastante difícil y sigue sin resolverse para gráficos arbitrarios. Considere una solución aproximada que sea simple de codificar. Un algoritmo secuencial debe hacer. El algoritmo galés-Powell es una solución codiciosa basada en un orden descendente de los vértices por grado. Traducido al lenguaje de los polígonos originales, primero ordene los polígonos en orden descendente del número de otros polígonos que se superponen. Trabajando en orden, déle al primer polígono un color inicial. En cada paso sucesivo, intente colorear el siguiente polígono con un color existente: es decir, elija un color que no seaya utilizado por cualquiera de los vecinos de ese polígono. (Hay muchas formas de elegir entre los colores disponibles; pruebe el que menos se haya utilizado o elija uno al azar). Si el próximo polígono no se puede colorear con un color existente, cree un nuevo color y asígnelo.
Una vez que haya logrado una coloración con una pequeña cantidad de colores, realice las zonas zonal color por color: por construcción, se garantiza que no se superponen dos polígonos de un color determinado.
Aquí hay un código de muestra R
. (El código de Python no sería muy diferente). Primero, describimos las superposiciones entre los siete polígonos mostrados.
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)
Es decir, los polígonos 1 y 2 se superponen, y también lo hacen los polígonos 2 y 3, 3 y 4, ..., 1 y 7.
Ordenar los vértices por grado descendente:
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 de coloración secuencial (en bruto) utiliza el primer color disponible que no haya sido utilizado por ningún polígono superpuesto:
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
}
Inicialice las estructuras de datos ( colors
y color.next
) y aplique el algoritmo:
colors <- rep(0, length(vertices))
color.next <- 1
temp <- sapply(v, color)
Divide los polígonos en grupos según el color:
split(vertices, colors)
La salida en este ejemplo usa cuatro colores:
$`1`
[1] 2 4
$`2`
[1] 3 6 7
$`3`
[1] 5
$`4`
[1] 1
Ha dividido los polígonos en cuatro grupos no superpuestos. En este caso, la solución no es óptima ({{3,6,5}, {2,4}, {1,7}} son tres colores para este gráfico). Sin embargo, en general, la solución que obtiene no debería ser tan mala.