Ich habe derzeit eine funktionierende Implementierung von Kosarajis Algorithmus, der bei einem gerichteten Graphen ohne Gewichte die SCCs in einem Graphen ausgibt.Kosarajas Algorithmus für das Finden von SCCs, aber behalten Sie den Überblick zwischen den SCCs?
Ich möchte es so anpassen, dass es auch angibt, wo die Kanten zwischen den SCCs sind.
Hier ist der Code:
from collections import defaultdict
#---- Definitions ----#
#Graph
Graph = {}
#Transpose of Graph
Transpose_Graph = {}
#Visited Nodes for Graph
Visited_Nodes_Graph = {}
#Visited Nodes for Transpose Graph
Visited_Nodes_Transpose_Graph = {}
#Stack to process
Stack = []
#---- Definitions ----#
#Based on the number of verticies, create a dictionary where every vertex is the key, and the value are the edges from it to another vertex.
def Generate_Empty_Graphs(Number_of_Verticies):
for Vertex in range(1, Number_of_Verticies+1):
Graph[Vertex] = []
Transpose_Graph[Vertex] = []
Visited_Nodes_Graph[Vertex] = False
Visited_Nodes_Transpose_Graph[Vertex] = False
#Populate Graph with edges
def Populate_Graphs(Head, Tail):
Graph[Head].append(Tail)
Transpose_Graph[Tail].append(Head)
#Run DFS on given Graph, at provided position.
#This is used for DFS #2 (
def Run_DFS(Vertex, Given_Graph, SCC_List):
Visited_Nodes_Transpose_Graph[Vertex] = True
SCC_List.append(Vertex)
for Adjacent_Vertex in Transpose_Graph[Vertex]:
if(Visited_Nodes_Transpose_Graph[Adjacent_Vertex] == False):
Run_DFS(Adjacent_Vertex, Transpose_Graph[Adjacent_Vertex], SCC_List)
#TODO something here to log it...
return SCC_List
#Process Stack and run DFS
#This is used for DFS #1
def Populate_Stack(Vertex, Given_Graph):
Visited_Nodes_Graph[Vertex] = True
for Adjacent_Vertex in Given_Graph[Vertex]:
if (Visited_Nodes_Graph[Adjacent_Vertex] == False):
Populate_Stack(Adjacent_Vertex, Given_Graph)
Stack.append(Vertex)
def Detect_SCCs(Given_Graph, Number_Of_Verticies):
for Vertex in range(1, Number_Of_Verticies+1):
if(Visited_Nodes_Graph[Vertex] == False):
Populate_Stack(Vertex, Given_Graph)
SCC = []
while(len(Stack) != 0):
Current_Vertex = Stack.pop()
if(Visited_Nodes_Transpose_Graph[Current_Vertex] == False):
SCC = Run_DFS(Current_Vertex, Transpose_Graph, [])
print(SCC)
Number_Of_Verticies = 9
Generate_Empty_Graphs(Number_Of_Verticies)
Populate_Graphs(1, 2)
Populate_Graphs(2, 3)
Populate_Graphs(3, 1)
Populate_Graphs(3, 4)
Populate_Graphs(3, 7)
Populate_Graphs(4, 6)
Populate_Graphs(6, 5)
Populate_Graphs(5, 4)
Populate_Graphs(7, 8)
Populate_Graphs(8, 9)
Populate_Graphs(9, 7)
Detect_SCCs(Graph, Number_Of_Verticies)
Für das gegebene Diagramm:
{1,2,3} -> {8,7,9} {1,2,3} - > {4,5,6}
Das bedeutet, es gibt eine Kante zwischen {1,2,3} und {8,7,9}. Es gibt auch eine Kante zwischen: {1,2,3} -> {4,5,6}
Es gibt jedoch keine Kante zwischen {8,7,9} und {4,5,6}
Ziel ist es, diese zu verfolgen, um die größtmögliche Anzahl an SCCs zu bestimmen, die von einem gegebenen Scheitelpunkt aus berührt werden können. Wie kann ich diesen Code ändern, um ihn als Diagramm zu erstellen?
Also wäre Ihr Vorschlag eine Ergänzung zu dem Code, den ich bereits habe, richtig? Können Sie Code bereitstellen, der dies anzeigt? – Jorge
Hier könnte die Änderung in Ihrem Code sein, wie ich in der Antwort erklärt habe. https://ideone.com/veSoSC – dipal