rechercher le chevauchement des intervalles dans la liste des intervalles?

Disons que [a, b] représente l’intervalle sur la droite réelle de a à b, a <b inclus (c.-à-d. [A, b] = ensemble de tous les x tels que a <= x <= b). En outre, disons que [a, b] et [c, d] se chevauchent s'ils partagent un x tel que x soit à la fois dans [a, b] et [c, d].

Étant donné une liste d’intervalles, ([x1, y1], [x2, y2], …), quel est le moyen le plus efficace de trouver tous les intervalles qui chevauchent [x, y]?

De toute évidence, je peux essayer chacun et l’obtenir dans O (n). Mais je me demandais si je pouvais sortinger la liste d’intervalles de manière intelligente, je pourrais trouver / un / superposition d’éléments dans O (log N) via une recherche binary, puis «regarder autour» de cette position dans la liste pour trouver tous les intervalles qui se chevauchent. Cependant, comment est-ce que je sortinge des intervalles tels qu’une telle stratégie fonctionnerait?

Notez qu’il peut y avoir des chevauchements entre les éléments des éléments de la liste, ce qui rend cela difficile.

Je l’ai essayé en sortingant les intervalles par leur extrémité gauche, leur extrémité droite, leur milieu, mais aucun ne semble conduire à une recherche exhaustive.

Aidez-moi?

[a, b] recouvre [x, y] ssi b> x et a

Pour être complet, j’aimerais append qu’il existe une structure de données bien connue pour ce type de problème, connue (surprise, surprise) en tant qu’arborescence d’ intervalles . Il s’agit essentiellement d’un arbre équilibré augmenté (rouge-noir, AVL, votre choix) qui stocke les intervalles sortingés par leur extrémité gauche (basse). L’augmentation est que chaque noeud stocke le plus grand noeud final droit (haut) dans son sous-arbre. Cet arbre vous permet de trouver tous les intervalles qui se chevauchent dans le temps O (log n).

C’est décrit dans CLRS 14.3.

Un quadtree est une structure de données souvent utilisée pour améliorer l’efficacité de la détection des collisions en 2 dimensions.

Je pense que vous pourriez trouver une structure 1-D similaire. Cela nécessiterait un pré-calcul mais devrait aboutir à une performance O (log N).

Fondamentalement, vous commencez avec un nœud racine qui couvre tous les intervalles possibles, et lorsque vous ajoutez un nœud à l’arbre, vous décidez s’il tombe à gauche ou à droite du point milieu. S’il traverse le point médian, vous le divisez en deux intervalles (mais enregistrez le parent d’origine) et procédez de manière récursive à partir de là. Vous pouvez définir une limite pour la profondeur de l’arborescence, ce qui peut économiser de la mémoire et améliorer les performances, mais se traduit par une légère complication (vous devez stocker une liste d’intervalles dans vos nœuds).

Ensuite, lors de la vérification d’un intervalle, vous trouvez essentiellement tous les nœuds feuilles qui seraient insérés, vérifiez les intervalles partiels dans ces nœuds pour l’intersection, puis rapportez l’intervalle enregistré comme parent d’origine.

Juste une pensée rapide ‘hors du coude’ pour ainsi dire.

Pourriez-vous les organiser en deux listes, une pour le début des intervalles et l’autre pour la fin des intervalles.

De cette façon, vous pouvez comparer les éléments de la liste de début d’intervalle (disons par recherche binary) pour réduire les candidats en fonction de cela.

Vous pouvez ensuite comparer x aux éléments de la liste de fin d’intervalle.

MODIFIER

Cas: Une fois éteint

Si vous comparez un seul intervalle à la liste d’intervalles dans une situation unique, je ne pense pas que le sorting vous aidera car le sorting idéal est O (n) .

En effectuant une recherche linéaire dans tous les x pour supprimer tous les intervalles impossibles, puis en effectuant une autre recherche linéaire dans les y restants, vous pouvez réduire votre travail total. Bien que ce soit toujours O (n), sans cela, vous effectueriez 2n comparaisons, alors qu’en moyenne, vous ne feriez que (3n-1) / 2 comparaisons de cette façon.

Je pense que c’est le mieux que vous puissiez faire pour une liste non sortingée.

Cas: le pré-sorting ne compte pas

Si vous comparez à plusieurs resockets des intervalles uniques à cette liste d’intervalles et que vous pré-sortingez votre liste, vous pouvez obtenir de meilleurs résultats. Le processus ci-dessus s’applique toujours, mais en effectuant une recherche binary sur la première liste, vous pouvez obtenir O (m log n) par opposition à O (mn), où m est le nombre d’intervalles uniques comparés. Notez que vous avez toujours l’avantage de réduire les comparaisons totales. [2m log n comparé à m (3 (log n) – 1) / 2]

Vous pouvez sortinger par extrémité gauche et extrémité droite en même temps et utiliser les deux listes pour éliminer les valeurs qui ne se chevauchent pas. Si la liste est sortingée par l’extrémité gauche, aucun des intervalles à droite de l’extrémité droite de la plage de test ne peut se chevaucher. Si la liste est sortingée par l’extrémité droite, aucun des intervalles à gauche de l’extrémité gauche de la plage de test ne peut se chevaucher.

Par exemple si les intervalles sont

[1,4], [3,6], [4,5], [2,8], [5,7], [1,2], [2,2.5] 

et vous trouvez le chevauchement avec [3,4] puis le sorting par l’extrémité gauche et la position de marquage de l’extrémité droite du test (avec l’extrémité droite juste supérieure à sa valeur de sorte que 4 soit incluse dans la plage)

 [1,4], [1,2], [2,2.5], [2,8], [3,6], [4,5], *, [5,7] 

vous savez [5,7] ne peut pas se chevaucher, puis sortinger par extrémité droite et marquer la position de l’extrémité gauche du test

 [1,2], [2,2.5], *, [1,4], [4,5], [3,6], [5,7], [2,8] 

vous savez [1,2] et [2,2.5] ne peuvent pas se chevaucher

Je ne suis pas sûr de l’efficacité avec laquelle vous devez effectuer deux sortes de recherches.

Comme vous pouvez le voir dans d’autres réponses, la plupart des algorithmes sont associés à une structure de données spéciale. Par exemple, pour une liste non sortingée d’intervalles, l’entrée O(n) est la meilleure que vous obtiendrez. (Et généralement, il est plus facile de penser en termes de structure de données qui dicte l’algorithme).

Dans ce cas, votre question n’est pas complète:

  • Avez-vous la liste entière ou c’est vous qui la crée réellement?

  • Devez-vous effectuer une telle recherche ou plusieurs d’entre eux?

  • Avez-vous des estimations pour les opérations qu’il devrait supporter et leurs fréquences?

Par exemple, si vous devez effectuer une seule recherche de ce type, il n’est pas utile de sortinger la liste auparavant. Si beaucoup, alors le sorting plus cher ou la génération d’un “quadtree 1D” serait amorti.

Cependant, il serait difficile de le résoudre, car un simple quadtree (si je comprends bien) est capable de détecter la collistion, mais il est impossible de créer la liste de tous les segments qui se chevauchent avec votre entrée.

Une implémentation simple serait une liste ordonnée (par coordonate) dans laquelle vous insérez toutes les extrémités de segment avec le début / la fin du drapeau et avec le numéro de segment. De cette façon, en l’analysant (toujours O (n), mais je doute que vous puissiez le faire plus rapidement si vous avez également besoin de la liste de tous les segments qui se chevauchent) et de garder la trace de tous les segments ouverts qui ne sont pas fermés. points de contrôle “.