¿Cómo resuelven los árboles de segmentos el problema de apuñalamiento (todos los intervalos que contienen un punto dado)?

  # [1] https://www.cs.umd.edu/class/spring2008/cmsc420/L22.IntervalTrees.pdf
 # [2] Árbol de intervalos - Wikipedia
 # [3] http://www.cs.nthu.edu.tw/~wkhon/algo08-tutorials/tutorial-stabbing.pdf

 # Según [1], el árbol de intervalo es una especie de árbol de segmento degradado (sin inclinación).
 # Según [3], el árbol de segmentos es una especie de árbol segmentado, almacena segmentos de un intervalo en un árbol.
 # Aquí implementamos el problema de consulta de apilamiento utilizando la estructura de datos "Árbol aumentado" mencionado en [2] y [3].

 de functools import total_ordering

 @total_ordering
 intervalo de clases:
     def __init __ (self, start, end):
         self.start = start
         self.end = end

     def __eq __ (self, otro):
         return self.start == other.start y self.end == other.end

     def __gt __ (self, otro):
         return (self.start, self.end)> (other.start, other.end)

     def __str __ (self):
         return "[% d ..% d]"% (self.start, self.end)

     def contiene (self, pos):
         return self.start <= pos  itv.end o self.end  iend: return
     si istart == iend:
         return IntervalTreeNode (intervalos [istart], intervalos [istart] .end)

     imid = (istart + iend) // 2
     max_ = intervalos [imid] .end

     left = build (intervalos, istart, imid-1)
     si se deja:
         max_ = max (max_, left.max_)

     right = build (intervalos, imid + 1, iend)
     si es correcto:
         max_ = max (max_, right.max_)

     nodo = IntervalTreeNode (intervalos [imid], max_)
     node.left, node.right = left, right
     nodo de retorno

 def insert_interval (root, itv):
     si root.max_ <itv.end:
         root.max_ = itv.end

     si itv.start  = root.interval.start:
         si root.right:
             insert_interval (root.right, itv)
         más:
             root.right = IntervalTreeNode (itv, itv.end)

 def query_point_overlap (resultado, raíz, punto):
     si no es root o point> root.max_:
         regreso

     si root.interval.contains (punto):
         result.append (root.interval)

     query_point_overlap (resultado, root.left, punto)

     if point> root.interval.start:
         query_point_overlap (resultado, root.right, punto)

 def query_interval_overlap (resultado, raíz, itv):
     si no es root o itv.start> root.max_:
         regreso

     si root.interval.overlap (itv):
         result.append (root.interval)

     query_interval_overlap (resultado, root.left, itv)

     si itv.end> root.interval.start:
         query_interval_overlap (resultado, root.right, itv)


 if __name__ == "__main__":
     de semilla de importación aleatoria, randint
     seed (2016) # entero determinista aleatorio.
     intervalos = []
     para i en rango (20):
         p1 = randint (0, 100)
         p2 = randint (0, 100)
         intervalos.append (Intervalo (min (p1, p2), max (p1, p2)))

     intervalos.sort ()
     print ("," .join ([str (itv) para itv en intervalos]))

     root = build (intervalos, 0, len (intervalos) -1)

     punto = 50
     resultado = []
     query_point_overlap (resultado, raíz, punto)
     print ("resultado de la consulta para% 2d:"% point "," .join ([str (itv) para itv en ordenado (resultado)]))
     print ("resultado esperado:", "," .join ([str (itv) para itv en intervalos si itv.contains (punto)]))

     intervalo = intervalo (50, 51)
     resultado = []
     query_interval_overlap (resultado, raíz, intervalo)
     print ("resultado de la consulta para% 2d:"% point "," .join ([str (itv) para itv en ordenado (resultado)]))
     print ("resultado esperado:", "," .join ([str (itv) para itv en intervalos si itv.overlap (intervalo)]))

     insert_interval (raíz, intervalo)

Esta página en nthu.edu.tw es más precisa 🙂

Lee el contenido de esta página. Tiene una sección sobre consulta de apuñalamiento
Árbol de segmentos – PEGWiki

More Interesting

¿Dónde puedo encontrar a alguien dispuesto a enseñarme estructura de datos y algoritmos de forma gratuita o a un costo muy barato?

Cómo resolver ADAGAME en SPOJ

¿Cuál es la lógica detrás del algoritmo de escaneo de Graham para casco convexo?

Es un método de retroceso para imprimir permutaciones de cadena. No entiendo de qué manera se produce el flujo de control, como después de encontrar el intercambio, el intercambio se llama luego permutar y luego nuevamente. ¿Esto no se me viene a la cabeza?

¿Cuál es el enfoque algorítmico para este problema de hackerrank?

¿Cómo encontraron los pilotos el camino más corto, cuando volaron a larga distancia en 1950?

Soy completamente nuevo en algoritmos. ¿Cuál es el mejor libro / curso / método para realmente entrar en ellos?

¿Qué es un algoritmo eficiente para el agrupamiento k-means donde k es 2 y la dimensión es una, con o sin pesos?

Cómo aprender estructuras de datos de manera efectiva

Cómo ejecutar cruces en algoritmos genéticos con cromosomas codificados por gráficos

Trabajo muy duro para estudiar 13 horas al día durante más de 7 meses, pero todavía no puedo mejorar mi estructura de datos y habilidades de algoritmos, ¿qué debo hacer?

Quicksort: ¿Cuál es el algoritmo de ordenación rápida?

Cómo hacer que los algoritmos sean eficientes

¿Cuáles son los trabajos orientados a la lógica pura para los programadores?

¿Es cierto que no debería importarme tanto aprender lenguajes de programación sino construir una gran base de estructuras de datos y algoritmos?