如果我想在无向网络中最大化隔离节点的数量,我想知道应该删除哪个节点?
例如在下面的R脚本中,如果我删除1个节点和H&节点,我希望结果为H.如果我删除2个节点,等等......
library(igraph)
graph <- make_graph( ~ A-B-C-D-A, E-A:B:C:D,
G-H-I,
K-L-M-N-K, O-K:L:M:N,
P-Q-R-S-P,
C-I, L-T, O-T, M-S,
C-P, C-L, I-U-V,V-H,U-H,H-W)
plot(graph)
感谢您的帮助。
答案 0 :(得分:1)
您需要执行以下操作:
计算每个节点的k核心(在python绑定中称为Graph.coreness,不知道R)。
找到具有k-coreness 2的节点,该节点连接到具有k-coreness 1的最大节点数。
你的反例是现场,所以我使用蛮力(在这种情况下仍然是线性时间)。 这是一个可以优化的强力python实现(只在具有k-coreness 1的节点上循环),但它在线性时间内完成,即使你不知道python也应该可以访问。
import numpy as np
import igraph
def maximise_damage(graph):
coreness = graph.coreness()
# find number of leaves for each node
n = graph.vcount()
number_of_leaves = np.zeros((n))
for ii in range(n):
if coreness[ii] == 1:
neighbour = graph.neighbors(ii) # list of length 1
number_of_leaves[neighbour] += 1
# rank nodes by number of leaves
order = np.argsort(number_of_leaves)
# reverse order such that the first element has the most leaves
order = order[::-1]
return order, number_of_leaves[order]
刚刚意识到,对于您希望一次删除多个节点的情况,这通常不起作用。但我认为一般方法仍然可行 - 我会再考虑一下。
我们走了;仍然线性。您需要稍微处理输出 - 某些解决方案少于您要删除的节点数,然后您必须将它们组合在一起。
import numpy as np
import igraph
def maximise_damage(graph, delete=1):
# get vulnerability
# nodes are vulnerable if their degree count is lower
# than the number of nodes that we want to delete
vulnerability = np.array(graph.degree())
# create a hash table to keep track of all combinations of nodes to delete
combinations = dict()
# loop over vulnerable nodes
for ii in np.where(vulnerability <= delete)[0]:
# find neighbours of vulnerable nodes and
# count the number of vulnerable nodes for that combination
neighbours = tuple(graph.neighbors(ii))
if neighbours in combinations:
combinations[neighbours] += 1
else:
combinations[neighbours] = 1
# determine rank of combinations by number of vulnerable nodes dangling from them
combinations, counts = combinations.keys(), combinations.values()
# TODO:
# some solutions will contain less nodes than the number of nodes that we want to delete;
# combine these solutions
return combinations, counts