我有以下代码:
import networkx
def reverse_graph(g):
reversed = networkx.DiGraph()
for e in g.edges():
reversed.add_edge(e[1], e[0])
return reversed
g = networkx.DiGraph()
for i in range(500000):
g.add_edge(i, i+1)
g2 = g.reverse()
g3 = reverse_graph(g)
根据我的线型分析器,我花费更多时间使用networkx
来反转图形(他们的反向花费了大约21秒,我的大约花了7秒)。在这个简单的情况下,开销似乎很高,而且在其他代码中,对于更复杂的对象,它的情况更糟。在networkx
我不知道的情况下是否发生了一些事情?这似乎应该是一个相对便宜的功能。
供参考,以下是reverse
函数
编辑:我还尝试以相反的方式运行实现(即我的第一个),以确保在创建他们的时候没有缓存发生。我的速度仍然快得多
答案 0 :(得分:2)
The source code for the reverse method看起来像这样:
def reverse(self, copy=True):
"""Return the reverse of the graph.
The reverse is a graph with the same nodes and edges
but with the directions of the edges reversed.
Parameters
----------
copy : bool optional (default=True)
If True, return a new DiGraph holding the reversed edges.
If False, reverse the reverse graph is created using
the original graph (this changes the original graph).
"""
if copy:
H = self.__class__(name="Reverse of (%s)"%self.name)
H.add_nodes_from(self)
H.add_edges_from( (v,u,deepcopy(d)) for u,v,d
in self.edges(data=True) )
H.graph=deepcopy(self.graph)
H.node=deepcopy(self.node)
else:
self.pred,self.succ=self.succ,self.pred
self.adj=self.succ
H=self
return H
因此默认情况下,当copy=True
时,不仅边缘节点被反转,
但也可以对任何边缘数据进行深度复制。然后图形属性(保持在
self.graph
)被深度复制,然后节点本身被深度复制。
这是reverse_graph
没有做的很多复制。
如果您没有对所有内容进行深度检查,则修改g3
可能会影响g
。
如果您不需要深入检查所有内容,(如果可以接受变异g
那么
g.reverse(copy=False)
甚至比
更快g3 = reverse_graph(g)
In [108]: %timeit g.reverse(copy=False)
1000000 loops, best of 3: 359 ns per loop
In [95]: %timeit reverse_graph(g)
1 loops, best of 3: 1.32 s per loop
In [96]: %timeit g.reverse()
1 loops, best of 3: 4.98 s per loop