2010-06-02 14 views
11

Tengo un conjunto de puntos que están dentro del rectángulo. Me gustaría dividir los rectángulos en subrectangles basados ​​en la densidad de puntos (dando una cantidad de subrectangles o densidad deseada, lo que sea más fácil).Algoritmo de partición de espacio

El particionamiento no tiene que ser exacto (casi cualquier aproximación mejor que la grilla normal), pero el algoritmo tiene que hacer frente a la gran cantidad de puntos - aprox. 200 millones. Sin embargo, el número deseado de subrectangles es sustancialmente más bajo (alrededor de 1000).

¿Alguien sabe algún algoritmo que pueda ayudarme con esta tarea en particular?

+1

¿Quieres (aproximadamente) el mismo número de puntos en cada subrectángulo? Creo que sí, pero no está del todo claro. –

+0

Sí, quiero el mismo número de puntos en cada subrect. –

+5

Si no impone restricciones en la forma de los rectángulos, el problema es unidimensional, y todo lo que tiene que hacer es cortar un segmento con la misma cantidad de puntos (coordenada x de los puntos). Me parece que estás olvidando alguna restricción de "topología" –

Respuesta

2

sólo para entender el problema. El siguiente es crudo y un mal resultado, pero quiero saber si el resultado es lo que quiere>

Asunción> Número de rectángulos es aún
Asunción> Punto de distribución es marcadamente 2D (no hay gran acumulación en una sola línea)

Procedimiento>
Bisecar n/2 veces en cualquiera de los ejes, de bucle de un extremo al otro de cada recuento rectángulo determinado previamente "pasan" puntos y almacenar el número de puntos aprobadas en cada iteración. Una vez contados, biseque el rectángulo seleccionando por los puntos contados en cada ciclo.

¿Eso es lo que quieres lograr?

+0

Sí, exactamente. Eso sería perfecto. Estaba pensando en crear inicialmente una matriz (1000x1000 más o menos) y almacenar el número de puntos en cada celda. Entonces puedo usar tu algoritmo de bisección. –

2
+0

-1: R-tree no es un algoritmo, es una estructura de datos, y usted no propone un algoritmo para poblar el R-tree. –

+0

@HPM, tal vez si mira la página que identifiqué y busca el algoritmo del encabezado, estaría satisfecho. –

1

Creo que comenzaría con lo siguiente, que está cerca de lo que @belisarius ya propuso. Si tiene requisitos adicionales, como preferir rectángulos "casi cuadrados" a "largos y delgados", deberá modificar este enfoque ingenuo. Asumiré, en aras de la simplicidad, que los puntos están distribuidos aproximadamente de forma aleatoria.

  1. Divida su rectángulo inicial en 2 con una línea paralela al lado corto del rectángulo y corriendo exactamente a través del punto medio.
  2. Cuenta el número de puntos en ambos medios rectángulos. Si son iguales (suficientes), vaya al paso 4. De lo contrario, vaya al paso 3.
  3. En función de la distribución de puntos entre los medios rectángulos, mueva la línea para equilibrar las cosas nuevamente. Entonces, si, por casualidad, el primer corte divide los puntos 1/3, 2/3, mueve la línea a la mitad de la mitad pesada del rectángulo. Vaya al paso 2. (Tenga cuidado de no quedar atrapado aquí, moviendo la línea en pasos decrecientes primero en una dirección, luego en la otra.)
  4. Ahora, pase cada uno de los semicregulos en una llamada recursiva a esta función, en el paso 1.

Espero que describa la propuesta lo suficientemente bien. Tiene limitaciones: producirá un número de rectángulos igual a una potencia de 2, así que ajústelo si eso no es lo suficientemente bueno. Lo he expresado recursivamente, pero es ideal para la paralelización. Cada división crea dos tareas, cada una de las cuales divide un rectángulo y crea dos tareas más.

Si no te gusta ese enfoque, quizás podrías comenzar con una cuadrícula regular con algunos múltiplos (10 - 100 quizás) del número de rectángulos que deseas. Cuenta el número de puntos en cada uno de estos pequeños rectángulos. Luego comience a pegar los pequeños rectángulos hasta que el rectángulo menos pequeño contenga (aproximadamente) el número correcto de puntos.O bien, si satisface sus requisitos lo suficientemente bien, puede usar esto como un método de discretización e integrarlo con mi primer enfoque, pero solo coloque las líneas de corte a lo largo de los límites de los pequeños rectángulos. Esto probablemente sea mucho más rápido ya que solo tendrías que contar los puntos en cada pequeño rectángulo una vez.

