Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
拓扑排序python实现中的错误_Python_Algorithm_Graph - Fatal编程技术网

拓扑排序python实现中的错误

拓扑排序python实现中的错误,python,algorithm,graph,Python,Algorithm,Graph,我刚刚编写了一些代码,用于在Python中进行拓扑排序,给定一个无向图 G = { 7: [11, 8], 5: [11], 3: [8, 10], 11: [2, 9], 8: [9], 2: [], 9: [], 10: [] } class GraphException(Exception): def __init__(self, str): pass def has_incoming_edges(

我刚刚编写了一些代码,用于在Python中进行拓扑排序,给定一个无向图

G = {
    7: [11, 8],
    5: [11],
    3: [8, 10],
    11: [2, 9],
    8: [9],
    2: [],
    9: [],
    10: []
}

class GraphException(Exception):
    def __init__(self, str):
        pass

def has_incoming_edges(g, a_node):
    """
    Return True if it has incoming edges,
    False otherwise.
    """
    for each_node in g:
        if a_node in g[each_node]:
            return True
    return False

def remove_edge(g, start, end):
    """
    Removes the edge start->end in g.
    """
    edges = g[start]
    edges.pop(edges.index(end))

def edges_exist(g):
    for each_node in g:
        if g[each_node]: return True
    return False

def do_topsort(g):
    S = [] # list of all nodes that have no incoming nodes
    L = [] # topordering

    for each_node in G:
        if not has_incoming_edges(g, each_node):
            S.append(each_node)

    while S:
        a_node = S.pop(0)
        print "Popping", a_node
        L.append(a_node)
        x = g[a_node]
        #TODO NEVER ITERATE ON A LIST AND REMOVE FROM IT AT
        # THE SAME TIME
        backup = g[a_node]
        for each_connected in backup:
            print ">>>", backup

            print "Removing edge", a_node, each_connected
            # Remove the edge from a_node to each_connected
            remove_edge(g, a_node, each_connected)

            print g

            if not has_incoming_edges(g, each_connected):
                print "Adding", each_connected
                S.append(each_connected)

    if edges_exist(g):
        print g
        print L
        raise GraphException("Graph has cycles")
    return L

def main():
    global G
    topsort = do_topsort(G)
    print topsort

if __name__ == '__main__':
    main()
我从这段代码中获得的输出如下:-

Popping 3
>>> [8, 10]
Removing edge 3 8
{2: [], 3: [10], 5: [11], 7: [11, 8], 8: [9], 9: [], 10: [], 11: [2, 9]}
Popping 5
>>> [11]
Removing edge 5 11
{2: [], 3: [10], 5: [], 7: [11, 8], 8: [9], 9: [], 10: [], 11: [2, 9]}
Popping 7
>>> [11, 8]
Removing edge 7 11
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [2, 9]}
Adding 11
Popping 11
>>> [2, 9]
Removing edge 11 2
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [9]}
Adding 2
Popping 2
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [9]}
[3, 5, 7, 11, 2]
Traceback (most recent call last):
  File "topsort.py", line 80, in <module>
    main()
  File "topsort.py", line 76, in main
    topsort = do_topsort(G)
  File "topsort.py", line 71, in do_topsort
    raise GraphException("Graph has cycles")
__main__.GraphException
弹出3
>>> [8, 10]
拆卸边缘3 8
{2: [], 3: [10], 5: [11], 7: [11, 8], 8: [9], 9: [], 10: [], 11: [2, 9]}
弹出5
>>> [11]
拆卸边缘5 11
{2: [], 3: [10], 5: [], 7: [11, 8], 8: [9], 9: [], 10: [], 11: [2, 9]}
弹出7
>>> [11, 8]
拆卸边缘7 11
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [2, 9]}
加11
弹跳11
>>> [2, 9]
拆卸边缘11 2
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [9]}
添加2
弹出2
{2: [], 3: [10], 5: [], 7: [8], 8: [9], 9: [], 10: [], 11: [9]}
[3, 5, 7, 11, 2]
回溯(最近一次呼叫最后一次):
文件“topsort.py”,第80行,在
main()
文件“topsort.py”,第76行,主目录
topsort=do_topsort(G)
do_topsort中第71行的文件“topsort.py”
引发GraphException(“图形有循环”)
__主图形异常

请注意,在输出中有一行
弹出7
。它表示
7
是针对备份中连接的每个\u在for循环
中处理的节点:
。我们可以看到7同时连接到
11
8
。但是,循环似乎只运行了一次并删除了边
7-11
。节点
8
似乎未被处理。我做错了什么?

您正在迭代并从备份中删除元素,因此最终删除了错误的元素,请使用:

for each_connected in reversed(backup):
或复制列表:

for each_connected in backup[:]:
您还可以从类中删除init方法:

class GraphException(Exception):
    pass