在Python w / networkX中高效存储和使用大量图表,目的是在图表中进行推理?

时间:2015-01-09 22:14:22

标签: python graph networkx inference

目标如下:我有一组节点,大小为N,我想要

  • 生成(作为一个可迭代的)一组所有可能的有向图(大概使用networkx.DiGraph()和numpy.arange(0,N))(编辑:澄清 - 这是一个非常大量的图表甚至小N,所以需要一些可迭代的结构,允许集合动态构建
  • 根据满足某些条件(例如,存在从节点0到节点N-1的完整路径)过滤这组图表。
  • 存储与每条边相关的参数值
  • 在已过滤的图形集中计算函数,同时考虑这些函数中与边缘相关的参数值,而无需同时在内存中包含所有图形(因为如果没有并行化,这将非常繁琐,而且我不会#39;知道如何处理并行化)

似乎有很多关于有效处理具有许多节点和边缘的图形(即大图)的讨论,但很少讨论如何有效地同时处理多个图形(< strong> large 设置图表),其中每个图表都不会超过系统。

编辑:理想情况下,这也适用于pandas和numpy数组,但我非常确定上述任何解决方案也可以用于解决这些问题,因为从根本上说,networkX正在使用字典词典。< / p>

1 个答案:

答案 0 :(得分:3)

您写道,您希望生成具有N个节点的所有可能的有向图。不幸的是,即使是小N,这也是不可行的。

给定一组N个节点,可能的无向边数为N(N-1)/2。我们可以通过选择这些边的子集来定义图。有2^(N*(N-1)/2)个可能的子集,这意味着在N个节点上确实存在许多可能的无向图。

假设N=10。这些节点上大概有3.5 * 10^13个可能的图表。如果你每秒可以处理一百万个图形,那么你需要大约10^7秒来处理所有的图形。这大约是一年。

这只是无向图。有更多有向图。对于N个节点,有2^(N*(N-1))个有向图。这是一张表格,展示了这种情况有多快。 |V|是节点数:

|V|   Number of Digraphs
===   ==================
1     1
2     4
3     64
4     4096
5     1048576
6     1073741824
7     4398046511104
8     72057594037927936
9     4722366482869645213696

如果你真的喜欢这样做,下面是python生成器,它会懒惰地枚举节点集上的图形:

from itertools import chain
import networkx as nx

def power_set(iterable):
    """Return an iterator over the power set of the finite iterable."""
    s = list(iterable)
    return chain.from_iterable(combinations(s, n) for n in xrange(len(s) + 1))

def enumerate_graphs(nodes):
    # create a list of possible edges
    possible_edges = list(combinations(nodes, 2))

    # create a graph for each possible set of edges
    for edge_set in power_set(possible_edges):
        g = nx.Graph()
        g.add_nodes_from(nodes)
        g.add_edges_from(edge_set)
        yield g

def enumerate_digraphs(nodes):
    # create a list of possible edges
    possible_edges = list(combinations(nodes, 2))

    # generate each edge set
    for edge_set in power_set(possible_edges):
        # for each set of `M` edges there are `M^2` directed graphs
        for swaps in power_set(xrange(len(edge_set))):
            directed_edge_set = list(edge_set)
            for swap in swaps:
                u,v = directed_edge_set[swap]
                directed_edge_set[swap] = v,u
            g = nx.DiGraph()
            g.add_nodes_from(nodes)
            g.add_edges_from(directed_edge_set)
            yield g

然后我们可以这样绘制所有有向图:

nodes = ("apples", "pears", "oranges")

digraphs = list(enumerate_digraphs(nodes))
layout = nx.random_layout(digraphs[0])

plt.figure(figsize=(20,30))
for i,g in enumerate(digraphs):
    plt.subplot(6,5,i+1)
    nx.draw_networkx(g, pos=layout)
    plt.gca().get_xaxis().set_visible(False)
    plt.gca().get_yaxis().set_visible(False)

Enumeration of digraphs