def test_degree_disassortative_unary_binary(self): adjacency = { 1: [], # degree 1 connnected to degree 3 2: [], # degree 1 connected to degree 3 3: [3, 1, 2], # degree 4 connected to degree 1 twice 4: [], # 1 -> 3 5: [], # 1 -> 3 6: [4, 5, 7], # 3 -> 1, 1, 2 7: [], # 2 -> 3, 4 8: [7, 9, 10, 11], # 4 -> 2, 1, 1, 1 9: [], # 1 -> 4 10: [], # 1 -> 4 11: [] # 1 -> 4 } edge_list = adjacency_to_edge_list(adjacency) reader = GraphReader(edge_list=edge_list) double_adjacency = reader.double_adjacency() computed_assortativity = self.assortativity.compute_degree_assortativity( double_adjacency) # this is the expected input format for networkx vertex_ids = adjacency.keys() edge_list = adjacency_to_edge_list(adjacency) networkx_graph = nx.Graph() # using undirected graphs networkx_graph.add_nodes_from(vertex_ids) networkx_graph.add_edges_from(edge_list) correct_assortativity = nx.degree_assortativity_coefficient( networkx_graph) np.testing.assert_approx_equal(computed_assortativity, correct_assortativity, err_msg="")
def test_double_adjacency_binary(self): edge_list = np.array([ [4, 5], [4, 6], [5, 6], [7, 8], [7, 9], [7, 10], [8, 9], [8, 10], [9, 10] ]) vertices = list(range(1, 11)) correct_double_adjacency = { 1: set(), 2: set(), 3: set(), 4: {5, 6}, 5: {4, 6}, 6: {4, 5}, 7: {8, 9, 10}, 8: {7, 9, 10}, 9: {7, 8, 10}, 10: {7, 8, 9}, } reader = GraphReader(edge_list=edge_list) reader.add_vertices(vertices) # some vertices don't have edges double_adjacency = reader.double_adjacency() self.assertDictEqual(correct_double_adjacency, double_adjacency)
def test_degree_assortativity_fully_assortative_unary_binary(self): adjacency = { 1: [1], 2: [2], 3: [3], 4: [4, 5, 6], # with self-edge 5: [5, 6], # with self-edge 6: [6], # with self-edge 7: [8, 9, 10], 8: [9, 10], 9: [10], 10: [] } edge_list = adjacency_to_edge_list(adjacency) reader = GraphReader(edge_list=edge_list) double_adjacency = reader.double_adjacency() computed_assortativity = self.assortativity.compute_degree_assortativity( double_adjacency) # this is the expected input format for networkx vertex_ids = adjacency.keys() edge_list = adjacency_to_edge_list(adjacency) networkx_graph = nx.Graph() # using undirected graphs networkx_graph.add_nodes_from(vertex_ids) networkx_graph.add_edges_from(edge_list) correct_assortativity = nx.degree_assortativity_coefficient( networkx_graph) np.testing.assert_approx_equal(computed_assortativity, correct_assortativity, err_msg="")
def test_transitivity_dissortative_network_binary(self): adjacency = { 1: [], # degree 1 connnected to degree 2 2: [], # degree 1 connected to degree 2 3: [1, 2], # degree 2 connected to degree 1 twice 4: [], # 1 -> 3 5: [], # 1 -> 3 6: [4, 5, 7], # 3 -> 1, 1, 2 7: [], # 2 -> 3, 4 8: [7, 9, 10], # 4 -> 2, 1, 1, 1 9: [10], # 1 -> 4 10: [], # 1 -> 4 } edge_list = adjacency_to_edge_list(adjacency) reader = GraphReader(edge_list=edge_list) double_adjacency = reader.double_adjacency() transitivity_measure = Transitivity(double_adjacency=double_adjacency, edge_list=reader.edge_list) computed_transitivty = transitivity_measure.get_coefficient() # this is the expected input format in networkx vertex_ids = adjacency.keys() edge_list = reader.edge_list networkx_graph = nx.Graph() # using undirected graphs networkx_graph.add_nodes_from(vertex_ids) networkx_graph.add_edges_from(edge_list) correct_transitivity = nx.transitivity(networkx_graph) np.testing.assert_approx_equal(computed_transitivty, correct_transitivity)
def test_transitivity_fully_assortative_binary(self): adjacency = { 1: [2, 3], 2: [], 3: [], 4: [5, 6], 5: [6], 6: [], 7: [8, 9, 10], 8: [9, 10], 9: [10], 10: [] } edge_list = adjacency_to_edge_list(adjacency) reader = GraphReader(edge_list=edge_list) double_adjacency = reader.double_adjacency() transitivity_measure = Transitivity(double_adjacency=double_adjacency, edge_list=reader.edge_list) computed_transitivty = transitivity_measure.get_coefficient() # this is the expected input format in networkx vertex_ids = adjacency.keys() edge_list = reader.edge_list networkx_graph = nx.Graph() # using undirected graphs networkx_graph.add_nodes_from(vertex_ids) networkx_graph.add_edges_from(edge_list) correct_transitivity = nx.transitivity(networkx_graph) np.testing.assert_approx_equal(computed_transitivty, correct_transitivity)
def test_directed_edge_deduplication(self): edge_list = np.array([ [4, 5], [5, 4], [4, 6], [6, 4], [5, 6], [6, 5], [7, 8], [7, 9], [9, 7], [7, 10], [10, 7], [8, 9], [9, 8], [8, 10], [9, 10], [10, 9] ]) correct_edge_list = np.array([ [4, 5], [4, 6], [5, 6], [7, 8], [7, 9], [7, 10], [8, 9], [8, 10], [9, 10] ]) reader = GraphReader(edge_list=edge_list, deduplicate_directed_edges=True) reader_edge_list = reader.edge_list # hard to test for correctness due to non deterministic edge reductions, just check shape match np.testing.assert_equal(correct_edge_list.shape, reader_edge_list.shape)
def test_transitivity_unary_binary_ignores_unary(self): """ The concept of "transitivity" or "triangles" isn't definable when one edge is a self-edge, ie. the "triangle" is effectively composed of only two vertices A and B. We gain no information by saying "A --- A, and A -- B, so A -- B with likelihood x" (cf. "A -- B, B -- C, so A -- C with likelihood y"). So choosing to ignore self-edges/loops, when measuring transitivity :return: """ adjacency = { 1: [], 2: [], 3: [1, 2, 3], # loop 4: [4], # loop 5: [5], # loop 6: [4, 5, 7], 7: [], 8: [7, 9, 10], 9: [10], 10: [], } edge_list = adjacency_to_edge_list(adjacency) reader = GraphReader(edge_list=edge_list) double_adjacency = reader.double_adjacency() transitivity_measure = Transitivity(double_adjacency=double_adjacency, edge_list=reader.edge_list) computed_transitivty = transitivity_measure.get_coefficient() # this is the expected input format in networkx vertex_ids = adjacency.keys() edge_list = reader.edge_list networkx_graph = nx.Graph() # using undirected graphs networkx_graph.add_nodes_from(vertex_ids) networkx_graph.add_edges_from(edge_list) # networkx does ignore loops in transitivity calculations, safe to use as a reference again correct_transitivity = nx.transitivity(networkx_graph) np.testing.assert_approx_equal(computed_transitivty, correct_transitivity)
def test_test(self): adjacency = { 1: [2, 3], 2: [], 3: [4], 4: [], 5: [], 6: [4, 5, 7], 7: [8], 8: [9, 10], 9: [10], 10: [] } edge_list = adjacency_to_edge_list(adjacency) reader = GraphReader(edge_list=edge_list) double_adjacency = reader.double_adjacency() computed_assortativity = self.assortativity.compute_degree_assortativity( double_adjacency) # this is the expected input format in networkx vertex_ids = adjacency.keys() edge_list = adjacency_to_edge_list(adjacency) networkx_graph = nx.Graph() # using undirected graphs networkx_graph.add_nodes_from(vertex_ids) networkx_graph.add_edges_from(edge_list) correct_assortativity = nx.degree_assortativity_coefficient( networkx_graph) np.testing.assert_approx_equal( computed_assortativity, correct_assortativity, err_msg= "Assortativity score mismatch in a binary graph without self-edges, that should be fully assortative" )
def test_undirected_edge_no_deduplication_flag(self): """ Not deduplicating if the the edge list file isknown to be undirected will save time on large graphs """ edge_list = np.array([ [4, 5], [4, 6], [5, 6], [7, 8], [7, 9], [7, 10], [8, 9], [8, 10], [9, 10] ]) reader = GraphReader(edge_list=edge_list, deduplicate_directed_edges=False) reader_edge_list = reader.edge_list np.testing.assert_array_almost_equal(edge_list.shape, reader_edge_list.shape)
def test_directed_edge_deduplication_from_file(self): edge_list = np.array([ [4, 5], [5, 4], [4, 6], [6, 4], [5, 6], [7, 8], [8, 7], [7, 9], [7, 10], [10, 7], [8, 9], [9, 8], [10, 8], [9, 10], [10, 9] ]) edge_list_file = "test_edge_list_file.txt" with open(edge_list_file, 'w') as f: for (start, end) in edge_list: f.write("{0} {1}\n".format(start, end)) correct_edge_list = np.array([ [4, 5], [4, 6], [5, 6], [7, 8], [7, 9], [7, 10], [8, 9], [8, 10], [9, 10] ]) reader = GraphReader(edge_list_file=edge_list_file, deduplicate_directed_edges=True) reader_edge_list = reader.edge_list # hard to test for correctness due to non deterministic edge reductions, just check shape match np.testing.assert_equal(correct_edge_list.shape, reader_edge_list.shape) os.remove(edge_list_file)
parser.add_argument('-b', dest='n_buckets', type=int, help='Number of buckets', nargs='?', default=32) args = parser.parse_args() print("Number of nodes: ", args.n_nodes) n_nodes = args.n_nodes n_buckets = args.n_buckets filename = '../data/airport_graph.txt' reader = GraphReader(path=filename, is_undirected=True) graph = reader.read_graph() start = time.time() print("\nStart the HyperBall algorithm\n") hyperball = CentralityHyperBall(graph=graph, num_buckets=n_buckets) hyperball.compute_hyper_balls() ids = [el for el in range(n_nodes)] for idx in ids: node = graph.get_node(id=idx) print("Node {} Closeness: ".format(idx), hyperball.calculate_closeness(node)) print("Node {} Lin: ".format(idx), hyperball.calculate_lin(node))
required=True, help="Input tab-separated edge list, comments with # are ignored ") parser.add_argument( "--subsample", type=float, required=False, default=1.0, help= "1/multiplier of graph vertices to sample when measuring (default 1.0 -- ex: use 2 to sample 50% of nodes)" ) args = parser.parse_args() graph_file = args.graph subsample = args.subsample graph_reader = GraphReader(edge_list_file=graph_file) if subsample != 1.0: vertices = graph_reader.vertices sub_vertices = np.random.choice(list(vertices), int(len(vertices) / subsample), replace=False) print("Reduced graph from {1} to {0} vertices".format( len(sub_vertices), len(vertices))) graph_reader = graph_reader.subgraph(sub_vertices) double_adjacency = graph_reader.double_adjacency() # density edges = graph_reader.num_edges() vertices = graph_reader.num_vertices() density = edges / (vertices**2) print("Graph density: {0}".format(density))