簡體   English   中英

無向圖中節點排序算法的錯誤

[英]Error in the algorithm of ordering nodes in the undirected graph

想法是在無向圖中按度數順序構造節點列表。 圖形以{節點:(其鄰居的集合)表示圖中節點的形式}給出

該代碼在“ graph [neighbor] .remove(node)”行引發KeyError異常。 似乎該節點已從集合中刪除,但我看不到位置。

有人可以指出這個錯誤嗎?

編輯:此節點列表按圖中節點值的順序用於模擬目標攻擊。 因此,在對度數最大的節點進行攻擊后,會將其從節點中刪除,並應相應地重新計算其余節點的度數。

def fast_targeted_order(graph):
    """returns an orderedv list of the nodes in the graph in decreasing 
    order of their degrees"""

    number_of_nodes = len(graph)  
    # initialise a list of sets of every possible degree
    degree_sets = [set() for dummy_ind in range(number_of_nodes)]

    #group nodes in sets according to their degrees
    for node in graph:
        degree = len(graph[node])
        degree_sets[degree] |= {node}

    ordered_nodes = []
    #starting from the set of nodes with the maximal degree
    for degree in range(number_of_nodes - 1, -1, -1):

        #copy the set to avoid raising the exception "set size changed 
        during the execution
        copied_degree_set = degree_sets[degree].copy()
        while degree_sets[degree]:

            for node in copied_degree_set:
                degree_sets[degree] -= {node}
                for neighbor in graph[node]:
                    neighbor_degree = len(graph[neighbor])
                    degree_sets[neighbor_degree] -= {neighbor}
                    degree_sets[neighbor_degree - 1] |= {neighbor}
                    graph[neighbor].remove(node)

            ordered_nodes.append(node)
            graph.pop(node)

    return ordered_nodes

我以前的答案(現在已刪除)是不正確的,問題不在於使用set,而是在於在通過相同序列進行迭代期間以任何順序刪除項目。

版本3.1的Python教程明確警告:

在循環中修改要迭代的序列是不安全的(這僅適用於可變序列類型,例如列表)。 如果需要修改要遍歷的列表(例如,復制選定的項目),則必須遍歷一個副本。

但是,適用於Python 3.5的教程。 (我使用的)僅建議:

如果需要修改循環中要迭代的序列(例如,復制選定的項目), 建議您首先進行復制。

看來此操作在Python 3.5中仍然是不可預測的,使用相同的輸入會產生不同的結果。

從我的角度來看,該教程的前一版本比當前版本更可取。

@PetarPetrovic和@jdehesa,感謝您的寶貴建議。

工作解決方案:

def fast_targeted_order(ugraph):
    """
    input: undirected graph in the form {node: set of node's neighbors)
    returns an ordered list of the nodes in V in decresing order of their degrees
    """

    graph = copy_graph(ugraph)
    number_of_nodes = len(graph)

    degrees_dict = {degree: list() for degree in range(number_of_nodes)}

    for node in graph:
        degree = len(graph[node])
        degrees_dict[degree].append(node)

    ordered_degrees = OrderedDict(sorted(degrees_dict.items(), 
                                  key = lambda key_value: key_value[0],
                                  reverse = True))
    ordered_nodes = []

    for degree, nodes in ordered_degrees.items():
        nodes_copy = nodes[:]
        for node in nodes_copy:
            if node in nodes:

                for neighbor in graph[node]:
                    neighbor_degree = len(graph[neighbor])
                    ordered_degrees[neighbor_degree].remove(neighbor)
                    if neighbor_degree:
                        ordered_degrees[neighbor_degree - 1].append(neighbor)
                    graph[neighbor].remove(node)

                graph.pop(node)
                ordered_degrees[degree].remove(node)
                ordered_nodes.append(node)

    return ordered_nodes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM