拓扑排序不符合预期

时间:2016-08-27 17:28:44

标签: python graph topological-sort

这是我在Python中的图形实现。这是有向图。

class DiGraph:
    def __init__(self):
        self.all_vertices = []
        self.vertex_map = {}
        self.size = 0

    def add(self, a, b):

        if a in self.vertex_map:
            av = self.vertex_map[a]
            if b in self.vertex_map:
                bv = self.vertex_map[b]
                av.add(bv)
            else:
                bv = Vertex(b)
                av.add(bv)
                self.vertex_map[b] = bv
                self.all_vertices.append(bv)
                self.size += 1
        else:
            av = Vertex(a)
            self.size += 1
            if b in self.vertex_map:
                bv = self.vertex_map[b]
                av.add(bv)
            else:
                bv = Vertex(b)
                av.add(bv)
                self.vertex_map[b] = bv
                self.all_vertices.append(bv)
                self.size += 1
            self.vertex_map[a] = av
            self.all_vertices.append(av)

    def __sizeof__(self):
        return self.size

    def print(self):
        for v in self.all_vertices:
            print(v.data, end='->')
            for n in v.neighbors:
                print(n.data, end=', ')
            print()


class Vertex:
    def __init__(self, data):
        self.data = data
        self.neighbors = []
        self.connections = 0

    def add(self, item):
        self.neighbors.append(item)
        self.connections += 1

这是拓扑排序的代码

def top_sort(g):
    stack = []
    visited = set()

    for v in g.all_vertices:
        if v not in visited:
            top_sort_util(v, visited, stack)

    for ele in stack:
        print(ele, end=' ')
    print()


def top_sort_util(v, visited, stack):
    visited.add(v)
    for n in v.neighbors:
        if n in visited:
            continue
        top_sort_util(n, visited, stack)
    stack.append(n)

这是来电者图。

def main():
    graph = DiGraph()
    graph.add(1, 2)
    graph.add(1, 3)
    graph.add(3, 4)
    graph.add(3, 5)
    graph.add(2, 6)
    graph.add(2, 7)
    graph.add(2, 8)

    top_sort(graph)


if __name__ == '__main__':
    main()

这是我收到的错误消息,

stack.append(n)
UnboundLocalError: local variable 'n' referenced before assignment

在调试代码时,我可以看到在行stack.append(n)上没有任何内容被附加,虽然递归折叠,但调用堆栈没有进入遍历top_sort_util内的邻居的下一次迭代。 似乎无法理解这里的逻辑错误。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

如果v.neighbors为空,则永远不会设置n,因此stack.append(n)外面的for n in v.neighbors: 会失败。

如果必须将所有n添加到堆栈(而不仅仅是最后一个),请将stack.append()正确地缩进到循环中:

def top_sort_util(v, visited, stack):
    visited.add(v)
    for n in v.neighbors:
        if n in visited:
            continue
        top_sort_util(n, visited, stack)
        stack.append(n)