2017-05-14 7 views
0

Ich schreibe ein Projekt, wo Sie ein Polygon mit Scheitelpunkten und Linien verbinden können und dann in eine Physik-Engine wie pymunk laufen lassen.Überprüfen, ob alle Scheitelpunkte in einer Schleife verbunden sind

Ich möchte sicherstellen, dass alle Knoten in einer Schleife wie diese enter image description here

verbunden sind, und wenn es nicht ganz wie so

enter image description here
verbunden ist Jeder Knoten ist ein Vertex-Objekt, das unter

class Vertex(): 
    def __init__(self, id, position, pointsTo = [], rectSize = [10, 10]): 
     self.id = int(id) 
     self.position = tuple(position) 
     self.rect = tuple((position[0], position[1], rectSize[0], rectSize[1])) 
     self.pointsTo = list(pointsTo) 

    def setPosition(self, position): 
     self.position = tuple((position[0] - (self.rect[2]/2), position[1] - (self.rect[3]/2))) 
     self.rect = tuple((self.position[0], self.position[1], self.rect[2], self.rect[3])) 

    def getRect(self): 
     return self.rect 

Wo pointsTo eine Liste der Scheitelpunkte ist, die an diesem Eckpunkt verbunden sind .Wie würde ich herausfinden, ob eine Liste von Scheitelpunkten in einer Schleife miteinander verbunden ist

+0

Ist 'pointsTo' eine Liste von Vertex-Instanzen? – Artyer

+0

@Artyer Ja, Entschuldigung für die langsame Antwort. – adammoyle

+0

Nur um zu überprüfen, dass alle Adjazenzlisten genau zwei Elemente haben, im Graphen g, das ist eine Liste von Vertex-Objekten: all (map (lambda v: 2 == len (v.pointsTo), g)) –

Antwort

1

Wenn wir es als Graphen betrachten, haben wir den Scheitelpunkt, und pointsTo ist eine Adjazenzliste von Kanten. Ich nehme auch eine ungerichtete Graphik an, basierend auf der Illustration in der Frage, also wenn A-> B, dann B-> A. Wir können uns ein Polygon als einen N-Zyklus vorstellen. Ich ignoriere die Möglichkeit von Kanten, die sich auf dem Bildschirm ohne tatsächlichen Scheitelpunkt im Diagramm kreuzen.

Angenommen, es ist ein N-Zyklus. Dann hat jeder Eckpunkt genau zwei Kanten und alle Eckpunkte sind verbunden. Beides ist einfach zu testen.

(Hinweis: Wenn jeder Scheitelpunkt genau zwei Kanten hat, dann haben Sie sich verbunden. Der verbundene Test ist nur um zu sehen, ob es mehrere Polygone gibt, und um den Beweis zu erleichtern. Siehe für eine ähnliche Wie dieses berühmte Problem zeigt, könnten Sie sogar testen, ob Sie mehrere Polygone zulassen, aber nur nach zusätzlichen Linien suchen möchten, die nicht zu einem Polygon verbunden sind.

hypothetisch, beginnen Sie an einem beliebigen Punkt und beginnen Sie, die Punkte zu Vertices zu besuchen, die dem Graphen folgen, und niemals eine zuvor besuchte Kante/Vertex zu verwenden. Jedes Mal, wenn Sie einen neuen Scheitelpunkt besuchen, ist es das erste Mal, dass Sie dort waren. Daher können Sie die anderen Punkte nicht an diesem Scheitelpunkt verwenden, sodass Sie fortfahren können, bis Ihnen die Scheitelpunkte ausgehen. Zu diesem Zeitpunkt haben Sie zwei unbenutzte pointsTo - one im Startknoten und einen außerhalb des Endvertex. Entweder zeigen sie auf einen Knoten, der nicht existiert, oder sie zeigen aufeinander, was bedeutet, dass es sich um einen N-Zyklus handelt.

Somit ist der obige Test bewiesen.

Ich sagte, es ist leicht, Dinge zu testen, so muss ich tun, so: Um zu testen, dass die Kurve, siehe https://en.wikipedia.org/wiki/Connectivity_(graph_theory)

verbunden ist

eine Begegnungsflag hinzufügen (auf false initialisiert) mit allen Ecken. Wählen Sie einen beliebigen Eckpunkt aus und beginnen Sie, Nachbarn zu besuchen. Wenn Sie ausgehen, sehen Sie, ob ein Vertex nicht besucht wurde.

oder machen Sie eine Reihe von vertex.id's, fügen Sie sie beim Besuch hinzu. Am Ende prüfen len (das Set) ist die Anzahl der Ecken in der Grafik

+0

Wie wäre es Wenn der Graph ABCDEB verbunden ist und Sie von A aus beginnen? Scheint so, als würdest du jeden Knoten noch einmal besuchen, aber du hättest einen "Schwanz" von deinem Polygon, der von B nach A führt. Du musst auch überprüfen, dass der letzte Knoten, den du besuchst, derselbe wie der erste ist. – Basic

+0

Dieses Gegenbeispiel besteht den Test nicht, also würde man kein Polygon betrachten. B ist mit drei anderen Knoten A, C, E verbunden. Auch A ist nur mit B verbunden. –

+0

Entschuldigung, ich muss diesen Satz überflogen haben. – Basic

0

Sie müssen bei der Definition eines Strongly Connected Component suchen und dann testen, ob Ihr Diagramm als stark von Ihrem Vertex und Edges dh Vertex.pointsTo Formen dargestellt Verbundene Komponente mit allen Vertices in Ihrer Liste.

+0

Dies funktioniert nur, wenn die Links in einer Richtung sind, und wir sehen nicht, wie der Graph erstellt wurde. Die Abbildung deutet auf ungerichtet hin, aber der Code suggeriert, dass er gerichtet ist, ohne dass eine Rückverbindung aufgebaut wird. –

+0

Ein ungerichteter Graph ist nur ein gerichteter Graph mit zwei gerichteten Kanten zwischen A-> B und B-> A, die die ungerichtete Kante A-B darstellen, wobei A und B Vertices sind. –

+0

Ja, und das ist, was ich angenommen habe, aber in diesem Fall ist ein Nicht-Polygon ein SCC, der alle Scheitelpunkte umfasst, was bedeutet, dass die Überprüfung auf SCC nicht funktioniert, um ein Polygon zu erkennen. Wenn die Links in einer Richtung verlaufen, funktioniert die Überprüfung des SCC, da Sie nicht zum Start zurückkehren können, wenn sie nicht in einem Zyklus verbunden sind. Wir haben nur zwei verschiedene Antworten, von denen eine abhängig davon funktioniert, wie die Grafik aufgebaut ist und welche nicht. –

Verwandte Themen