7
votes

Comment utiliser l'ordre de Morton dans la plage de gamme?

Si j'ai un jeu de données, où les clés sont des points en 3D, représentés par 3 entiers 64 bits signés. Et je souhaite utiliser un magasin de valeur de clé (trié) pour les stocker, où les touches ne sont que de l'ensemble d'octet (mais je peux spécifier un comparateur). Je pense que je peux transformer tous ces points en une matrice d'octet à l'aide de l'entrelacement bit, comme cela est fait avec Z / Morton Command comme dans Comment calculer un numéro de morton 3D

En plus de récupérer des points individuels, qui peuvent être effectués plus simplement sans commander à morton, je souhaite faire une recherche de portée, où je recherche dans une boîte alignée sur les axes. Je définirai A et B comme étant respectivement les coins de la boîte où toutes les coordonnées sont les plus bas et le coin opposé où toutes les coordonnées sont les plus élevées.

Maintenant, mes questions sont:

  1. Pour tout point C, qui est logiquement entre, A et B, le nombre de morton de C soit également entre le nombre de Morton d'A et B? (N'est-ce pas le point d'ordre de Morton?)

  2. Si 1 est non, peut-on et b être "arrondi" aux valeurs qui garantissent que c sera inclus?

  3. supposant que 1 ou 2 est possible, la recherche renvoie-t-elle également des points à l'extérieur de cette boîte, que je dois "post-filtre"? Quelle est la taille de cette "erreur d'erreur" (dépend-elle de la taille ou de la position, de la recherche)?

  4. Le fait que les entiers soient signés causent des problèmes? Et si oui, y a-t-il un travail-autour?

    Pour récapituler, à l'aide de NUMÉROS MORTON n'est qu'une solution possible au problème réel: la recherche de manière efficace dans l'espace entier 3D, lorsque les points 3D doivent être mappés sur une valeur unidimensionnelle? Je veux obtenir tous les points entre A et B, en effectuant une seule gamme Sélectionnez dans la DB, à l'aide d'une touche MIN et d'une clé max, et idéalement, d'obtenir aussi peu de points à l'extérieur de la boîte. aussi possible.


6 commentaires

Ou 5: vous pouvez prendre deux numéros de morton (a, b, c) et (d, e, f) et les ajouter de manière intelligente et rapide (donc pas de désentrelacement ni d'entrelacement et d'entrelacement ) Pour obtenir (A + D, B + E, C + F) , vous pouvez ainsi analyser cette case dans la commande normale. Êtes-vous intéressé par cette technique aussi?


@HAROLD Je ne comprends pas comment l'ajout aide, mais si c'est une solution à la recherche de la plage, je serais intéressé.


Eh bien, peut-être que je ne comprends pas votre problème, mais vous voulez chercher dans une boîte, non? Comme dans, visitez tous les éléments de cette boîte et effectuez probablement une sorte de test sur l'élément? Ce que j'avais à l'esprit était la même idée que trois boucles imbriquées sur x , y et z mais évite de convertir toutes ces coordonnées en Morton Nombres en incrémentant directement les champs de la coordonnée Morton.


Ok, je pense que je vais avoir votre idée, en partie. Mais je ne suis pas sûr que cela s'applique. Je veux obtenir tous les points entre A et B, en effectuant une seule gamme Sélectionnez dans la DB, à l'aide d'une touche MIN et d'une clé max. Je pense que votre solution, en utilisant une boucle, impliquerait de nombreux appels de DB, si je comprends bien correctement.


Oh, oui, je pensais que nous parlions simplement de quelque tableau dans la RAM ici, ce qui complique des questions


Demander toute la gamme ne saurait rien sauter, mais cela vous donnerait une charge complète de données inutiles. Vraiment beaucoup.


3 Réponses :


2
votes

