表示图形的简单方法是使用以下形式的数据结构:
{1:[2,3],
2:[1,3],
3:[1,2]}
此字典中的键是节点,并且边缘由它们连接的其他节点的列表表示。如果链接不对称,该数据结构也可以很容易地表示有向图:
{1:[2],
2:[3],
3:[1]}
我对图理论知之甚少,所以我要提出的建议可能已经有了一个简单的解决方案,但我不知道该寻找什么。我遇到的情况是图形有些指向,取决于您所在的节点和您来自的节点。为了说明,我有一张图:
想象一下你在卡丁车中沿着边缘A加速,而在节点1处,你将左边悬挂在边缘B上。由于你走得这么快,当你击中节点3时,你被迫继续前行F.但是,如果你来自边缘F,你将能够继续前进到边缘E或B.很明显,节点3连接到1和2,但是否可以从该节点到达它们取决于你来自哪个方向。
我想知道是否有一个图论理论概念描述了这个和/或是否有一个简单的数据结构来描述它。虽然我将在python中编写代码,但我会从任何合理适用的语言中获取建议。
编辑: 我试图发布一张图片,但是我不确定它是否会显示出来。如果它不是image
的链接编辑2: 我应该很清楚。发布的图像是完整图形的一部分,其中屏幕上有更多节点来自A,D和F.
答案 0 :(得分:7)
答案 1 :(得分:1)
您可以将其实现为包含节点和边的基本图形。在每个节点中,存储边缘列表。对于每个边缘,存储从“入口”边缘到有效出口边缘的映射。
我应该指出,您发布的图像不是图形,因为A,F和D不连接到任何节点(除非它们只是在屏幕外)。
答案 2 :(得分:1)
将图表表示为字符串映射到字符串到集合的映射。
更清楚一点,在python中你会得到:
graph = {
'A': {
'B': set(['C', 'D', ...]),
'E': set(['F']),
},
...
}
如果A
映射中的条目B
包含密钥B
,则A
和graph
之间存在边缘。
如果我们来自的节点包含在由graph['A']['B']
映射的集合中,则可以遍历此边缘。
以下python类实现了此规范(您可以在this gist上找到注释版本):
class Graph(object):
def __init__(self):
self.nodes = {}
def addEdge(self, (node1, comingFrom1), (node2, comingFrom2)):
self.nodes.setdefault(node1, {})[node2] = comingFrom1
self.nodes.setdefault(node2, {})[node1] = comingFrom2
def isEdge(self, comingFrom, passingBy, goingTo):
try:
return comingFrom in self.nodes[passingBy][goingTo]
except KeyError:
return False
def destinations(self, comingFrom, passingBy):
dests = set()
try:
for node, directions in self.nodes[passingBy].iteritems():
if comingFrom in directions:
dests.add(node)
except KeyError:
pass
return dests
def sources(self, passingBy, goingTo):
return self.destinations(goingTo, passingBy)
这个类可以像这样使用:
>>> graph = Graph()
>>> graph.addEdge(('0', set([ ])), ('1', set(['3', '2'])))
>>> graph.addEdge(('1', set(['0' ])), ('3', set(['4' ])))
>>> graph.addEdge(('1', set(['0' ])), ('2', set(['5' ])))
>>> graph.addEdge(('3', set(['1', '2'])), ('4', set([ ])))
>>> graph.addEdge(('3', set(['4' ])), ('2', set(['5' ])))
>>> graph.addEdge(('2', set(['1', '3'])), ('5', set([ ])))
>>> print graph.isEdge('0', '1', '3')
True
>>> print graph.isEdge('1', '3', '2')
False
>>> print graph.isEdge('1', '2', '5')
True
>>> print graph.isEdge('5', '2', '3')
True
>>> print graph.isEdge('3', '2', '5')
True
>>> print graph.destinations('0', '1')
set(['3', '2'])
>>> print graph.destinations('1', '3')
set(['4'])
>>> print graph.destinations('3', '4')
set([])
>>> print graph.sources('0', '1')
set([])
>>> print graph.sources('1', '3')
set(['0'])
>>> print graph.sources('3', '4')
选择的数据结构及其用法已经允许构建有向图,只需要调整addEdge
方法。