Estoy buscando una buena manera de aplanar (dividir) una lista de rangos numéricos potencialmente superpuestos. El problema es muy similar al de esta pregunta: la forma más rápida de dividir rangos de fechas superpuestos , y muchos otros.
Sin embargo, los rangos no son solo enteros, y estoy buscando un algoritmo decente que se pueda implementar fácilmente en Javascript o Python, etc.
Datos de ejemplo:
Solución de ejemplo:
Disculpas si esto es un duplicado, pero aún no he encontrado una solución.
javascript
algorithms
python
Jollywatt
fuente
fuente
Respuestas:
Camina de izquierda a derecha, usando una pila para hacer un seguimiento del color en el que estás. En lugar de un mapa discreto, use los 10 números en su conjunto de datos como puntos de quiebre.
Comenzando con una pila vacía y estableciendo
start
a 0, repite hasta llegar al final:start
, y empújelo junto con todos los colores de menor rango en la pila. En su lista aplanada, marque el comienzo de ese color.start
, y encuentre el final del color actualstart
al final de este color, sáquelo de la pila y verifique el siguiente color mejor clasificadostart
está dentro del rango del siguiente color, agregue este color a la lista aplanada, comenzando enstart
.Este es un repaso mental dados sus datos de ejemplo:
fuente
Esta solución parece la más simple. (O al menos, el más fácil de entender)
Todo lo que se necesita es una función para restar dos rangos. En otras palabras, algo que dará esto:
Lo cual es bastante simple. Luego, puede simplemente recorrer cada uno de los rangos, comenzando por el más bajo, y para cada uno, restar de él todos los rangos por encima, a su vez. Y ahí lo tienes.
Aquí hay una implementación del sustractor de rango en Python:
Usando esta función, el resto se puede hacer así: (Un 'span' significa un rango, ya que 'range' es una palabra clave de Python)
Esto da
[['red', [12.5, 13.8]], ['blue', [0.0, 2.0]], ['green', [2.0, 3.5]], ['green', [10.0, 12.0]], ['yellow', [3.5, 6.7]], ['orange', [6.7, 10.0]]]
, que es correcto.fuente
Si los datos realmente son similares en alcance a sus datos de muestra, podría crear un mapa como este:
Luego simplemente recorra este mapa para generar los rangos
Para funcionar, los valores deben estar en un rango relativamente pequeño como en los datos de muestra.
Editar: para trabajar con flotadores verdaderos, use el mapa para generar un mapeo de alto nivel y luego consulte los datos originales para crear los límites.
fuente
Aquí hay una solución relativamente sencilla en Scala. No debería ser demasiado difícil portar a otro idioma.
apply
toma unoSet
de todos los rangos que ya se han aplicado, encuentra las superposiciones, luego devuelve un nuevo conjunto menos las superposiciones y más el nuevo rango y los rangos recién divididos.foldLeft
Llama repetidamenteapply
con cada rango de entrada.fuente
Simplemente mantenga un conjunto de rangos ordenados por inicio. Añadir rango que cubre todo (-oo .. + oo). Para agregar un rango r:
fuente