python图的表示_在Python中表示图形(数据结构)

即使这是一个有点老的问题,我想我会给任何绊倒这个的实际答案。

让我们假设你得到你的连接的输入数据作为元组的列表,如:

[('A', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('E', 'F'), ('F', 'C')]

我发现对Python中的图形最有用和最有效的数据结构是一组字典。这将是我们的Graph类的基础结构。您还必须知道这些连接是弧(定向,单向连接)还是边缘(无向,连接两种方式)。我们将通过向Graph .__ init__方法添加一个有向参数来处理它。我们还将添加一些其他有用的方法。

from collections import defaultdict

class Graph(object):

""" Graph data structure, undirected by default. """

def __init__(self, connections, directed=False):

self._graph = defaultdict(set)

self._directed = directed

self.add_connections(connections)

def add_connections(self, connections):

""" Add connections (list of tuple pairs) to graph """

for node1, node2 in connections:

self.add(node1, node2)

def add(self, node1, node2):

""" Add connection between node1 and node2 """

self._graph[node1].add(node2)

if not self._directed:

self._graph[node2].add(node1)

def remove(self, node):

""" Remove all references to node """

for n, cxns in self._graph.iteritems():

try:

cxns.remove(node)

except KeyError:

pass

try:

del self._graph[node]

except KeyError:

pass

def is_connected(self, node1, node2):

""" Is node1 directly connected to node2 """

return node1 in self._graph and node2 in self._graph[node1]

def find_path(self, node1, node2, path=[]):

""" Find any path between node1 and node2 (may not be shortest) """

path = path + [node1]

if node1 == node2:

return path

if node1 not in self._graph:

return None

for node in self._graph[node1]:

if node not in path:

new_path = self.find_path(node, node2, path)

if new_path:

return new_path

return None

def __str__(self):

return '{}({})'.format(self.__class__.__name__, dict(self._graph))

我将把它作为一个“为读者练习”创建一个find_shortest_path和其他方法。

让我们看看这个在行动,虽然…

>>> connections = [('A', 'B'), ('B', 'C'), ('B', 'D'),

('C', 'D'), ('E', 'F'), ('F', 'C')]

>>> g = Graph(connections, directed=True)

>>> pprint(g._graph)

{'A': {'B'},

'B': {'D', 'C'},

'C': {'D'},

'E': {'F'},

'F': {'C'}}

>>> g = Graph(connections) # undirected

>>> pprint(g._graph)

{'A': {'B'},

'B': {'D', 'A', 'C'},

'C': {'D', 'F', 'B'},

'D': {'C', 'B'},

'E': {'F'},

'F': {'E', 'C'}}

>>> g.add('E', 'D')

>>> pprint(g._graph)

{'A': {'B'},

'B': {'D', 'A', 'C'},

'C': {'D', 'F', 'B'},

'D': {'C', 'E', 'B'},

'E': {'D', 'F'},

'F': {'E', 'C'}}

>>> g.remove('A')

>>> pprint(g._graph)

{'B': {'D', 'C'},

'C': {'D', 'F', 'B'},

'D': {'C', 'E', 'B'},

'E': {'D', 'F'},

'F': {'E', 'C'}}

>>> g.add('G', 'B')

>>> pprint(g._graph)

{'B': {'D', 'G', 'C'},

'C': {'D', 'F', 'B'},

'D': {'C', 'E', 'B'},

'E': {'D', 'F'},

'F': {'E', 'C'},

'G': {'B'}}

>>> g.find_path('G', 'E')

['G', 'B', 'D', 'C', 'F', 'E']

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值