On dirait que je dois répondre à ma question moi-même. Et la réponse se rapportera à la courbe d'ordre z, qui est ce que je réellement demandé. Ceci est aussi loin que je l'obtiens:

  1. Oui. Il a toujours travailler comme ça avec des courbes d'ordre z. Li>
  2. est pas pertinent, parce que 1) est vrai. Li>
  3. Cela dépend de la taille de la région est, et où il est, mais le scénario du pire est lorsque vous incluez en fait le centre de l'espace, plutôt que lorsque vous êtes loin de là. Pour toute dimensionnalité, si vous utilisez des index de profondeur N bits dans chaque dimension, il y a des cas particuliers, où la courbe de l'ordre z vous donner une correspondance exacte, et vous obtenez des points que dans la zone de recherche. Cela se produit lorsque les conditions suivantes sont remplies: li>
  4. La zone de recherche est la même taille dans toute dimension, et une puissance de deux, 2 ^ M, où 0
  5. La zone de recherche est un hypercube aligné avec tous les axes. Li>
  6. Toutes les coordonnées de la zone de recherche de coins hypercube sont un multiple de 2 ^ M. Lorsque toutes ces conditions sont remplies, la zone de recherche correspond exactement à un nœud sous-arbre, et correspond donc exactement. Dans le cas général, cependant, le mieux que vous pouvez faire est de trouver le plus petit noeud qui contiendra tous les points souhaités, et subdivisez récursive dans les petits noeuds qui fournissent une correspondance partielle, à une profondeur maximale souhaitée, pour obtenir un meilleur match à le coût de l'utilisation de plusieurs requêtes. Trouver le nœud de l'arbre le plus petit qui contient tous les coins de la région équivaut à trouver le préfixe commun du code Morton pour tous les coins. Et lors de l'utilisation d'une seule requête, le nombre de points en dehors de la zone de retour est le volume de ce nœud interrogé moins le volume de la zone de recherche. Li>
  7. Je suis sûr que c'est un problème, mais je n'ai pas trouvé d'informations sur encore. Li> Ol>

    Il semble que je dis est pas clair, donc je vais faire un peu d'art ASCII ... p>

    Un ordre Z de base courbe (Morton commande) en 2D va comme ceci (chemin d'accès est A, B, C, D): p>

    SELECT key,data FROM table WHERE (key >= Hilbert(XXX(box))) AND (key <= Hilbert(YYY(box)))
    


3 commentaires

IIUC Si A et B sont des coins de la zone de recherche, vous prenez le plus long préfixe commun de Morton (A) et Morton (B) pour trouver la plus grande "zone Z" qui contient la zone de recherche et répéter cet algorithme à travers la dichotomie, c'est que correct?


@Amirouche il y a 3 ans, et je suis depuis longtemps abandonné ce projet (pour des raisons non liées à cette question), sans parler de l'utilisateur Morton (ou Hilbert) à nouveau, alors j'ai tout oublié, et je ne peux pas (compétent) répondre à votre question. Pardon.


La source de révélation est vision-tools.com/h-tropf/multidimensionalrangequery.pdf < / a> via WP; Merci!



7
votes

4) Oui, le panneau provoquera un problème, mais il est trivial de résoudre.

Just Xor le bit de signe de x, y et z avec 1 avant de créer votre numéro de morton.

Pourquoi cela fonctionne (en utilisant 1 dimension signé des octets à la place):

-1 en binaire est 11111111

0 en binaire est 00000000

1 en binaire est 00000001

La commande que vous voulez est -1, 0, 1, mais l'ordre binaire actuel est 0, 1, -1.

-1 xor 10000000 = 01111111

0 xor 10000000 = 10000000

1 xor 10000000 = 10000001

maintenant votre ordre binaire est correct



-1
votes

Il n'y a pas grand chose que vous pouvez vous attendre à essayer de réduire les 3 dimensions à 1 dimension. Ce que vous pourriez essayer cependant: trouvez l'axe majeur (c'est-à-dire une ligne qui ajuste à travers vos points), puis projetez les points sur la ligne. Cela vous donne une valeur d'un dimension demandée pour chaque point. Lorsque vous projetez les coins des cases sur la ligne et prenez l'intervalle de ces valeurs, vous obtenez la plage de recherche.


0 commentaires