如何使用模块NetworkX大致估计计算时间

时间:2018-03-17 04:48:21

标签: python time-complexity networkx scalability

嗨我正在处理一些(抱歉含糊不清的)图表, 29,981个节点数 150,000个定向边在里面。

我正在使用模块 networkx 处理它,这在图理论家中现在被广泛使用。

我今天早上在Jupyter执行了以下脚本,但无法估计何时完成:

import netowkx as nx
import pickle

# to read the graph
with open ('/home/zachary/H{}'.format("29981"), 'rb') as fp:
    H = pickle.load(fp)     

print(list(nx.simple_cycles(H)))

我怎样才能粗略猜出这个剧本的完成时间?

我有点知道big Osmall O是什么......但通常这种理论知识在我的脑海中尚未成熟,工业上使用这些知识来计算和估计计算时间

1 个答案:

答案 0 :(得分:2)

正如NetworkX documentation中所述,simple_cycles使用Johnson的算法来查找基本周期。算法的复杂性为O((V+E).(1+C))其中

  • V是顶点数;
  • E是边数;
  • C周期数。

在您的情况V+E ~= 150,000中,假设python进程没有重载,我们可以预期运行时间为150,000.K.C

要尝试查找K的估算值,您可以使用10(V+E = 10, 100, 1000 ...)的幂来在较小的图上运行算法,以确保simple_cycles的运行时间保持成比例到(V+E)(1+C),得到K的粗略值,并根据您希望找到的周期数估算图表的运行时间。更准确地说,如果我们注意到R(V + E,C)每个实验较小图的实际运行时间,以及C0, C1, ...Cn它们各自的周期数,那么我们就可以预期

R(100,C1)  / R(10,C0)  ~= 10.K.[(1+C1) / (1+C0)]
R(1000,C1) / R(100,C0) ~= 10.K.[(1+C2) / (1+C1)]
...

如果simple_cycles运行时间没有表现出约翰逊算法的复杂性,那么有一个非算法因素会减慢/阻止计算 - 这需要进行调查。

<强>后续 这些是您提供的图表的一些调查结果。我尝试使用NetworkX库为较小的子图计算周期数,并在下面重现一些有趣的结果。每个子图的节点和边数都有计算的周期数。

\#Nodes  | \#Edges | \#Cycles (computed)
----------------------------------------
   1,000 |     186 |                17
   2,000 |     675 |                37
   3,000 |   1,460 |                72
   4,000 |   2,538 |             2,147   
   4,250 |   2,881 |         2,351,883

我在#Nodes = 4000停了下来,几分钟后我就无法得到任何结果。

让我们为每个值计算值

log10(C)/E with C = \#Cycles and E = \#Edges.

E = \#Edges | C = \#Cycles (computed) |  log(C)/E  | 
----------------------------------------------------
        186 |                      17 |     0.0067 |
        675 |                      37 |     0.0023 |
      1,460 |                      72 |     0.0013 |
      2,538 |                   2,147 |     0,0013 |
      2,881 |               2,351,883 |     0,0022 |

正如我们所看到的,至少对于G小于~2,500个边缘的子图,周期数大致遵循以下幂律

log10(C) = 0.0013.E => C = 1.003^E

经验1.003来自图表的拓扑结构(作为旁注,maximum theoretical number of cycles given the number of edges估计为1.443^E。)。

请注意,我们不知道这个常数是否与图表变大一样 - 这将是一个有趣的事情要检查,但使用的方法不同于这个蛮力的方法(我们已经有一千个)当我们达到5000个边缘时,十亿个周期。)

在这种情况下(并且仅在这种情况下),当图形变得更大到G的150,000个边时,常数不会改变,大约的周期数将是... {{1} }

=&GT;看起来你实际上正在打算算法复杂性墙。考虑到这一点,我不知道您希望选择哪种替代方案 - 可能存在非指数近似算法?

注意
为了试验~10^359的子图,我使用了以下命令 - 指定目标节点数,例如3,000个节点:

G