9
votes

Connecter les points de définition dans les segments de ligne

On m'a donné une tâche où je dois connecter tous les points de l'avion 2D. Il y a quatre conditions à remplir:

  1. La longueur des segments de tous les segments réunis doit être minimale.
  2. Un point peut faire partie d'un seul segment de ligne.
  3. Les segments de ligne ne peuvent pas intersecter
  4. Tous les points doivent être utilisés (on ne peut pas être laissé seul mais seulement s'il ne peut pas être évité)

    image pour visualiser le problème: Entrez la description de l'image ici

    La mauvaise image connectée des points correctement, bien que la longueur totale soit plus grande que celle à gauche.

    Au début, j'ai pensé à trier les points et à le faire avec une ligne de balayage et à construire un arbre de toutes les possibilités, bien que cela semble être un moyen d'une solution compliquée avec une complexité énorme. Par conséquent, je cherche de meilleures approches. J'apprécierais quelques conseils quoi faire, ou comment puis-je m'approcher du problème.


1 commentaires

Je ne sais pas trop à ce sujet, mais si vous avez commencé avec une analyse K-Windows ( En.wikipedia.org/wiki/k-Means_Clustering ) Où k = n / 2 ? n étant le nombre de points. Running K-signifie sur votre exemple semblait produire le résultat correct à chaque fois que je l'ai essayé. Avez-vous des exemples plus résolus avec des collections plus importantes de points?


4 Réponses :


0
votes

wow, c'est un problème délicat. C'est beaucoup de conditions à rencontrer.

Je pense à un point de vue de la programmation, la solution "la plus simple" pourrait réellement être de la boucle, de trouver toutes les possibilités qui répondent aux 3 dernières conditions et enregistrent la longueur totale lorsque vous en boucle, et choisissez simplement celui avec La longueur la plus courte à la fin - force brute, devine-et-vérification. Je pense que c'est ce que vous faisiez référence à votre op lorsque vous avez mentionné une "ligne de balayage et construisant un arbre de toutes les possibilités". Cette approche est très chère de calcul, mais si le code est écrit correctement, il devrait toujours fonctionner à la fin.

Si vous voulez la solution "meilleure" solution, où vous voulez simplement résoudre la réponse finale unique, j'ai bien peur que mes compétences en mathématiques ne soient pas assez fortes pour cela - je ne suis même pas sûr s'il y a toute solution analytique unique à ce problème pour toute collection arbitraire de points. Peut-être essayez peut-être de vérifier avec les gens sur Mathoverflow . Si une personne là-bas peut vous expliquer avec les mathématiques derrière ce calcul, vous avez toujours besoin d'aide pour convertir ce mathématique en code dans un certain langage de programmation, mettez-vous à jour votre question (peut-être avec un lien vers la réponse qu'ils vous fournissent) et Je suis sûr que quelqu'un sera capable de vous aider à partir de ce point.


0 commentaires

0
votes

L'une des solutions possibles consiste à utiliser la théorie des graphes.

construire un graphique bipartite g, de sorte que chaque point ait sa copie dans les deux parties. Maintenant, mettez les bords entre les points i et j avec le poids = i == j? Infinity: distance [i] [j] . La correspondance maximale maximale du poids dans le graphique sera la configuration souhaitée.

Notez que, étant donné que cela se trouve sur un plan 2D euclidien, les "bords" résultants de la correspondance ne se croisent pas. Disons que les bords AB et xy intersect pour les points a, b, x, y . Ensuite, la correspondance n'est pas du poids minimum, car AX, par ou ay, bx produira un poids total plus petit sans intersection (ceci provient de l'inégalité de triangle A + B> c)


0 commentaires

1
votes

Je commencerais avec une triangulation de Delaunay de la partie Set. Cela devrait déjà vous donner les connexions voisines les plus proches de chaque point sans intersections. à l'étape suivante, je regarderais les triangles qui résultent de la triangulation - la propriété commode ici est celle basée sur votre Manchet, vous pouvez choisir exactement un côté de chaque triangle et retirer les deux autres de la sélection.

Le problème qui reste maintenant est de choisir ces bords qui vous donnent la plus petite somme totale qui, bien sûr, ne sera pas toujours le plus petit que celui-ci aurait déjà pu être bloqué par un triangle voisin. Je commencerais par une approche gourmande, choisissant toujours le plus petit bord restant qui n'a pas encore été bloqué par les triangles voisins.

edit: Dans la prochaine étape, vous récupérez une liste de tous les bords de la triangulation et triez-les par longueur. Vous faites également une autre liste dans laquelle vous comptez la quantité de connexions que chaque point a. Vous ithérez maintenant la liste des bords passant du bord le plus long au plus bref et vérifiez les deux points qu'il se connecte dans la liste de comptage de connexion: Si chacun des points a encore plus d'une connexion, vous pouvez jeter le bord et décrémenter le Compte de connexion pour les deux points concernés. Si au moins l'un des points n'a plus qu'une seule connexion, vous avez l'un des bords que vous recherchez. Vous répétez le processus jusqu'à ce qu'il ne reste plus de bords et cela devrait, espérons-le, vous donner la plus petite somme de bord possible.

Si je ne me trompe pas, ce problème est lié lié au problème du sac à dos qui est NP-Hard, donc je ne suis donc pas sûr que cette solution vous donne vraiment le meilleur possible.


0 commentaires

1
votes

Je dirais que ceci est une extension du problème du vendeur itinérant connu .

Une bonne technique (si un peu à l'ancienne) consiste à utiliser une technique d'optimisation de recuit simulé .

Vous devrez effectuer des ajustements au coût (A.K.A. Objectif ) fonctionner pour rater des sections du chemin. Mais étant donné un chemin de candidat continu, il est raisonnablement trivial de décider quelles sections manqueraient de minimiser sa longueur. (Vous enlevez d'abord plus de toutes les lignes intersectives).


0 commentaires