为什么在Python中使用字典表示图形?

时间:2015-07-17 01:01:33

标签: python math dictionary graph set

Python没有对图表的直接支持,但很多消息来源都说它们可以用字典表示,例如。

graph = { "a" : ["c"],
          "b" : ["c", "e"],
          "c" : ["a", "b", "d", "e"],
          "d" : ["c"],
          "e" : ["c", "b"],
          "f" : []
        }

因为这是一个无向图,字典是方向映射,所以看起来真的很不合适。说graph = {'x':['y'], 'y':['x']}而不是graph = {{'x', 'y'}}真的更好吗?

3 个答案:

答案 0 :(得分:1)

将它们存储为连接使其非常容易行走:

vertex = 'x'
connected_to = graph[vertex]
second_degree_connections = {p for subset in graph[p] for p in connected_to}

尝试使用一组两元组有效地执行此操作。不是很容易,对吧?

答案 1 :(得分:1)

如果图表是无向的,则一组2元素集更适合表示它:

graph = set()

添加边缘:

>>> graph.add(frozenset(('a', 'b')))

(注意:你必须使用不可变的frozenset(),因为set()由于其可变性而不可清除)

检查边缘是否在图表中:

>>> {'b', 'a'} in graph
True

添加更多边缘:

>>> graph.add(frozenset(('a', 'c')))
>>> graph.add(frozenset(('c', 'd')))
>>> graph.add(frozenset(('d', 'e')))
>>> graph.add(frozenset(('d', 'f')))

让边缘触及'd':

>>> set(x for x in graph if 'd' in x)
{frozenset({'c', 'd'}), frozenset({'f', 'd'}), frozenset({'d', 'e'})}

但是,对于上一次操作,使用字典的表示在时间上更有效。

答案 2 :(得分:0)

无向图是一种特定类型的有向图,其中每条边(a,b)也存在(b,a)。

所以你可以实现两次存储边缘(正常和反向),但最好写一个类来保持它的一致性:

from collections import defaultdict

class UndirectedGraph:
    def __init__(self):
        self.edge = defaultdict(set)

    def add_edge(self, a, b):
        self.edge[a].add(b)
        self.edge[b].add(a)

    def remove_edge(self, a, b):
        self.edge[a].remove(b)
        self.edge[b].remove(a)

    def has_edge(self, a, b):
        return b in self.edge[a] or a in self.edge[b]

    def neighbours(self, a):
        return set(self.edge[a])

这是非常基本的,根据您要执行的操作,您可以删除某些方法,或者您可能需要添加其他方法。

>>> g=UndirectedGraph()
>>> g.add_edge('a','b')
>>> g.add_edge('a','c')
>>> g.add_edge('c','d')
>>> g.add_edge('a','d')
>>> g.remove_edge('a','d')
>>> g.has_edge('a','d')
False
>>> g.has_edge('a','c')
True
>>> g.neighbours('c')
{'a', 'd'}