No he pensado realmente en el tiempo de ejecución de ninguno de estos; Tengo una preferencia por el enfoque anterior porque hago una buena cantidad de programación paralela y tengo montones de procesadores.

+0

Pensar de nuevo y resumir ambas respuestas, cortar rectángulos delgados es equivalente a un problema dimensional. Por lo tanto, si tiene N puntos y rectángulos r, solo tenga en cuenta la coordenada x de los puntos y sume N/r puntos en cada partición –

0

Buena pregunta.

Creo que el área que necesita investigar es la "geometría computacional" y el problema de "partición k". Hay un enlace que puede ayudarlo a comenzar here

Puede encontrar que el problema en sí es NP-hard, lo que significa que un buen algoritmo de aproximación es lo mejor que va a obtener.

+0

El póster ha pedido la equipartición de puntos, sin minimizar ni maximizar las interacciones. Este último puede ser NP-hard (por ejemplo, gráfico máximo de corte); el primero es 'O (n log n)'. –

2

Está buscando un árbol de partición de árbol binario o binario estándar, creo. (Puede buscarlo en Wikipedia.)

Dado que tiene muchos puntos, es posible que desee dividir solo aproximadamente los primeros niveles. En este caso, debe tomar una muestra aleatoria de sus puntos de 200M - tal vez 200k de ellos - y dividir el conjunto de datos completo en el punto medio de la submuestra (a lo largo de cualquier eje que sea más largo). Si realmente elige los puntos al azar, la probabilidad de que pierda un gran grupo de puntos que deben subdividirse será aproximadamente cero.

Ahora tiene dos problemas de aproximadamente 100M puntos cada uno. Divide cada uno a lo largo del eje más largo. Repita hasta que deje de tomar submuestras y se divida a lo largo de todo el conjunto de datos. Después de diez iteraciones de amplitud, habrá terminado.

Si tiene un problema diferente, debe proporcionar marcas a lo largo de los ejes X e Y y completar una cuadrícula lo mejor que pueda, en lugar de tener la descomposición irregular de un árbol de KD, tome su submuestra de puntos y encuentra los percentiles 0/32, 1/32, ..., 32/32 a lo largo de cada eje. Dibuje sus líneas de cuadrícula allí, luego llene la cuadrícula resultante de 1024 elementos con sus puntos.

+0

Tal vez me esté faltando el punto de los kd, pero no parecen crear rectángulos con puntos DENTRO de los rectángulos como dice la pregunta. El segundo comentario dice que está buscando la misma cantidad de puntos dentro de un rectángulo. La referencia contenía muchas otras referencias que pensé que podrían ser útiles. – Grembo

+0

@Grembo: es un pequeño detalle de implementación para pasar a hacer que las líneas sean _entre_puntos en lugar de _en_ ​​puntos. –

+0

KD-Tree fue de hecho mi primer reflejo también, me resistí al principio debido al gran conjunto, pero el enfoque de muestreo alivia el problema. –

0

Eso se ve como Cluster analysis.

+0

En general, tiene razón, es un problema de análisis de conglomerados. Pero es un problema bastante inusual, así que no creo que sean útiles los métodos listos para usar de la caja de herramientas de análisis de clusters. Solo me interesan los rectángulos, no los clusters, tengo muchos objetos y no me importa mucho la precisión. –

+0

Utilice la distancia de Manhattan. – ony

0

¿Funcionaría QuadTree?

Un quadtree es una estructura de datos en árbol en la que cada nodo interno tiene exactamente cuatro hijos. Los cuatristrenos se usan con mayor frecuencia para dividir un espacio bidimensional subdividiéndolo recursivamente en cuatro cuadrantes o regiones. Las regiones pueden ser cuadradas o rectangulares, o pueden tener formas arbitrarias. Esta estructura de datos fue nombrada quadtree por Raphael Finkel y J.L. Bentley en 1974. Una partición similar también se conoce como Q-tree. Todas las formas de Quadtrees comparten algunas características comunes:

  • Descomponen espacio en células adaptables
  • Cada célula (o de cubo) tiene una capacidad máxima.Cuando se alcanza la capacidad máxima, el cubo se divide
  • El árbol de directorios sigue la descomposición espacial de la Quadtree
Cuestiones relacionadas