Bei einem Spanning Tree und ein Edge Nicht auf dem Spanning Tree, wie ein Zyklus Basis bilden?

StackOverflow https://stackoverflow.com/questions/1612073

  •  05-07-2019
  •  | 
  •  

Frage

ich ein Diagramm mit Edge-E und Vertex V haben, kann ich den Spanning Tree finden mit Kruskal Algorithmus (oder jede andere Traverse-Backtrack-Traversen wieder Art von Algorithmen), jetzt habe ich alle Zyklus Basen finden wollen, die von utilitizing dass Spanning tree und die Kanten erstellt werden, die nicht auf dem Baum sind, jeder Algorithmus dass mir erlaubt, das zu tun, außer Brute-Force-Methode?

ich kann, natürlich geht von einem Scheitelpunkt der nicht-Spanning-Tree-Kante, bekommt alle Kanten, alle von ihnen erforschen, zieht mich, wenn ich Sackgasse zu finden, bis ich wieder auf die anderen Scheitel der Kante kommen. Aber das ist etwas, äh ... brutal. Jede andere Ideen?

War es hilfreich?

Lösung

Ein einfacher Algorithmus, den wir für die Suche nach Zyklen in Graphen verwenden:

  

ein depth-first erstellen Spanning Tree   wobei jeder Knoten einen Elternteil.       Beim Durchlaufen erstellen der Baum eine Aufzeichnung des verwendeten Knoten.       Wenn eine Kante zeigt auf einen zuvor verwendeten Knoten, speichern sie als   zyklisches Kante.       Wenn der Spanning Tree abgeschlossen ist, wird der Zählwert des zyklischen   Kanten gibt die Anzahl der Zyklen.       Für jede zyklische Kante Rekursion durch die Vorfahren der beiden Knoten   bis ein gemeinsamer Vorfahre gefunden wird. Das   geben genau die Zyklen.

Es kann nützlich sein, um einen Index zu haben (Hashtable) alle Vorfahren eines zyklischen Randknoten, so dass schnell ist, um die gemeinsamen Vorfahren zu finden.

Ich bezweifle, dass dies der beste Algorithmus, aber es ist ziemlich schnell.

Bearbeiten in repsonse Kommentar Jeder Knoten in dem Spanning Tree hat einen Elternteil. Wenn ein Knoten in einem zyklischen Kante erreicht wird berechnet er die Liste der Vorfahren (List<Node>This Liste für Geschwindigkeit indexiert werden kann (dh enthält () ist < O(n)). Wenn ein zyklisches Kante mit zwei Knoten (n1, n2) gefunden wird, dann iteriert durch die Vorfahren von n1, n1.ancestorList ( schnell, da die Liste bereits erstellt) und Test worden, ob der Vorfahr in n2.ancestorList ist. Wenn es (commonAncestor), dann genau diese überquert Vorfahren Zyklen entsprechen. dann durch n2 laufen, bis Sie commonAncestor (schnell) erreichen. sollte die Zeit abhängen auf der Anzahl der zyklischen Kanten, mit der Suche in Listen kombiniert (wahrscheinlich O(logN) aber billig). Es gibt keine Notwendigkeit, den Graphen neu zu entdecken und es gibt keinen Rückzieher.

Andere Tipps

Nach dem Spanning-Tree-Konstruktion, iterieren auf jeder Kante (A, B), die nicht im Baum ist und findet niedrigste gemeinsame Vorfahre (LCA) für Knoten dieser Kante, würde Ihr Zyklus seinen Weg von A -> LCA -> B -> A

können Sie über diesen Link: http://www.topcoder.com/tc?module=Static&d1 = Tutorials & d2 = Lowest Common Ancestor     für eine effiziente niedrigste gemeinsame Vorfahre Algorithmus Umsetzung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top