def get_node_ns(graph, k=3): """ Get k nodes to attack based on the Netshield algorithm :cite`tong2010vulnerability`. :param graph: an undirected NetworkX graph :param k: number of nodes to attack :return: a list of nodes to attack """ if not scipy.sparse.issparse(graph): sparse_graph = get_sparse_graph(graph) else: sparse_graph = graph lam, u = eigsh(sparse_graph, k=1, which='LA') lam = lam[0] u = np.abs(np.real(u).flatten()) v = (2 * lam * np.ones(len(u))) * np.power(u, 2) nodes = [] for i in range(k): B = sparse_graph[:, nodes] b = B * u[nodes] score = v - 2 * b * u score[nodes] = -1 nodes.append(np.argmax(score)) return nodes
def __init__(self, graph, runs, steps, **kwargs): # TODO: efficiency improvement--store edge and node difference rather than whole graph twice self.graph_og = graph.copy() self.graph = graph self.prm = { 'runs': runs, 'steps': steps, 'seed': 1, 'max_val': 1, 'gif_animation': False, 'gif_snaps': False, 'plot_transition': False, 'edge_style': None, 'node_style': None, 'fa_iter': 200 } self.sim_info = defaultdict() self.sparse_graph = get_sparse_graph(self.graph) if self.prm['seed'] is not None: random.seed(self.prm['seed']) np.random.seed(self.prm['seed'])