NetworkX多方向图可能吗?

时间:2013-12-18 06:42:18

标签: python algorithm csv graph networkx

我有一个网络,我正试图找出最好的图形表示。我不是图形理论家,而是生物学家,所以请原谅我缺乏技术性。

目前,网络可以被认为如下:“n”个网络层,每个层在节点之间保持不同的边缘集。每个边都是定向的,并且具有与之相关的概率,但该概率属性直到稍后才被使用。每个图层作为单独的图形存储为CSV文件,位于邻接列表表示中。

使用邻接列表表示,我有一个“摘要”层,其中我压缩所有“n”层,每层为每个节点之间的权重提供“+1”值。这当前存储为单独的图形,作为CSV文件,存储在邻接列表表示中。

如果在一对节点之间存在“n”个边缘,则在摘要层中,边缘的权重为“n”;在任何一对节点之间只能有“n”或更少的边。

我还有一个“全全”图层,它只包含权重为“n”的边。同样,当前存储为CSV文件,在邻接列表表示中。

最后,我有一个“最可能完全唯一”的图层。在这一层中,概率起作用。对于每个“全部”层边缘,我乘以与n个边缘相关的所有概率(回想一下:“完整”层是“n”边缘的总和,每个边缘都有概率)。

在我对这个网络的分析中,有时能够在任何“n”层和“摘要”层之间切换。但是,最方便的最小存储格式(即没有预先计算任何东西)是将各个边缘存储为一个表格(如下图所示):

|Node 1 | Node 2 | Layer 1 Weight | Layer 2 Weight | ... | Layer n Weight |
|-------|--------|----------------|----------------|-----|----------------|
|  x    |   y    |   0.99         |       1.00     | ... |       1.00     |
|  x    |   z    |   0.98         |       1.00     | ... |       0.97     |
|  y    |   z    |   0 (no edge)  |       1.00     | ... |       1.00     |

我说这种格式很方便,因为我能够很容易地生成这样的表格。

所以这是我的问题:在NetworkX中是否可以存储这样的图形(多层,指向每一层)?如果有可能,那么我想能够编写函数来实时计算“摘要”图,“完全”图形和“最可能完全”图形,因为它们是彼此的子集。我还可以想象编写计算其他图形的函数,例如图形,它还将多个边缘的互补集合并入到没有完整边缘进入每个节点的节点中。

然而,检查NetworkX文档,我找不到类似我正在寻找的东西。我能找到的最好的是“多图”,它允许节点之间有多条边,但每条边都必须是无向的。我在这里错过了什么吗?

此外,是否有更好的代表我想要实现的目标?同样,我在这里缺乏图论的经验,所以我可能会遗漏一些东西。非常感谢(提前)给每个需要时间回应的人!

2 个答案:

答案 0 :(得分:6)

NetworkX中有一个MultiDiGraph()对象可能适用于您的情况。 您可以存储多个有向边,每个边都有任意属性。 节点也可以具有任意属性。

In [1]: import networkx as nx

In [2]: G = nx.MultiDiGraph()

In [3]: G.add_edge(1,2,color='green')

In [4]: G.add_edge(1,2,color='red')

In [5]: G.edges(data=True)
Out[5]: [(1, 2, {'color': 'green'}), (1, 2, {'color': 'red'})]

In [6]: G.node[1]['layer1']=17

In [7]: G.node[1]['layer2']=42

In [8]: G.nodes(data=True)
Out[8]: [(1, {'layer1': 17, 'layer2': 42}), (2, {})]

有一些辅助函数可以获取和设置可能有用的节点属性,例如

In [9]: nx.get_node_attributes(G,'layer1')
Out[9]: {1: 17}

答案 1 :(得分:0)

在networkx中,边缘有一个“权重”属性,实际上权重可以是任何对象。因此,您可以让权重成为存储每个层中所有概率值的列表。即:weight = [.99, .57, .0, .89]

问题是如何定义两个节点之间的边缘。只是有一个大于零的概率或有一个阈值。你可以编写像sum([ 1 for i in weight if i > 0 ])这样的代码  或sum([ 1 for i in weight if i > threshold ]) 如果你需要概率,只需用i替换1,如sum([ i for i in weight if i > ..])