我需要计算其值由以下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)。
我试着考虑某种广泛的第一次搜索,但我不能。
编辑:更多信息
答案 0 :(得分:5)
这是一个粗略的想法。但首先,一些假设:1。无向图2.恒定顶点计数
您的图表不断变化。因此,您需要有效地更新邻居(边缘)和第二邻居的数量。第一个是微不足道的,所以让我们看看第二个邻居。
Per @ Patrick的建议,让我们使用A^2
,让我们看看如何有效地更新它,而不必每次都重新计算它。 A^2_ij
是从i
到j
的长度为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
的行BA
是j
的行A
,而j
的行BA
是行i
A
,其余为零。再说一次,计算速度很快。删除边缘将类似。
你只需要第二个邻居的 count ,所以不用计算每一步有多少非零非对角线条A^2
,而是可以计算一些额外的工作量当您添加A^2
时,AB + BA
中非零条目的数量会发生多少变化。
修改强>
整个事情用不同的语言解释:
让我们跟踪矩阵M
中任意两个顶点之间的长度为2的路径数。当我们在i
和j
之间添加(删除)边时,i
与j
的所有邻居之间的长度为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本身)。我错过了什么吗?