在图表中获取下一个最近邻居的最佳方法是什么?

时间:2011-07-12 15:32:54

标签: algorithm graph breadth-first-search

我需要计算其值由以下inneficient伪python代码给出的东西:

def foo(a,b):
   tmp = 0
   for i in graph.nodes():
       for j in graph.nodes():
          tmp += c
          if (i and j are neighbors):
              tmp += a - c
          elif (i and j are next-neighbors):
              tmp += b - c
   return tmp

换句话说,给定所有节点对,foo = a *(E =边数)+ b *(EE =不是邻居但有共同邻居的对数)+ c *(N( N-1)/ 2 - EE - E)。

我试着考虑某种广泛的第一次搜索,但我不能。

编辑:更多信息

  • 图表不是静态的。我经常添加和删除边缘,所以我不能只计算一次。我必须不断更新“下一个邻居名单”。
  • 我将图形存储为邻接矩阵。

3 个答案:

答案 0 :(得分:5)

这是一个粗略的想法。但首先,一些假设:1。无向图2.恒定顶点计数

您的图表不断变化。因此,您需要有效地更新邻居(边缘)和第二邻居的数量。第一个是微不足道的,所以让我们看看第二个邻居。

Per @ Patrick的建议,让我们使用A^2,让我们看看如何有效地更新它,而不必每次都重新计算它。 A^2_ij是从ij的长度为2的路径的数量,请记住它也会有对角线条目,因为从顶点始终有一条长度为2的路径对自己。如果您有A^2,则可以轻松计算第二个邻居的数量,因此在图表发生变化时,请将所有A^2更新到内存中。

如何有效更新A^2

添加/删除边缘时,可以通过只有两个条目的矩阵A更改B。假设我们正在添加(不删除)边缘。然后是(A+B)^2 = A^2 + AB + BA + B^2

假设添加的边是(i,j)

  • B^2很简单:(B^2)_ii = (B^2)_jj = 1,其余为0。
  • AB = transpose(BA)所以我们只需要计算其中一个,比如BA。事实证明,i的行BAj的行A,而j的行BA是行i A,其余为零。再说一次,计算速度很快。

删除边缘将类似。

你只需要第二个邻居的 count ,所以不用计算每一步有多少非零非对角线条A^2,而是可以计算一些额外的工作量当您添加A^2时,AB + BA中非零条目的数量会发生多少变化。

修改

整个事情用不同的语言解释:

让我们跟踪矩阵M中任意两个顶点之间的长度为2的路径数。当我们在ij之间添加(删除)边时,ij的所有邻居之间的长度为2的路径数将增加(减少)1以及j以及i的所有邻居,因此M在每次更改图表后O(n)内都很容易更新。

答案 1 :(得分:1)

如果您将图表存储在Adjacency Matrix A中,则可以通过将矩阵与其自身(A^2)相乘来找到所有长度为2的路径,如果这是您要求的。

这将花费O(n ^ 3)时间进行预处理,但随后您可以在恒定时间内对邻居和“下一个邻居”执行查找。

答案 2 :(得分:0)

获取节点的邻居列表(node_main)。访问每个邻居。将其每个邻居添加到邻居邻居列表,除非它是node_main的邻居之一(或者是node_main本身)。我错过了什么吗?