简体   繁体   English

在python中实现有向图

[英]Implementing a directed graph in python

I read Python Patterns - Implementing Graphs .我阅读了Python 模式 - 实现图形 However this implementation is inefficient for getting the edges that point to a node.然而,这种实现对于获取指向节点的边是低效的。

In other languages a common solution is using a two-dimensional array, but to do this in Python would require a list of lists.在其他语言中,一个常见的解决方案是使用二维数组,但在 Python 中这样做需要一个列表列表。 This does not seem pythonic.这似乎不是pythonic。

What is an implementation of a directed graph in python where finding all the nodes with edges to and from a node (as two separate lists) is fast?什么是 python 中的有向图的实现,其中找到所有节点的边进出一个节点(作为两个单独的列表)是快速的?

Another library you could use is NetworkX .您可以使用的另一个库是NetworkX It provides a implementation of directed graphs that provide functions to get incomming edges DiGraph.in_edges() and outgoing edges DiGraph.out_edges() for arbitrary sets of nodes.它提供了有向图的实现,提供了获取任意节点集的DiGraph.out_edges()DiGraph.in_edges()和传出边DiGraph.out_edges()函数。 Usage samples are provided in the linked documentation, but unfortunately I didn't see any details about efficiency or run time.链接文档中提供了使用示例,但不幸的是,我没有看到有关效率或运行时间的任何详细信息。

Scipy offers efficient Graph routines if computational efficiency or scientific computing is your concern:如果您关心计算效率或科学计算,Scipy 会提供高效的 Graph 例程:

http://docs.scipy.org/doc/scipy/reference/sparse.csgraph.html http://docs.scipy.org/doc/scipy/reference/sparse.csgraph.html

This doesn't answer your graph question, but you can certainly implement a 2D list in Python without resorting to lists of lists in at least two ways:这不能回答您的图形问题,但您当然可以在 Python 中实现 2D 列表,而无需以至少两种方式求助于列表列表:

You can simply use a dictionary:您可以简单地使用字典:

import collections
t = collections.defaultdict(int)

t[0, 5] = 9
print t[0, 5]

This also has the advantage that it is sparse.这也具有稀疏性的优点。

For a fancier approach, but one requiring more work, you can use a 1d list and compute the index using the 2D coordinates along with the table's height and width.对于更高级但需要更多工作的方法,您可以使用一维列表并使用二维坐标以及表格的高度和宽度来计算索引。

class Table(object):
    def __init__(self, width, height):
        self._table = [None,] * (width * height)
        self._width = width

    def __getitem__(self, coordinate):
        if coordinate[0] >= width or coordinate[1] >= height:
            raise IndexError('Index exceeded table dimensions')
        if coordinate[0] < 0 or coordinate[1] < 0:
            raise IndexError('Index must be non-negative')
        return self._table[coordinate[1] * width + coordinate[0]]

    def __setitem__(self, coordinate, value):
        if coordinate[0] >= width or coordinate[1] >= height:
            raise IndexError('Index exceeded table dimensions')
        if coordinate[0] < 0 or coordinate[1] < 0:
            raise IndexError('Index must be non-negative')
        self._table[coordinate[1] * width + coordinate[0]] = value


t = Table(10,10)
t[0, 5] = 9
print t[0, 5]

networkx is definitely the most popular Python graph library. networkx绝对是最流行的 Python 图形库。 It is well documented, has a great API, and is performant.它有很好的文档记录,有一个很棒的 AP​​I,并且是高性能的。 Suppose you have the following graph:假设您有以下图表:

在此处输入图片说明

Here's how to create this graph and calculate all the edges that are pointing to node e:以下是创建此图并计算指向节点 e 的所有边的方法:

import networkx as nx

graph = nx.DiGraph()
graph.add_edges_from([("root", "a"), ("a", "b"), ("a", "e"), ("b", "c"), ("b", "d"), ("d", "e")])
print(graph.in_edges("e")) # => [('a', 'e'), ('d', 'e')]

Here's how you can calculate all the edges that node b points towards:以下是计算节点 b 指向的所有边的方法:

print(graph.out_edges("b")) # => [('b', 'c'), ('b', 'd')]

networkx is a fantastic library. networkx 是一个很棒的库。 See here for more details.请参阅此处了解更多详情。

Take a look at the Pygraph .看看Pygraph I've used it quite a bit for large directed (and undirected) graphs without memory or run-time issues, though it is all implemented in Python so a C++ wrapped implementation could be much fast.我已经将它用于没有内存或运行时问题的大型有向(和无向)图,尽管它都是在 Python 中实现的,因此 C++ 包装的实现可能会快得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM