Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Reporte DV
Reporte DV
Definición formal
Construcción de la región de Voronói de un sitio debido a la intersección de semiplanos.
Aplicaciones
Esta estructura sirve para diferenciar el espacio en regiones puede aplicarse al futbol, al
diagnostico de tumores o para evitar las colisiones de barcos en la costa.
Por ejemplo, en el futbol.
Si pensamos en los jugadores sobre el terreno de juego como puntos sobre un plano,
podemos asignarle a cada uno de ellos su región de Voronoi que estará formada por los
puntos del terreno de juego que están mas cerca de cada jugador que del resto.
Evidentemente, como los jugadores no están quietos, en general, este diagrama ira
modificándose con el tiempo, pero nos puede decir, en cada instante, que equipo esta mejor
posicionado en el campo.
Otro tipo de aplicaciones que igual no se nos ocurren en primera instancia tiene que ver
con las fronteras de las regiones. Imaginen que en lugar de querer encontrar la
farmacia más cercana a ustedes quieren cruzar la ciudad pasando lo más lejos posible
de cualquier farmacia. Igual no lo ven con farmacias, pero pueden pensar en pastelerías
y/o heladerías si están en eso que llaman la operación bikini. En ese caso, la ruta a
seguir nos la dan las líneas de las fronteras del diagrama de Voronoi. Caminando sobre
dichas líneas estaremos siempre lo más alejados posible de las dos pastelerías que
comparten esa línea en su frontera de Voronoi. Esto se utiliza para, por ejemplo, evitar
colisiones de barcos al atravesar zonas escarpadas de la costa.
Diagrama de voronoi en R
Python
import seaborn as sns
from random import randint
from PIL import Image, ImageColor
n = 40
k = 12
semillas = []
for s in range(k):
while True:
x = randint(0, n - 1)
y = randint(0, n - 1)
if (x, y) not in semillas:
semillas.append((x, y))
break
from math import sqrt
def celda(pos):
y = pos // n
x = pos % n
if pos in semillas:
return semillas.index(pos)
cercano = None
menor = n * sqrt(2)
for i in range(k):
(xs, ys) = semillas[i]
dx = x - xs
dy = y - ys
dist = sqrt(dx**2 + dy**2)
if dist < menor:
cercano = i
menor = dist
return cercano
import multiprocessing
if __name__ == "__main__":
celdas = None
with multiprocessing.Pool() as pool:
celdas = pool.map(celda, range(n * n))
zona = Image.new('RGB', (n, n))
p = zona.load()
c = sns.color_palette("Set3", k).as_hex()
for i in range(n * n):
s = celdas.pop(0)
p[i % n, i // n] = ImageColor.getrgb(c[s])
visual = zona.resize((10 * n, 10 * n))
visual.show()
visual.save("p4pc.png")
R
n <- 40
zona <- matrix(rep(0, n * n), nrow = n, ncol = n)
k <- 12
x <- rep(0, k) # ocupamos almacenar las coordenadas x de las semillas
y <- rep(0, k) # igual como las coordenadas y de las semillas
for (semilla in 1:k) {
while (TRUE) { # hasta que hallamos una posicion vacia para la
semilla
fila <- sample(1:n, 1)
columna <- sample(1:n, 1)
if (zona[fila, columna] == 0) {
zona[fila, columna] = semilla
x[semilla] <- columna
y[semilla] <- fila
break
}
}
}
celda <- function(pos) {
fila <- floor((pos - 1) / n) + 1
columna <- ((pos - 1) %% n) + 1
if (zona[fila, columna] > 0) { # es una semilla
return(zona[fila, columna])
} else {
cercano <- NULL # sin valor por el momento
menor <- n * sqrt(2) # mayor posible para comenzar la busqueda
for (semilla in 1:k) {
dx <- columna - x[semilla]
dy <- fila - y[semilla]
dist <- sqrt(dx^2 + dy^2)
if (dist < menor) {
cercano <- semilla
menor <- dist
}
}
return(cercano)
}
}
suppressMessages(library(doParallel))
registerDoParallel(makeCluster(detectCores() - 1))
celdas <- foreach(p = 1:(n * n), .combine=c) %dopar% celda(p)
stopImplicitCluster()
voronoi <- matrix(celdas, nrow = n, ncol = n, byrow=TRUE)
rotate <- function(x) t(apply(x, 2, rev))
png("p4s.png")
par(mar = c(0,0,0,0))
image(rotate(zona), col=rainbow(k+1), xaxt='n', yaxt='n')
graphics.off()
png("p4c.png")
par(mar = c(0,0,0,0))
image(rotate(voronoi), col=rainbow(k+1), xaxt='n', yaxt='n')
graphics.off()
Diagramas de Voronoi
Python R