我正在尝试实现一种返回图形边缘的方法,由邻接列表/字典表示。所以要遍历字典,首先我遍历键,然后遍历存储在相应键中的每个值。在嵌套的 for 循环中,我有一个条件,如果特定的边,比如说 (a,b) 不在边的集合中,那么将它添加到集合中——否则通过。在我第一次运行时,该方法采用了相同的边——也就是说,在边的集合中,有 (a,b) 和 (b,a)。class Graph(): def __init__(self, grph={}): self.graph = grph def get_vertices(self): for keys in self.graph: yield keys def get_edges(self): edges = set() for key in self.graph: for adj_node in self.graph[key]: if (key, adj_node) not in edges: edge = (key, adj_node) edges.add(edge) else: pass return edgesdef main(): graph1 = { 'A': ['B','C','D'], 'B': ['A','E'], 'C': ['A', 'D'], 'D': ['A', 'C'], 'E': ['B'], } graph_one = Graph(graph1) print(list(graph_one.get_vertices())) print(graph_one.get_edges())if __name__ =='__main__': main()输出是:{('A','B'),('D','A'),('B','A'),('B','E'),('A','D') ,('D','C'),('E','B'),('C','D'),('A','C'),('C','A') }所以我所做的是,我只是改变了 if 语句:“if (adj_node, key) not in edge:”def get_edges(self): edges = set() for key in self.graph: for adj_node in self.graph[key]: if (adj_node, key) not in edges: edge = (key, adj_node) edges.add(edge) else: pass return edges现在输出是:{('C','D'),('A','B'),('E','B'),('A','C'),('A','D') }我很好奇为什么会这样,如果你们能向我解释一下,我将非常感激。提前致谢!
2 回答
饮歌长啸
TA贡献1951条经验 获得超3个赞
我认为它只需要一点点改变,试试这个:
def get_edges(self):
edges = set()
for key in self.graph:
for adj_node in self.graph[key]:
if ((key, adj_node) not in edges) and ((adj_node, key) not in edges):
edge = (key, adj_node)
edges.add(edge)
else:
pass
return edges
更新:
所以它是一个Undigraph。
是我把它搞得太复杂了。
你的方式实际上比我检查两种方式都要好。
您的代码成功的原因是set它只包含任何值的一个实例。
所以每次执行add,如果已经存在相同的元组,它就不会改变集合。
并且您已经使用if来检查相反方向的元组,因此它不会创建重复的边。
例如,当(a, b)命中if检查时,它会检查(b,a)集合中是否存在,如果存在,则通过。如果不是,则在集合中添加 (a, b),如果 (a, b) 存在,则集合不会改变,因为集合中只有一个实例。
稍后当循环到 (b, a) 时,因为 (a, b) 已经在集合中,所以if将是假的并通过。
所以通过这种方式,集合是安全的,没有重复的边。
添加回答
举报
0/150
提交
取消