Wenn der gerichtete Graph linear ist, geben Sie die Knoten der Reihe nach zurück.Andernfalls fehlschlagen

cs.stackexchange https://cs.stackexchange.com/questions/125142

  •  29-09-2020
  •  | 
  •  

Frage

Problem

Ich habe eine Reihe von edges (a, b), wo a und b sind Knoten in einem gerichteten, azyklischen Graphen (DAG).

Die Anzahl der Kanten ist garantiert die Anzahl der Knoten - 1.

Ich suche nach einem Algorithmus, der eine Folge von Knoten findet [n_1, ... n_n] damit die Sequenz enthält aller knoten im Graphen, und dass alle Kanten (n_i, n_i+1) für 0 < i < n existieren in edges.Wenn diese Reihenfolge nicht möglich ist, weil die angegebene Menge von edges entspricht nicht der Menge der erforderlichen Kanten, dann muss ein Fehler ausgegeben werden.

Bearbeiten:der Graph kann eine beliebige Anzahl von getrennten Komponenten aufweisen.Ich betrachte einen Graphen mit mehreren getrennten Komponenten offensichtlich nicht als linear.

Bisherige Ideen

Beachten Sie, dass ich überprüfe, ob die Anzahl der edges ist genau die Anzahl der Kanten, die erforderlich sind, damit eine solche Sequenz existiert.Infolgedessen kann der Algorithmus fehlschlagen, wenn zwei Kanten vorhanden sind, die sich eine Quelle oder ein Ziel teilen.Ich brauche diese Sequenz jedoch noch.

Mir ist klar, dass die topologische Sortierung eine lineare Ordnung eines gerichteten Graphen zurückgibt, die meinen Anforderungen entspricht.Ich möchte jedoch immer noch scheitern, wenn der Graph nicht genau so linear ist, anstatt sowieso eine lineare Ordnung zu erhalten.

Vielleicht kann ich validieren und dann eine topologische Sortierung durchführen.Aber das klingt ineffizient.Ich bin mir auch nicht sicher über die formalen Namen der Dinge in diesem Problem, daher ist es schwierig, einfach einen Algorithmus nachzuschlagen.Ich habe das Gefühl, dass mir hier eine einfache Verbindung oder ein Trick fehlt.

Könnten Sie mir einen Algorithmus zur Verfügung stellen, der dies erreicht?Ich nehme Pseudocode oder eine beliebige Sprache Ihrer Wahl.

War es hilfreich?

Lösung 2

Ich habe einen Algorithmus gefunden, der zumindest meine Testfälle besteht:

let N = set of all nodes
let E = set of all edges

if (|E| != |N|-1) fail

let possibleStartNodes = new set containing all of N
let nexts = new dictionary from node -> node

foreach (prev, next) in E:
  if (next not in possibleStartNodes) fail 
  remove next from possibleStartNodes
  nexts[prev] = next
end foreach

if (|possibleStartNodes| != 1) fail

let currentNode = the one node in possibleStartNodes
let ordering = new list
ordering.push(currentNode)

while (nexts contains value for currentNode) 
  ordering.push(next)
  currentNode = next
end while

return ordering

$A(n)$ sieht für mich ziemlich vernünftig aus.Gibt es Möglichkeiten zur Verbesserung?

Bearbeiten: Ich würde mich über Hinweise zu den richtigen Fachbegriffen für die von mir verwendeten Konzepte freuen

Andere Tipps

Hier ist ein ziemlich nicht optimaler Algorithmus, um Ihnen den Einstieg zu erleichtern.

Über alle Kanten gehen $(ein, b)$.Gehen Sie für jede Kante erneut über alle Kanten und überprüfen Sie, wie oft $ein$ erscheint.Stoppen Sie, sobald Sie entdecken $ein$ das erscheint nur einmal (wenn das nie passiert, ablehnen).Wir werden nehmen $ n_1 = ein $.

Gehen Sie noch einmal über alle Kanten und suchen Sie nach der einzigartigen Kante $(n_1,b)$ in welchem $n_1$ erscheint.Nehmen $n_2 = b$.

Gehen Sie noch einmal über alle Kanten und suchen Sie nach einer Kante $(n_2,b)$ in welchem $n_2$ erscheint links (wenn es keine solche Kante gibt, ablehnen).Nehmen $n_3 = c$.

Fahren Sie auf diese Weise fort und finden Sie $n_4,\punkte,n_n$.

Dieser Algorithmus läuft in $O(n^2)$.Mit Hashing sollten Sie in der Lage sein, es zu verbessern $A(n)$.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit cs.stackexchange
scroll top