pythonalgorithmgraphkosaraju-algorithm

python graph inversion/reversal


hello fellow stackoverflowians,

i'm trying to implement kosaraju's algo, which requires inversion of the og directed (and in my case weighted) graph. i've successfully handled this a while back using edge lists and primitive types (idk if that's python's terminology, sorry if that's technically incorrect). however, i'm having trouble with implementing this when using adjacency lists

trying to create a dict with structure { node.val : GraphNode } and append to the GraphNode's neighbors within the dict as necessary. then, set Graph's node list = dict.values()

could be how i define my structs, could be overlooking something obvious in the code, could be my python ineptitudes showing, idk. i'm pretty close to a temper tantrum though

i think i covered all my bases and provided code below, but lmk if more detail is needed. thanks in advance, much appreciated

class GraphNode:
    def __init__(self,val,neighbors=[]) -> None:
        self.val = val
        self.neighbors = neighbors

class Graph:
    def __init__(self, nodes=[]) -> None:
        self.nodes = nodes

    def invert_graph(self):
        visited_edge_set = set()
        node_map = {}
        def dfs(node: GraphNode):
            if node.val not in node_map:
                node_map[node.val] = GraphNode(node.val)
            new_end_node = node_map[node.val]
            for (neigh,weight) in node.neighbors:
                if (neigh.val,node.val) in visited_edge_set or (node.val,neigh.val) in visited_edge_set:
                    continue
                visited_edge_set.add((neigh.val,node.val))
                if neigh.val not in node_map:
                    node_map[neigh.val] = GraphNode(neigh.val)
                new_start_node = node_map[neigh.val]
                new_start_node.neighbors.append((new_end_node, weight))
                dfs(neigh)
        for node in self.nodes:
            node.val not in node_map and dfs(node)
        self.nodes = node_map.values()
    
if __name__ == "__main__":
    zero = GraphNode(0)
    one = GraphNode(1)
    two = GraphNode(2)
    three = GraphNode(3)
    four = GraphNode(4)
    five = GraphNode(5)
    six = GraphNode(6)
    zero.neighbors = [(two, 2), (four, 3)]
    one.neighbors = [(three, 1)]
    two.neighbors = [(six, 6)]
    three.neighbors = [(four, 4)]
    four.neighbors = [(one, 1), (six, 4)]
    six.neighbors = [(five, 2)]
    arr = [zero,one,two,three,four,five,six]
    g = Graph(arr)
    g.invert_graph()

Solution

  • Two issues: