Accueil🇫🇷Chercher

Algorithme de Bentley-Ottmann

En géométrie algorithmique, l'algorithme de Bentley-Ottmann est un algorithme de sweep line pour trouver les intersections d'un ensemble de segments (en). C'est une généralisation de l'algorithme de Shamos et Hoey[1] qui vérifie si un ensemble de segments possède des intersections ou non. Pour n segments avec k intersections, la complexité en temps de l'algorithme de Bentley-Ottmann est O((n + k) log n). Dans le cas où k = o(n2 / log n), c'est une amélioration de l'algorithme naïf qui teste chaque pair de segments en temps O(n2).

L'algorithme a été développé à l'origine par Jon Bentley et Thomas Ottmann (1979). Il est décrit plus en détail dans les articles de Preparata et Shamos (1985), O'Rourke (1998), et de Berg et al. (2000). Bien que des algorithmes asymptotiquement plus rapides sont connus, l'algorithme de Bentley-Ottmann reste un choix pratique en raison de sa simplicité et de faibles besoins en mémoire.

Stratégie générale

L'idĂ©e principale de Bentley et Ottmann est d'utiliser une approche sweep line, dans laquelle une ligne verticale L se dĂ©place de gauche Ă  droite dans le plan, intersectant les segments en entrĂ©e au fur et Ă  mesure de son dĂ©placement[2]. L'algorithme est dĂ©crit sans perte de gĂ©nĂ©ralitĂ© sous les conditions suivantes :

  1. Aucune des deux extrĂ©mitĂ©s du segment ou des intersections n'ont la mĂŞme abscisse ;
  2. Aucune extrémité de segment n'est confondue avec l'extrémité d'un autre segment ;
  3. Il n'y a pas plus de deux segments qui se coupent en un mĂŞme point.

Dans un tel cas, la ligne L coupera toujours les segments en entrĂ©e en un ensemble de points dont l'ordonnancement vertical consiste en un ensemble fini d'Ă©vĂ©nements discrets. Ainsi, le mouvement continu de L peut ĂŞtre dĂ©composĂ© en une suite finie d'Ă©tapes, et simulĂ© par un algorithme qui s'exĂ©cute en un temps fini.

Deux types d'Ă©vĂ©nements peuvent se produire au cours de cette simulation. Lorsque L balaie l'extrĂ©mitĂ© d'un segment s, l'intersection de L avec s est ajoutĂ©e ou supprimĂ©e de l'ensemble — ordonnĂ© verticalement — de points d'intersection. Ces Ă©vĂ©nements sont faciles Ă  prĂ©voir car les extrĂ©mitĂ©s de segments sont connus dès le dĂ©but de l'algorithme. Le reste des Ă©vĂ©nements se produit lorsque L balaie un croisement entre deux segments s et t. Ces Ă©vĂ©nements peuvent Ă©galement ĂŞtre prĂ©dits Ă  partir du fait que, juste avant l'Ă©vĂ©nement, les points d'intersection de L avec s et t sont adjacents dans l'ordre vertical des points d'intersection.

L'algorithme de Bentley-maintient lui-même des structures de données représentant les points d'intersection (ordonnés verticalement) de la ligne de balayage avec les segments, et une collection d'événements futurs potentiels formés par des paires adjacentes de points d'intersection. Il traite chaque événement tour à tour en mettant à jour ses structures de données pour stocker l'ensemble des intersections.

Structures de données

Afin de gĂ©rer efficacement les points d'intersection de la ligne de balayage L avec les segments et la sĂ©quence des Ă©vĂ©nements Ă  venir, l'algorithme de Bentley-Ottmann utilise deux structures de donnĂ©es :

  • Un arbre binaire de recherche, contenant l'ensemble des segments qui intersectent L, triĂ©s selon l'ordonnĂ©e des points d'intersection. Ces points ne sont pas reprĂ©sentĂ©s explicitement dans l'arbre binaire. L'algorithme de Bentley-Ottmann insère un nouveau segment s dans cette structure de donnĂ©es lorsque la ligne L atteint l'extrĂ©mitĂ© gauche p de ce segment. La position correcte de s dans l'arbre binaire de recherche peut ĂŞtre dĂ©terminĂ© par une recherche dichotomique : chaque Ă©tape de la dichotomie vĂ©rifie si p est au-dessus ou en dessous d'un autre segment intersectĂ© par L. Ainsi, l'insertion peut ĂŞtre effectuĂ©e en temps logarithmique. L'algorithme de Bentley-Ottmann va Ă©galement supprimer des segments de l'arbre binaire de recherche et chercher des segments voisins d'autres segments (immĂ©diatement au-dessus ou en dessous). Ces opĂ©rations peuvent ĂŞtre effectuĂ©es en utilisant uniquement la structure de l'arbre, sans rĂ©fĂ©rence Ă  la gĂ©omĂ©trie sous-jacente des segments.
  • Une file de prioritĂ© (dite « file d'Ă©vĂ©nements »), utilisĂ©e pour stocker une sĂ©quence d'Ă©vĂ©nements futurs potentiels dans l'algorithme. Chaque Ă©vĂ©nement est associĂ© Ă  un point p dans le plan : soit une extrĂ©mitĂ©, soit une intersection. L'Ă©vĂ©nement se produit lorsque la ligne L croise p. Ainsi, les Ă©vĂ©nements peuvent ĂŞtre ordonnĂ©s par les abscisses de leurs points associĂ©s. Dans l'algorithme de Bentley-Ottmann, les Ă©vĂ©nements potentiels futurs sont des extrĂ©mitĂ©s de segments qui n'ont pas encore Ă©tĂ© balayĂ©es ou bien des points d'intersection de deux segments qui sont chacun immĂ©diatement au-dessus ou au-dessous de l'autre.

L'algorithme n'a pas besoin de garder explicitement une représentation de la ligne L ou de sa position dans le plan. La position de L est plutôt représentée indirectement : c'est la ligne verticale passant par le point traité le plus récemment dans la file d'événements.

L'arbre binaire de recherche peut ĂŞtre implĂ©mentĂ© comme n'importe quel arbre Ă©quilibrĂ©, Ă  l'exemple d'un arbre rouge-noir. L'essentiel est que les insertions, les suppressions et les recherches soient faits en temps logarithmique. De mĂŞme, la file de prioritĂ© peut ĂŞtre un tas binaire ou n'importe quelle autre structure du file en temps logarithmique. Des structures plus Ă©voluĂ©es comme le tas de Fibonacci ne sont pas nĂ©cessaires.

Algorithme détaillé

L'algorithme de Bentley-Ottmann effectue les Ă©tapes suivantes :

  1. Initialiser une file de prioritĂ© Q d'Ă©vĂ©nements futurs potentiels. Chaque Ă©vĂ©nement est associĂ© Ă  un point du plan et ordonnĂ© selon l'abscisse de ce point. Au dĂ©but de l'algorithme, Q contient un Ă©vĂ©nement pour chaque extrĂ©mitĂ© des segments.
  2. Initialiser un arbre binaire de recherche T des segments qui intersectent la ligne L, triĂ©s selon l'ordonnĂ©e des intersections. Initialement, T est vide.
  3. Tant que Q n'est pas vide, trouver et retirer l'Ă©vĂ©nement de Q associĂ© au point p d'abscisse minimale. DĂ©terminer de quel type d'Ă©vĂ©nement il s'agit afin d'appliquer un des cas suivants :
    • Si p est l'extrĂ©mitĂ© gauche d'un segment s, insĂ©rer s dans T. Trouver les segments r et t qui sont immĂ©diatement en dessous et au-dessus de s dans T (s'ils existent). Si leur intersection forme un Ă©vĂ©nement futur potentiel dans la file d'Ă©vĂ©nements, le supprimer. Si s intersecte r ou t, ajouter les intersections comme des Ă©vĂ©nements futurs potentiels dans la file d'Ă©vĂ©nements.
    • Si p est l'extrĂ©mitĂ© droite d'un segment s, retirez s de T. Trouver les segments r et t qui ont Ă©tĂ© (avant le retrait de s) immĂ©diatement au-dessus et en dessous de lui dans T (si ces segments existent). Si r et t s'intersectent, ajouter ce point d'intersection comme un Ă©vĂ©nement futur potentiel dans la file d'Ă©vĂ©nements.
    • Si p est le point d'intersection de deux segments s et t (avec un s au-dessous de t Ă  gauche du point p), Ă©changer la position de s et t dans T. Trouver les segments r et u (s'ils existent) qui sont immĂ©diatement en dessous et au-dessus de t et s respectivement (après l'Ă©change). Supprimer les Ă©ventuelles intersections rs et tu de la file d'Ă©vĂ©nements. Si r et t s'intersectent ou si s et u s'intersectent, ajouter les intersections correspondantes dans la file d'Ă©vĂ©nements.

Analyse

Il est possible de montrer par rĂ©currence que l'algorithme traite un Ă©vĂ©nement pour chaque extrĂ©mitĂ© de segment ou point d'intersection, ordonnĂ© selon l'abscisse de ce point. En effet, une fois un Ă©vĂ©nement traitĂ©, l'Ă©vĂ©nement suivant (si c'est une intersection) doit ĂŞtre le croisement de deux segments adjacents dans l'ordre des segments reprĂ©sentĂ©s par T. Puisque l'algorithme traite toutes les intersections entre segments adjacents comme de futurs Ă©vĂ©nements potentiels, le prochain Ă©vĂ©nement correct sera forcĂ©ment prĂ©sent dans la file d'Ă©vĂ©nements. En consĂ©quence, il trouve toutes les intersections des segments en entrĂ©e ce qui constitue le problème initial.

L'algorithme de Bentley-Ottmann traite une séquence de 2n + k événements, où n désigne le nombre de segments et k désigne le nombre d'intersections. Chaque cas est traité par un nombre constant d'opérations dans l'arbre binaire de recherche et la file d'événements. Puisque la file d'événements ne contient que des extrémités du segment et les intersections entre les segments adjacents, elle ne contient jamais plus de 3n événements. Ainsi, toutes les opérations se font en temps O(log n) et la durée totale de l'algorithme est O((n + k) log n).

Si les intersections trouvĂ©es par l'algorithme n'ont pas besoin d'ĂŞtre stockĂ©es une fois qu'elles ont Ă©tĂ© trouvĂ©es, l'espace utilisĂ© par l'algorithme Ă  n'importe quel Ă©tape est O(n) : chacun des n segments correspond au plus Ă  un nĹ“ud de l'arbre binaire de recherche T et la file d'Ă©vĂ©nements contient au plus 3n Ă©lĂ©ments. Cette complexitĂ© spatiale est due Ă  Brown (1981). La version originale de l'algorithme Ă©tait lĂ©gèrement diffĂ©rente : les Ă©vĂ©nements d'intersection de deux segments n'Ă©taient pas retirĂ©s de Q lorsque d'autres Ă©vĂ©nements rendaient ces segments non adjacents. Ceci entraĂ®ne une utilisation de plus d'espace[3].

Chen et Chan (2003) ont décrit une version très économe en mémoire de l'algorithme de Bentley-Ottmann. La plupart des informations y sont encodées dans l'ordre des segments de l'entrée de l'algorithme, ce qui requiert seulement O(log2n) blocs mémoire. Cependant, l'algorithme est ralenti d'un facteur logarithmique pour l'accès à l'information encodée.

Cas particuliers et problèmes de précision numérique

La description de l'algorithme ci-dessus suppose que les segments ne sont pas verticaux, que les extrĂ©mitĂ©s de segments ne se chevauchent pas, que les intersections ne sont formĂ©es que par deux segments et que deux points d'Ă©vĂ©nement ne peuvent avoir la mĂŞme abscisse. Cependant, ces hypothèses ne sont pas valides pour la plupart des applications du problème. Bentley et Ottmann (1979) ont suggĂ©rĂ© de perturber lĂ©gèrement les coordonnĂ©es des segments en entrĂ©e pour Ă©viter ce genre de coĂŻncidences numĂ©riques sans prĂ©ciser comment. De Berg et al. (2000) ont mis au point les procĂ©dures suivantes pour gĂ©rer les cas particuliers :

  • Trier les points d'Ă©vĂ©nement de mĂŞme abscisse selon leur ordonnĂ©e pour pouvoir les traiter. Cette modification gère Ă  la fois le problème des points de mĂŞme abscisse et le problème des segments verticaux. Les Ă©tapes nĂ©cessaires pour traiter un segment vertical sont alors essentiellement les mĂŞmes que celles d'un segment quelconque avec une très forte pente.
  • DĂ©finir un segment comme un fermĂ© contenant ses extrĂ©mitĂ©s. Ainsi, deux segments qui partagent une extrĂ©mitĂ© ou un segment qui contient l'extrĂ©mitĂ© d'un autre segment gĂ©nĂ©reront une intersection.
  • Lorsque plusieurs segments se coupent en un mĂŞme point, crĂ©er et traiter un Ă©vĂ©nement unique pour cette intersection. Les mises Ă  jour de l'arbre binaire de recherche causĂ©es par cet Ă©vĂ©nement peuvent impliquer la suppression de tous les segments dont c'est l'extrĂ©mitĂ© droite, l'insertion de nouveaux segments dont c'est l'extrĂ©mitĂ© gauche et l'inversion de l'ordre des autres segments contenant ce point d'Ă©vĂ©nement. La sortie de l'algorithme dĂ©crit par de Berg et al. (2000) consiste alors en l'ensemble des points d'intersection de segments, marquĂ©s par les segments auxquels ils appartiennent, plutĂ´t que l'ensemble des paires de segments de lignes qui se coupent.

Pour la correction de l'algorithme, il est nĂ©cessaire de dĂ©terminer (sans approximation) les relations « en dessous » et « au-dessus » entre une extrĂ©mitĂ© et un segment et de hiĂ©rarchiser correctement les points d'Ă©vĂ©nement. Pour cette raison, il est standard d'utiliser des coordonnĂ©es entières pour les extrĂ©mitĂ©s des segments et d'utiliser des coordonnĂ©es rationnelles exactes pour les intersections Ă  l'aide de l'arithmĂ©tique multiprĂ©cision. Il est cependant possible d'accĂ©lĂ©rer les calculs et les comparaisons de coordonnĂ©es Ă  l'aide de calculs en virgule flottante et en vĂ©rifiant si les valeurs calculĂ©es de cette manière sont suffisamment prĂ©cises pour ĂŞtre utilisĂ©es sans aucune possibilitĂ© d'erreur. Les calculs arithmĂ©tiques exacts requis pour une implĂ©mentation naĂŻve de l'algorithme de Bentley-Ottmann peuvent exiger cinq fois le nombre de bits de prĂ©cision des coordonnĂ©es de segments en entrĂ©e. Toutefois, Boissonat et al. (2000) ont dĂ©crit des modifications de l'algorithme pour rĂ©duire la prĂ©cision requise Ă  deux fois le nombre de bits des entrĂ©es.

Algorithmes plus rapides

O(n log n) est un minorant inĂ©vitable pour la complexitĂ© temporelle de l'algorithme de Bentley-Ottmann. Il Ă©quivaut au minorant du problème de la dĂ©tection d'intersection de segments dans un modèle algĂ©brique de calcul utilisant des arbres de dĂ©cision[4]. Cependant, la dĂ©pendance en k, le nombre d'intersections est amĂ©liorable. Clarkson (1988) et Mulmuley (1988) ont fourni des algorithmes probabilistes pour construire un graphe planaire dont les sommets sont les extrĂ©mitĂ©s et les intersections de segments, et dont les arĂŞtes sont des morceaux de segments reliant ces sommets. La complexitĂ© en temps de ces algorithmes est en O(n log n + k). Le mĂŞme problème a Ă©tĂ© rĂ©solu de manière dĂ©terministe avec la mĂŞme borne temporelle O(n log n + k) par Chazelle et Edelsbrunner (1992). Cependant, la construction de cet arrangement comme un ensemble nĂ©cessite O(n + k) d'espace mĂ©moire, supĂ©rieur Ă  la complexitĂ© spatiale en O(n) de l'algorithme de Bentley-Ottmann. Balaban (1995) a dĂ©crit un algorithme diffĂ©rent qui rĂ©pertorie toutes les intersections en temps O(n log n + k) et en espace O(n).

Si les segments et leurs extrĂ©mitĂ©s forment les arĂŞtes et les sommets d'un graphe connexe (Ă©ventuellement avec les intersections), la borne temporelle en O(n log n) de l'algorithme de Bentley-Ottmann peut aussi ĂŞtre rĂ©duite. Comme Clarkson, Cole et Tarjan (1992) l'ont montrĂ©, il existe dans ce cas un algorithme probabiliste pour rĂ©soudre ce problème en temps O(n log* n + k) oĂą la fonction log* dĂ©signe le logarithme itĂ©rĂ©, qui croit beaucoup plus lentement que le logarithme. Un algorithme probabiliste semblable d'Eppstein, Goodrich et Strash (2009) permet de rĂ©soudre le mĂŞme problème en temps O(n + k log(i)n) pour toute constante i oĂą log(i) dĂ©signe la fonction obtenue par itĂ©ration de la fonction logarithme i fois. Le premier de ces algorithmes est de complexitĂ© temporelle linĂ©aire pour peu que k soit plus grand que n d'un facteur log(i)n pour toute constante i. Au contraire, le second algorithme prend un temps linĂ©aire Ă  condition que k soit plus petit que n d'un facteur log(i)n. Ces deux algorithmes consistent Ă  appliquer l'algorithme de Bentley-Ottmann sur de petits Ă©chantillons alĂ©atoires de l'entrĂ©e.

Notes

(en) Cet article est partiellement ou en totalité issu de l’article de Wikipédia en anglais intitulé « Bentley–Ottmann algorithm » (voir la liste des auteurs).
  1. (en) Shamos et Hoey (1976).
  2. Dans la description de l'algorithme de de Berg et al. (2000), la ligne de balayage L est horizontale et se déplacement verticalement. Cela échange le rôle des abscisses et des ordonnées dans le déroulement de l'algorithme, mais ne modifie en rien son analyse ou son temps d'exécution.
  3. La complexité spatiale non linéaire de la version originale de l'algorithme a été analysée par Pach et Sharir (1991).
  4. (en) Preparata et Shamos (1985), p. 280, théorème 7.6.

Références

  • (en) I. J. Balaban, « An optimal algorithm for finding segments intersections », Proc. 11th ACM Symp. Computational Geometry,‎ , p. 211-219 (DOI 10.1145/220279.220302)
  • (en) U. Bartuschka, K. Mehlhorn et S. Näher, « A robust and efficient implementation of a sweep line algorithm for the straight line segment intersection problem », Proc. Worksh. Algorithm Engineering,‎ (lire en ligne)
  • (en) J. Bentley et T. Ottmann, « Algorithms for reporting and counting geometric intersections », IEEE Transactions on Computers, vol. C-28,‎ , p. 643-647 (DOI 10.1109/TC.1979.1675432)
  • (en) Mark de Berg, Marc van Kreveld, Mark Overmars et Otfried Schwarzkopf, « Chapter 2: Line segment intersection », Computational Geometry,‎ , p. 19-44
  • (en) J.-D. Boissonat et F. D. Preparata, « Robust plane sweep for intersecting segments », SIAM Journal on Computing, vol. 29,‎ , p. 1401-1421 (DOI 10.1137/S0097539797329373, lire en ligne)
  • (en) K. Q. Brown, « Comments on "Algorithms for Reporting and Counting Geometric Intersections" », IEEE Transactions on Computers, vol. C-30,‎ , p. 147 (DOI 10.1109/tc.1981.6312179)
  • (en) Bernard Chazelle et Herbert Edelsbrunner, « An optimal algorithm for intersecting line segments in the plane », Journal of the ACM, vol. 39,‎ , p. 1-54 (DOI 10.1145/147508.147511)
  • (en) E. Y. Chen et T. M. Chan, « A space-efficient algorithm for segment intersection », Proc. 15th Canadian Conference on Computational Geometry,‎ (lire en ligne)
  • (en) K. L. Clarkson, « Applications of random sampling in computational geometry, II », Proc. 4th ACM Symp. Computational Geometry,‎ , p. 1-11 (DOI 10.1145/73393.73394)
  • (en) K. L. Clarkson, R. Cole et R. E. Tarjan, « Randomized parallel algorithms for trapezoidal diagrams », International Journal of Computational Geometry and Applications, vol. 2,‎ , p. 117-133 (DOI 10.1142/S0218195992000081). Corrigendum, 2 (3) : 341 – 343.
  • (en) D. Eppstein, M. Goodrich et D. Strash, « Linear-time algorithms for geometric graphs with sublinearly many crossings », Proc. 20th ACM-SIAM Symp. Discrete Algorithms (SODA 2009),‎ , p. 150-159 (arXiv 0812.0893)
  • (en) K. Mulmuley, « A fast planar partition algorithm, I », Proc. 29th IEEE Symp. Foundations of Computer Science (FOCS 1988),‎ , p. 580-589 (DOI 10.1109/SFCS.1988.21974)
  • (en) J. O'Rourke, Computational Geometry in C, Cambridge University Press, , 2e Ă©d., 376 p. (ISBN 978-0-521-64976-6), « Section 7.7 : Intersection of segments », p. 263-265
  • (en) F. P. Preparata et M. I. Shamos, Computational Geometry : An Introduction, Springer-Verlag, , « Section 7.2.3 : Intersection of line segments », p. 278-287
  • (en) J. Pach et M. Sharir, « On vertical visibility in arrangements of segments and the queue size in the Bentley–Ottmann line sweeping algorithm », SIAM Journal on Computing, vol. 20, no 3,‎ , p. 460-470 (DOI 10.1137/0220029, MR 1094525)
  • (en) M. I. Shamos et D. Hoey, « Geometric intersection problems », 17th IEEE Conf. Foundations of Computer Science (FOCS 1976),‎ , p. 208-215 (DOI 10.1109/SFCS.1976.16)

Liens externes

Cet article est issu de wikipedia. Text licence: CC BY-SA 4.0, Des conditions supplémentaires peuvent s’appliquer aux fichiers multimédias.