Coûts d'exécution env. recherche du plus proche voisin dans un quadruple saut


10

REMARQUE : La question a été reformulée dans mes réponses: en supposant maintenant que nous pouvons trouver les ancêtres frères les plus bas en , l'ANN peut-il vraiment être exécuté en ?O ( log n )O(1)O(logn)


Les Quadtrees sont des indices spatiaux efficaces. J'ai un casse-tête avec l'implémentation d'une recherche de voisin le plus proche dans une structure à quatre arbres compressée comme décrit dans [2]. (Sans entrer dans les détails, la recherche va de haut en bas le long de carrés dits équidistants, se terminant par le nœud de queue d'un chemin équidistant. Dans l'image jointe, il peut s'agir de n'importe lequel des nœuds du sud-est remplis de points.)

Pour que leur algorithme fonctionne, il faut maintenir pour chaque nœud - un carré avec au moins deux quadrants non vides - des pointeurs pour chaque nœud ancêtre le plus bas (le plus proche dans la hiérarchie) dans chacune des quatre directions (nord, ouest, sud , est). Ceux-ci sont indiqués par les flèches vertes pour l'ancêtre des nœuds vers l'ouest (la flèche pointe au centre du carré des ancêtres).

Le document prétend que ces pointeurs peuvent être mis à jour dans O (1) lors des insertions et suppressions de points. Cependant, quand on regarde l'insertion du point vert, il semble que je doive mettre à jour n'importe quel nombre arbitraire de pointeurs, dans ce cas six d'entre eux.

J'espère une astuce pour faire cette mise à jour du pointeur en temps constant. Peut-être existe-t-il une forme d'indirection qui peut être exploitée?

quadtree avant (gauche) et après (droite) insertion de point

ÉDITER:

La section pertinente de l'article est 6.3, où il se lit: "si le chemin a des virages, alors en plus du ancêtres les plus bas de , nous devrions également considérer pour chacune des directions la plus basse ancêtre de qui va dans cette direction [...] Trouver ces carrés à partir de peut être fait en fois par carré si nous associons pointeurs supplémentaires à chaque carré dans pointant vers ses ancêtres les plus proches pour chaque direction . Ces pointeurs peuvent également être mis à jour en temps lors de l'insertion ou de la suppression d'un point. "q q O ( 1 ) 2 d Q 0 O ( 1 )log(c/ε)q q2dqqO(1)2dQ0O(1)

[2]: Eppstein, D. et Goodrich, MT et Sun, JZ, «The Skip Quadtree: A Simple Dynamic Data Structure for Multidimensional Data», dans Actes du vingt et unième symposium annuel sur la géométrie informatique, pp. 296—305 , 2005.


2
Cela fait un moment, donc je ne me souviens pas précisément, mais en relisant le papier ce matin (les versions arxiv et journal), je n'ai pas pu trouver où il est dit que nous gardons les pointeurs dont vous dites avoir besoin. Je pensais que nous ne gardions que des pointeurs parent-enfant et des pointeurs croisés. Alors peut-être pourriez-vous indiquer plus précisément le texte du document qui dit ce que vous dites.
David Eppstein

2
Salut David, merci d'avoir regardé. La recherche ANN est la dernière section (6). Le problème est indiqué sur la fig. 7 (b) qui est à peu près ce que j'ai représenté dans l'illustration ci-dessus, si q est quelque part en bas à gauche. J'ai modifié la question pour inclure la partie particulière du texte de la section 6.3. J'ai quelques idées sur la façon dont je pourrais être détendu avec la définition de l'équistabbing peut-être, mais je ne suis pas sûr de pouvoir prouver que tout comptage alternatif ne viole pas les performances ciblées ...
0__

2
Ok, cela ressemble à un problème. J'en discute avec Goodrich (nous avons perdu le contact avec Sun, qui a fait la plupart des détails ici). Notre sentiment actuel est que nous ne devrions pas réellement avoir besoin de ces pointeurs supplémentaires (nous n'en avons pas besoin pour les plages approximatives, pourquoi les voisins approximatifs devraient-ils être différents, et il devrait être possible pour l'algorithme de requête de se souvenir des ancêtres qu'il a vus sur le plutôt que d'utiliser des pointeurs pour les rechercher), mais nous reviendrons vers vous lorsque nous serons un peu plus sûrs des détails ici.
David Eppstein

2
Super, merci beaucoup. Pour des raisons de nombre de caractères et de disposition, j'ajouterai une réponse qui esquisse mon «idée intuitive», c'est peut-être un point de départ.
0__

Réponses:


11

Comme David, je ne sais pas pourquoi Jonathan a fait cette remarque sur les 2 ^ d pointeurs. Ils ne sont pas nécessaires. Comme David l'a mentionné ci-dessus, la propriété essentielle est que lorsque nous effectuons un emplacement de point sur une feuille v dans Q_0, il suffit de se souvenir des nœuds frères (et de leurs boîtes) dans le saut d'arbre. Lorsque nous traitons une boîte à partir de P, nous faisons un emplacement de point pour la boîte à feuilles la plus proche de notre point de requête, en insérant les boîtes frères au fur et à mesure. Il semble que ce serait plus ou moins la même chose que votre réponse. De plus, cette procédure est très similaire, par exemple, à la façon dont la localisation approximative des points est effectuée dans l'article suivant: Arya, Sunil and Mount, David M. et Netanyahu, Nathan S.et Silverman, Ruth and Wu, Angela Y., "Un algorithme optimal pour le voisin le plus proche recherchant des dimensions fixes", JACM, 1998. En effet,


C'est une bonne nouvelle! Je ne savais tout simplement pas si l'ajout des frères et sœurs au cours de l'étape descendante changerait ou non la limite du coût global du pire des cas, mais je suppose que non. J'avais examiné le document d'Arya et al., Mais je l'ai trouvé beaucoup moins accessible que votre document
Quadtree

5
Hou la la! Bienvenue sur cstheory.SE!
Hsien-Chih Chang 張顯 之

5

On peut penser à ignorer quadtree comme une implémentation de liste de saut d'une structure de données stockant les points selon leur ordre z. C'est (sans doute) au moins conceptuellement plus simple ...

Voir le chapitre 2 ici: http://goo.gl/pLiEO .

Et oui, en supposant que vous puissiez effectuer certaines opérations de base de l'ordre z en temps constant, vous pouvez certainement faire ANN en temps logarithmique. Le chapitre susmentionné montre également qu'il n'y a aucun moyen d'éviter d'avoir des opérations bizarres si l'on veut des arbres quadratiques compressés. Notez que l'opération LCA n'est pas nécessaire ...


3
Oui, et les variantes déterministes ressemblent beaucoup à 2-3 arbres pour le même ordre z.
David Eppstein

Merci pour le lien, j'ai déjà vu votre article. En tout cas, je n'ai pas pu vérifier empiriquement la borne avec l'algorithme donné. J'ai le sentiment que la référence au lemme 7, qui est utilisé pour limiter le nombre de tours dans le théorème 13, pourrait être invalide, car elle suppose un rayon constant , tandis que le rayon de recherche dans l'ANN change progressivement, tout comme le ensemble de carrés critiques. ? r
0__

Le rayon défini diminue pendant le processus de recherche. Je suis raisonnablement optimiste, l'argument est correct.
Sariel Har-Peled

1

Je pense aussi intuitivement que l'on pourrait vivre sans ces pointeurs, et comme je dois persister tous les nœuds sur le disque dur à un moment donné, toute réduction des pointeurs est grande.

Mon idée est à peu près la suivante: à part le meilleur point candidat (feuille) , nous gardons également une trace de la pire distance à chaque tour, . Une pire distance serait le maximum des distances de tous les coins d'un nœud au point de requête , peu importe si est à l'intérieur d'un carré ou à l'extérieur. r m a x d i s t ( v , q ) q v vlbestrmaxdist(v,q)qvv

