Distance la plus courte entre un point en A et un point en B

9

Étant donné deux ensembles et contenant chacun points disjoints dans le plan, calculez la distance la plus courte entre un point dans et un point dans , c'est-à-dire .ABnABmin { dist(p,q) | pAqB }

Je ne sais pas si j'ai raison, mais ce problème est très similaire aux problèmes qui peuvent être résolus par programmation linéaire en géométrie computationnelle. Cependant, la réduction à LP n'est pas simple. De plus, mon problème semble lié à la recherche de la condition la plus mince entre deux ensembles de points qui peuvent évidemment être résolus par LP dans O(n) dans un espace à deux dimensions.

com
la source
4
Quelle est la question ici?
Raphael
Je ne suis pas un expert mais généralement en apprentissage automatique, où ces points sont des données, les ensembles se comportent bien la plupart du temps et sont regroupés, donc les algorithmes comme celui suggéré par @Pedro fonctionnent bien.
chazisop
3
"qui peut évidemment être résolu par LP dans O (n) dans un espace à deux dimensions" - je me demande ce qui a motivé cette déclaration. La "programmation linéaire" n'est généralement pas résoluble en temps linéaire; le "linéaire" fait référence à autre chose. Le LP a-t-il donc une forme spéciale?
Raphael

Réponses:

5

J'ai une solution qui peut sembler un peu compliquée, mais qui devrait être plus efficace que la recherche par force brute naïve :O(n2)

  1. laissez être l'axe entre les centres de masse de et .A BvAB
  2. Triez les points en et long de cet axe respectivement dans l'ordre décroissant et croissant, ce qui donne les séquences , , ..., et , , ..., .B a 0 a 1 a n b 0 b 1 b nABa0a1anb0b1bn

Le reste est en pseudo-code pour le rendre plus clair:

d = infinity.
for j from 1 to n
    if (b_1 - a_j) along v > d then break endif
    for k from 1 to n
        if (b_k - a_j) along v > d then
            break
        else
            d = min( d , ||b_k - a_j|| )
        endif
    enddo
enddo

Autrement dit, en pré-triant les points le long de , vous pouvez filtrer les paires qui ne seront jamais à l'intérieur de de l'autre puisque long de sera toujours.d b k - a j v b k - a jvdbkajvbkaj

Dans le pire des cas, c'est toujours , mais si et sont bien séparés, cela devrait être beaucoup plus rapide que cela, mais pas mieux que , ce qui est nécessaire pour le tri.O(n2)ABO(nlogn)

Mise à jour

Cette solution n'est nullement sortie d'un chapeau. C'est un cas particulier de ce que j'utilise dans les simulations de particules pour trouver toutes les paires de particules en interaction avec le binning spatial. Mon propre travail expliquant le problème plus général est ici .

Quant à la suggestion d'utiliser un algorithme de balayage de ligne modifié, bien que intuitivement simple, je ne suis pas convaincu que ce soit dans lorsque des ensembles disjoints sont considérés. Il en va de même pour l'algorithme randomisé de Rabin.O(nlogn)

Il ne semble pas y avoir beaucoup de littérature traitant du problème de paire la plus proche dans disjoints, mais je l' ai trouvé ce qui ne prétend pas à être sous , et ce qui ne semble pas pour faire des réclamations sur quoi que ce soit.O(n2)

L'algorithme ci-dessus peut être vu comme une variante du balayage plan suggéré dans le premier article (Shan, Zhang et Salzberg), mais au lieu d'utiliser l' axe et aucun tri, l'axe entre les ensembles est utilisé et les ensembles sont traversés dans l'ordre décroissant / croissant.x

Pedro
la source
2
@Pedro: Désolé, je n'ai pas commenté plus tôt (pas le temps à l'époque). La raison pour laquelle j'ai rétrogradé votre réponse était parce que c'était une mauvaise réponse et qu'elle n'aurait pas dû être au top. Il s'agit en fait d'un problème bien connu en géométrie de calcul avec le pire des cas O (n log n). Une bonne réponse aurait mis en évidence le problème connu (peut-être avec une référence) et les solutions courantes, qui comprennent: l'utilisation d'arbres kd et le test élément par élément, des algorithmes de balayage, etc. L'idée générale devrait être de prétraiter dans une structure ordonnée et de l'utiliser . Regardez le cas 1D - O plus évident (n log n) là-bas.
ex0du5
2
@ ex0du5: Cela semble comme si vous deviez poster votre propre réponse! Notez qu '«il y a une meilleure réponse» n'est généralement pas une bonne raison pour voter en aval; cette mesure doit être réservée aux réponses erronées, spam et très mal formatées. Pedro n'est ni l'un ni l'autre. Voir également ici pour avoir une idée de la quantité de réflexion que certaines personnes devraient penser avant un downvote.
Raphael
1
@Raphael: Je n'ai pas répondu car il y avait une réponse juste et je n'ai pas eu le temps de rechercher des références. Quant à votre référence sur la façon de voter, c'est un horrible algorithme pour ces sites! Les étudiants en CS devraient en particulier comprendre l'importance de ne pas perdre l'objectif du formalisme. Le but du vote est de déplacer les réponses vers un classement qui guidera les étudiants ultérieurs du même problème vers les réponses les plus utiles. Mon algorithme de vote le fait. Cet algo: évidemment pas. Cela peut être discuté sur une méta si vous voulez, mais en tant qu'adultes, nous devrions utiliser nos pouvoirs pour de bon, je pense.
ex0du5
1
@ ex0du5: Vous semblez avoir du temps libre maintenant. Pouvez-vous réellement montrer que cette instance est en fait un "problème bien connu avec le pire des cas "? O(nlogn)
Pedro
1
@ ex0du5: En fait, la recherche du plus proche voisin, par exemple en utilisant des arbres kd , n'a qu'une complexité moyenne O (logn) . Nous sommes donc de retour à la case départ.
Pedro
4

