简体   繁体   English

无向图中节点排序算法的错误

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

The idea is to construct a list of the nodes in the undirected graph ordered by their degrees. 想法是在无向图中按度数顺序构造节点列表。 Graph is given in the form {node: (set of its neighbours) for node in the graph} 图形以{节点:(其邻居的集合)表示图中节点的形式}给出

The code raises KeyError exception at the line "graph[neighbor].remove(node)". 该代码在“ graph [neighbor] .remove(node)”行引发KeyError异常。 It seems like the node have already been deleted from the set, but I don't see where. 似乎该节点已从集合中删除,但我看不到位置。

Can anyone please point out at the mistake? 有人可以指出这个错误吗?

Edit: This list of nodes is used in the simulation of the targeted attack in order of values of nodes in the graph. 编辑:此节点列表按图中节点值的顺序用于模拟目标攻击。 So, after an attack on the node with the biggest degree, it is removed from the node, and the degrees of the remaining nodes should be recalculated accordingly. 因此,在对度数最大的节点进行攻击后,会将其从节点中删除,并应相应地重新计算其余节点的度数。

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

My previous answer (now deleted) was incorrect, the issue was not in using set, but in deleting items in any sequence during iteration through the same sequence. 我以前的答案(现在已删除)是不正确的,问题不在于使用set,而是在于在通过相同序列进行迭代期间以任何顺序删除项目。

Python tutorial for version 3.1 clearly warns: 版本3.1的Python教程明确警告:

It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). 在循环中修改要迭代的序列是不安全的(这仅适用于可变序列类型,例如列表)。 If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. 如果需要修改要遍历的列表(例如,复制选定的项目),则必须遍历一个副本。

However, tutorial for Python 3.5. 但是,适用于Python 3.5的教程。 (which I use) only advises: (我使用的)仅建议:

If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. 如果需要修改循环中要迭代的序列(例如,复制选定的项目), 建议您首先进行复制。

It appears that this operation is still very unpredictable in Python 3.5, producing different results with the same input. 看来此操作在Python 3.5中仍然是不可预测的,使用相同的输入会产生不同的结果。

From my point of view, the previous version of the tutorial is preferred to the current one. 从我的角度来看,该教程的前一版本比当前版本更可取。

@PetarPetrovic and @jdehesa, thanks for the valuable advice. @PetarPetrovic和@jdehesa,感谢您的宝贵建议。

Working solution: 工作解决方案:

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.

相关问题 生成无向图的算法,该图的路径最大程度地指向所有节点? - Algorithm to generate an undirected graph with path to all nodes with a maximum degree? 无向图的A *算法 - A* algorithm for undirected graph 制作无向图的算法 - Algorithm to make undirected graph be connected 从可能有 1,024 个节点的无向图中提取所有唯一的完整子图的最佳算法是什么? - What's the best algorithm for extracting all unique, complete subgraphs from an undirected graph of perhaps 1,024 nodes? 以最低成本遍历无向加权图的k个节点(并返回原​​点)的算法 - Algorithm to traverse k nodes of an undirected, weighted graph (and return to the origin) at the lowest cost 找到距离至少为(无向)图直径一半的任何两个节点的算法 - Algorithm to find any two nodes with distance of at least half the (undirected) graph's diameter 根据Python中的值对无向图的节点进行排序 - Sorting nodes of a undirected graph based on value in Python 连接无向图中某些节点的最短路径 - shortest path connecting certain nodes in an undirected graph 如何将无向图的节点划分为k个集合 - how to partition the nodes of an undirected graph into k sets 枚举无向/无权图的节点集 - Enumerating Sets of Nodes of an Undirected / unweighted graph
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM