如何在某些数据结构中表示奇怪的图形

时间:2011-06-16 18:13:09

标签: python language-agnostic data-structures graph

表示图形的简单方法是使用以下形式的数据结构:

{1:[2,3],
 2:[1,3],
 3:[1,2]}

此字典中的键是节点,并且边缘由它们连接的其他节点的列表表示。如果链接不对称,该数据结构也可以很容易地表示有向图:

{1:[2],
 2:[3],
 3:[1]}

我对图理论知之甚少,所以我要提出的建议可能已经有了一个简单的解决方案,但我不知道该寻找什么。我遇到的情况是图形有些指向,取决于您所在的节点和您来自的节点。为了说明,我有一张图:

Strangely Directional Graph

想象一下你在卡丁车中沿着边缘A加速,而在节点1处,你将左边悬挂在边缘B上。由于你走得这么快,当你击中节点3时,你被迫继续前行F.但是,如果你来自边缘F,你将能够继续前进到边缘E或B.很明显,节点3连接到1和2,但是否可以从该节点到达它们取决于你来自哪个方向。

我想知道是否有一个图论理论概念描述了这个和/或是否有一个简单的数据结构来描述它。虽然我将在python中编写代码,但我会从任何合理适用的语言中获取建议。

编辑: 我试图发布一张图片,但是我不确定它是否会显示出来。如果它不是image

的链接

编辑2: 我应该很清楚。发布的图像是完整图形的一部分,其中屏幕上有更多节点来自A,D和F.

3 个答案:

答案 0 :(得分:7)

这可以用directed graph表示。

图表中的节点可以表示为图中的两个节点。 将节点视为代表街道特定边上的位置 - 边缘就像入站和出站车道。

enter image description here

答案 1 :(得分:1)

您可以将其实现为包含节点和边的基本图形。在每个节点中,存储边缘列表。对于每个边缘,存储从“入口”边缘到有效出口边缘的映射。

我应该指出,您发布的图像不是图形,因为A,F和D不连接到任何节点(除非它们只是在屏幕外)。

答案 2 :(得分:1)

将图表表示为字符串映射到字符串到集合的映射。

更清楚一点,在python中你会得到:

graph = {
    'A': {
        'B': set(['C', 'D', ...]),
        'E': set(['F']),
    },
    ...
}

如果A映射中的条目B包含密钥B,则Agraph之间存在边缘。

如果我们来自的节点包含在由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方法。