Vous pouvez adapter l' algorithme de balayage de ligne de la "paire la plus proche" qui est .O(nlogn)

Le seul changement que vous devrez faire est d'ignorer les paires qui appartiennent au même ensemble.

Edit: Ce n'est en fait pas simple (ou même possible) comme je l'ai décrit. Voir les commentaires pour discussion.

Artium
la source
2
Juste une remarque, on peut également adapter l'algorithme classique de division et de conquête pour les paires les plus proches qui s'exécute également en ; voir aussi Wikipedia . O(nlogn)
rizwanhudda
1
Pour un algorithme de temps linéaire aléatoire, voir par exemple Rabin lance une pièce sur le blog de Lipton.
Juho
3
Pourriez-vous être un peu plus précis sur la façon dont vous implémenteriez cela pour les ensembles disjoints, en particulier en ce qui concerne le maintien de la liaison ? O(nlogn)
Pedro
-1 pour inexactitude. L'algorithme de balayage de ligne de paire le plus proche que vous liez repose sur l'ensemble trié contenant des éléments , mais dans le cas d'ensembles disjoints, cet ensemble commence par contenir éléments, il n'est donc plus dans , à du moins pas dans le pire des cas. n O ( n log n )O(1)nO(nlogn)
Pedro
1
@Pedro: Pourquoi serait-il plus grand? Si quoi que ce soit, l'ensemble des points candidats actuels devrait se réduire.
Raphael
4

L'idée dans des problèmes comme celui-ci est de créer une structure ordonnée à partir de l'un des ensembles qui permet des requêtes efficaces du plus proche voisin. L'article classique qui présentait une structure de requête O (log n) pour une dimension arbitraire était le suivant:

Shamos et Hoey sur les solutions Voronoi

Un certain nombre d'autres partitions spatiales basées sur les idées des tesselations de Delauney ont été créées depuis lors, et elles se traduisent également par une variété de descriptions de balayage sous-spatial. Notez que la méthode Voronoi tomberait également sous une description générale de division et de conquête en raison de son partitionnement plan qui fait l'étape de construction O (n log n).

Ainsi, la solution de base à ce problème est:

  1. Prenez l'ensemble A et créez la structure de requête efficace du voisin le plus proche de votre choix. Cette étape de construction est O (n log n) [voir théorème 4].
  2. Pour chaque élément de B, interrogez la structure A pour le plus proche voisin. Chaque requête est O (log n) [voir théorème 15, dimension fixe], donc le temps total de requête pour tous les points de B est O (n log n).
  3. Lorsque le résultat du point A le plus proche de chaque B est récupéré, placez-le dans une structure ordonnée sur la distance. C'est O (log n) insérer chaque résultat, ou O (n log n) pour tous.
  4. Lorsque tous les B ont été examinés, vous pouvez rapidement (O (1)) obtenir le point B dans la structure ordonnée avec la plus petite distance voisine à un point en A.

Comme on peut le voir en regardant la complexité de chaque étape, la complexité totale est O (n log n). Pour le lecteur moderne qui ne regarde pas les articles classiques, cela est couvert dans de nombreux livres d'algorithmes, par exemple "The Algorithm Design Manual" de Skiena.

ex0du5
la source
1
"La solution d'Artium, par exemple, peut être écrite sous cette forme et est entièrement valide." - eh bien, ce que vous proposez ici n'est plus un algorithme de ligne de balayage (pur), donc je n'en sais rien.
Raphael
@Raphael: Bien sûr. Les algorithmes Sweepline prétraitent les points en une structure ordonnée comme décrit ici. J'ai même lié à l'algorithme de Fortune sous sa réponse, qui montre que l'algorithme sweepline n'est qu'une instance de l'algorithme Voronoi. La raison pour laquelle j'ai conservé la solution générique pour la structure de requête est qu'il existe un grand nombre de mécanismes géométriques qui ont été développés pour cela.
ex0du5
B
1

Je ne sais pas si j'ai raison, mais ce problème est très similaire aux problèmes qui peuvent être résolus par programmation linéaire en géométrie computationnelle. Cependant, la réduction à LP n'est pas simple. De plus, mon problème semble lié à la recherche de la condition la plus mince entre deux ensembles de points qui peuvent évidemment être résolus par LP dans un espace à 2 dimensions.

O(nlogn)

Nous allons réduire l'instance du problème de distinction d'élément E à C.

  • S={a1,a2,a3,...,an}
  • ϵ
  • {(ai,0):1in}B={(ai+ϵ):1in}
  • O(n)
    • Sϵ

O(nlogn)

rizwanhudda
la source