NetworkX是否支持多重有向图?

6

我有一个网络,正在尝试找出最佳的图表示。我不是图论专家而是生物学家,因此请原谅我的技术性不足。

目前,该网络可以被认为是:有“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文档时,我找不到任何类似于我正在寻找的内容。我能找到的最好的东西是“multigraph”,它允许节点之间有多个边,但每条边必须是无向的。我错过了什么吗?

另外,是否有更好的表示方法来实现我想要实现的内容?再次强调,我在图论方面缺乏经验,所以我可能会遗漏一些东西。非常感谢(提前)所有抽出时间回复的人!


拥有N个有向图会有什么问题? - Back2Basics
可能会起作用,但我必须保持N+3个图表(每层1到N,然后是摘要、完整和最有可能的层),并访问我感兴趣的图表。如果基础数据发生变化,我还必须更新每个图表,这可能会延长计算时间。 - ericmjl
在层之间,边的方向会改变吗? - Back2Basics
通常不会。我决定是否绘制边缘的规则是假设每个节点都是一个“源”,并找到它们的“汇点”。有时,当您将其他节点视为“源”时,到一个“汇点”的“源”也是一个“汇点”。因此,有一些成对的节点具有“双向”边缘,但我倾向于不使用该术语,因为它会减少构建图形的步骤。 - ericmjl
2个回答

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}

哇,Aric,像往常一样,你又来拯救了。感谢你的回答,出于某种原因,我就是找不到NetworkX文档中的MultiDiGraph()对象。我想这确实需要一定的正式培训才能识别这些术语。 - ericmjl

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 ]) 如果需要概率,请将1替换为i,例如:sum([ i for i in weight if i > ..])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接