[英]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.