Un tour est comme ceci: Si est vide, retournez le , s'il y en avait. Sinon, delete-min donne le actuel dans . Initialisez à (ou définissez-le sur si aucun meilleur candidat n'a encore été observé). Tout d'abord, testez chaque enfant non vide de dans . Si cet enfant est une feuille, mettez à jour et si nécessaire. Si est un nœud, calculez et , ce dernier étant la meilleure distance: Soit zéro, siPlbestp0Q0rmaxlbestp0Q0qlbestrmaxqdist(q,v)dist(q,v)v se trouve à l'intérieur de , ou la distance la plus courte de tous les coins de à .qqv

Si , oubliez , sinon conservez-le. Si le nombre de nœuds est maintenu , pousser les noeuds sur . Fin de manche. q 2 Pdist(q,v)>rmaxq2P

Sinon, procédez de manière similaire à la recherche d'origine: recherchez , le nœud correspondant à dans le le plus élevé possible , et commencez à partir de là: Encore une fois, au lieu de demander à un enfant équidistant de descendre, testez tous les enfants selon la procédure précédente , c'est-à-dire ignorer ceux dont la meilleure distance dépasse . Si après ce test un enfant est resté, descendez-y et recommencez. Si aucun enfant n'est resté, passez à et répétez. Si le test a été effectué en , la manche est terminée.p 0 Q j r m a x Q j - 1 Q 0qp0QjrmaxQj1Q0

En ce moment, je ne sais ni si cela garantit de trouver le plus proche voisin dans tous les cas possibles, ni qu'il fonctionne aussi bien que l'algorithme d'origine. Aussi si l'initialisation de est suffisante ou non. Et quelle devrait être la priorité en - toujours la meilleure distance? PrmaxP


EDIT (avril 2013)

J'ai maintenant mené plus d'expériences avec une clarification de l'algorithme ci-dessus qui utilise une définition de nœuds `` équipotents '' au lieu de nœuds d'équilibrage, en se basant sur la propriété selon laquelle la descente vers un tel nœud ne change pas la zone couverte par la forme de requête actuelle de l'étendue .rmax

Malheureusement, on peut construire des cas pathologiques (voir l'image ci-dessous; le point de requête est en bas au centre) où les performances se dégradent en tours.O(n)

entrez la description de l'image ici


0

J'ai maintenant implémenté l'algorithme basé sur l'équistabbing, où les ancêtres frères les plus bas sont recherchés en force brute (avant d'essayer de trouver une variante O (1)), afin de vérifier le nombre maximal de tours revendiqués dans le théorème 13: .O(ϵ1d(logn+logϵ1))

J'utilise l'exemple "pathologique" de ma réponse précédente. Le carré racine bidimensionnel a une longueur de côté de 512, où la coordonnée centrale est (256, 256). Les coordonnées sont données en nombres entiers, menant à un simple . Les points sont placés également espacés horizontalement à travers le carré racine, et le point de requête est à (256, 511) (notez que 512 est déjà en dehors du carré racine).vϵ=1v

Dans la figure ci-dessous, l'arborescence complète est affichée, et le nombre de points dans cet exemple est 16. Les contours carrés bleus indiquent les carrés intéressants qui sont poussés dans la file d'attente prioritaire, et les chiffres en leur centre indiquent le numéro rond dans qu'ils sont poussés. Les points foliaires découverts sont également étiquetés avec le numéro rond dans lequel ils sont comptabilisés. Les trois cercles bleus transparents indiquent le rayon NN connu après le 1er, le 2e et le 7e tour (le voisin le plus proche est vu pour la première fois au 7e tour). Il y a 12 tours au total (les 6 derniers carrés pop seulement de la file d'attente, mais n'ajoutez pas de nouveaux carrés).Q0

J'ai exécuté cet exemple avec une série de carrés racines de plus en plus grands et un nombre de points, où l'espacement des points est resté le même (32). Cela a confirmé ce qui est déjà intuitivement visible dans l'illustration: l'algorithme a besoin de tours, tandis que le théorème 13 avec et indique que seuls tours seraient nécessaires.d=2ϵ=1O(logn)O(n)d=2ϵ=1O(logn)

Donc, à moins que je manque quelque chose de crucial, l'algorithme ne peut pas atteindre la vitesse indiquée. Des commentaires ou des idées?

traversée

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.