diff --git a/grape/general_graph.py b/grape/general_graph.py index 4c54708..ba3cc2f 100644 --- a/grape/general_graph.py +++ b/grape/general_graph.py @@ -64,7 +64,7 @@ def load(self, filename): row['Father_mark'], row['Mark'], Father_cond = row['Father_cond'], - weight = float(row['Service']) ) + weight = float(row['Weight'])) self.newstatus = {} self.finalstatus = {} @@ -80,15 +80,15 @@ def load(self, filename): self.Father_mark = nx.get_node_attributes(self, 'Father_mark') self.condition = nx.get_edge_attributes(self, 'Father_cond') self.Type = nx.get_node_attributes(self, 'Type') - self.Service = nx.get_edge_attributes(self, 'weight') + self.Weight = nx.get_edge_attributes(self, 'weight') - self.services_SOURCE = [] - self.services_USER = [] + self.SOURCE = [] + self.USER = [] for id, Type in self.Type.items(): if Type == "SOURCE": - self.services_SOURCE.append(id) + self.SOURCE.append(id) elif Type == "USER": - self.services_USER.append(id) + self.USER.append(id) self.valv = { "isolation_A" : { "0": "OPEN", "1": "CLOSED"}, "isolation_B" : { "0": "CLOSED", "1": "OPEN"}, @@ -103,26 +103,24 @@ def check_input_with_gephi(self): nodes_to_print = [] with open("check_import_nodes.csv", "w") as csvFile: - fields = [ - "Mark", "Description", "InitStatus", "PerturbationResistant", - "Area" - ] + fields = [ "Mark", "Description", "InitStatus", + "PerturbationResistant", "Area" ] writer = csv.DictWriter(csvFile, fieldnames=fields) writer.writeheader() - if hasattr(self, "copy_of_self1"): - for n in self.copy_of_self1: + if hasattr(self, "cpy"): + for n in self.cpy: nodes_to_print.append({ 'Mark': n, 'Description': - self.copy_of_self1.nodes[n]["Description"], + self.cpy.nodes[n]["Description"], 'InitStatus': - self.copy_of_self1.nodes[n]["InitStatus"], + self.cpy.nodes[n]["InitStatus"], 'PerturbationResistant': - self.copy_of_self1.nodes[n]["PerturbationResistant"], + self.cpy.nodes[n]["PerturbationResistant"], 'Area': - self.copy_of_self1.nodes[n]["Area"] + self.cpy.nodes[n]["Area"] }) writer.writerows(nodes_to_print) else: @@ -149,9 +147,9 @@ def check_input_with_gephi(self): writer = csv.DictWriter(csvFile, fieldnames=fields) writer.writeheader() - if hasattr(self, "copy_of_self1"): - for n in self.copy_of_self1: - for p in self.copy_of_self1.predecessors(n): + if hasattr(self, "cpy"): + for n in self.cpy: + for p in self.cpy.predecessors(n): edges_to_print.append({'Mark': n, 'Father_mark': p}) else: @@ -193,10 +191,10 @@ def construct_path(self, source, target, pred): else: path = [] - path1 = list(map(self.ids.get, path)) - path1 = list(reversed(path1)) + path = list(map(self.ids.get, path)) + path = list(reversed(path)) - return path1 + return path def construct_path_kernel(self, pred, nodi): """ @@ -344,7 +342,8 @@ def floyd_warshall_kernel(self, dist, pred, init, stop, barrier=None): dist[init:stop, :], dist[init:stop, :]) diff = np.equal(dist[init:stop, :], dist_copy) - pred[init:stop, :][~diff] = np.tile(pred[w, :], (stop-init, 1))[~diff] + pred[init:stop, :][~diff] = \ + np.tile(pred[w, :], (stop-init, 1))[~diff] if barrier: barrier.wait() @@ -363,13 +362,13 @@ def floyd_warshall_predecessor_and_distance_parallel(self): dist, pred = self.floyd_warshall_initialization() - shared_arr = mp.sharedctypes.RawArray(ctypes.c_double, dist.shape[0]**2) - arr = np.frombuffer(shared_arr, 'float64').reshape(dist.shape) - arr[:] = dist + shared_d = mp.sharedctypes.RawArray(ctypes.c_double, dist.shape[0]**2) + dist_shared = np.frombuffer(shared_d, 'float64').reshape(dist.shape) + dist_shared[:] = dist - shared_arr_pred = mp.sharedctypes.RawArray(ctypes.c_double,pred.shape[0]**2) - arr1 = np.frombuffer(shared_arr_pred, 'float64').reshape(pred.shape) - arr1[:] = pred + shared_p = mp.sharedctypes.RawArray(ctypes.c_double,pred.shape[0]**2) + pred_shared = np.frombuffer(shared_p, 'float64').reshape(pred.shape) + pred_shared[:] = pred n = len(self.nodes()) chunk = [(0, int(n / self.num))] @@ -382,7 +381,7 @@ def floyd_warshall_predecessor_and_distance_parallel(self): barrier = mp.Barrier(self.num) processes = [ mp.Process( target=self.floyd_warshall_kernel, - args=(arr, arr1, chunk[p][0], chunk[p][1], barrier)) + args=(dist_shared, pred_shared, chunk[p][0], chunk[p][1], barrier)) for p in range(self.num) ] for proc in processes: @@ -396,7 +395,9 @@ def floyd_warshall_predecessor_and_distance_parallel(self): processes = [ mp.Process( target=self.construct_path_iteration_parallel, - args=(arr1, list(map(self.ids_reversed.get, node_chunks[p])), shpaths_dicts)) + args=(pred_shared, + list(map(self.ids_reversed.get, node_chunks[p])), + shpaths_dicts)) for p in range(self.num) ] for proc in processes: @@ -416,7 +417,8 @@ def floyd_warshall_predecessor_and_distance_parallel(self): self.nodes[self.ids[i]]["shpath_length"] = {} for key, value in self.nodes[self.ids[i]]["shortest_path"].items(): - length_path = arr[self.ids_reversed[value[0]], self.ids_reversed[value[-1]]] + length_path = dist_shared[self.ids_reversed[value[0]], + self.ids_reversed[value[-1]]] self.nodes[self.ids[i]]["shpath_length"][key] = length_path eff_dicts = manager.dict() @@ -464,7 +466,8 @@ def floyd_warshall_predecessor_and_distance_serial(self): self.nodes[self.ids[i]]["shpath_length"] = {} for key, value in self.nodes[self.ids[i]]["shortest_path"].items(): - length_path = dist[self.ids_reversed[value[0]], self.ids_reversed[value[-1]]] + length_path = dist[self.ids_reversed[value[0]], + self.ids_reversed[value[-1]]] self.nodes[self.ids[i]]["shpath_length"][key] = length_path eff_dicts = self.compute_efficiency_kernel(list(self)) @@ -477,8 +480,9 @@ def single_source_shortest_path_serial(self): The nested dictionaries for shortest-path, length of the paths and efficiency attributes are evaluated. - .. note:: Edges weight is taken into account. Edge weight attributes must - be numerical. Distances are calculated as sums of weighted edges traversed. + .. note:: Edges weight is taken into account. + Edge weight attributes must be numerical. + Distances are calculated as sums of weighted edges traversed. """ for n in self: @@ -498,8 +502,9 @@ def single_source_shortest_path_parallel(self, out_q, nodi): :param list nodi: list of starting nodes from which the SSSP should be computed to every other target node in the graph - .. note:: Edges weight is taken into account. Edge weight attributes must - be numerical. Distances are calculated as sums of weighted edges traversed. + .. note:: Edges weight is taken into account. + Edge weight attributes must be numerical. + Distances are calculated as sums of weighted edges traversed. """ for n in nodi: @@ -535,8 +540,9 @@ def parallel_wrapper_proc(self): The nested dictionaries for shortest-path, length of the paths and efficiency attributes are evaluated. - .. note:: Edges weight is taken into account. Edge weight attributes must - be numerical. Distances are calculated as sums of weighted edges traversed. + .. note:: Edges weight is taken into account. + Edge weight attributes must be numerical. + Distances are calculated as sums of weighted edges traversed. """ self.attribute_ssspp = [] @@ -596,9 +602,9 @@ def nodal_efficiency(self): "final_nodal_eff" is the efficiency of each node in the potentially perturbed graph, after the propagation of a perturbation. - .. note:: The global efficiency of the node is equal to zero for a node - without any outgoing path and equal to one if from it we can reach - each node of the digraph. + .. note:: The global efficiency of the node is equal to zero + for a node without any outgoing path and equal to one if from it + we can reach each node of the digraph. """ g_len = len(list(self)) @@ -607,20 +613,21 @@ def nodal_efficiency(self): if "original_nodal_eff" in all_attributes: - deleted_nodes = set(list(self.copy_of_self1)) - set(list(self)) + deleted_nodes = set(list(self.cpy)) - set(list(self)) for v in deleted_nodes: - self.copy_of_self1.nodes[v]["final_nodal_eff"] = " " + self.cpy.nodes[v]["final_nodal_eff"] = " " for v in self: sum_efficiencies = sum(self.nodes[v]["efficiency"].values()) - self.copy_of_self1.nodes[v][ + self.cpy.nodes[v][ "final_nodal_eff"] = sum_efficiencies / (g_len - 1) else: for v in self: sum_efficiencies = sum(self.nodes[v]["efficiency"].values()) - self.nodes[v]["original_nodal_eff"] = sum_efficiencies / (g_len - 1) + self.nodes[v]["original_nodal_eff"] = \ + sum_efficiencies / (g_len - 1) def local_efficiency(self): """ @@ -635,10 +642,11 @@ def local_efficiency(self): potentially perturbed graph, after the propagation of a perturbation. .. note:: The local efficiency shows the efficiency of the connections - between the first-order outgoing neighbors of node v when v is removed. - Equivalently, local efficiency measures the "resilience" of the digraph - to the perturbation of node removal, i.e. if we remove a node, - how efficiently its first-order outgoing neighbors can communicate. + between the first-order outgoing neighbors of node v + when v is removed. Equivalently, local efficiency measures + the "resilience" of the digraph to the perturbation of node removal, + i.e. if we remove a node, how efficiently its first-order outgoing + neighbors can communicate. It is in the range [0, 1]. """ @@ -647,10 +655,10 @@ def local_efficiency(self): if "original_local_eff" in all_attributes: - deleted_nodes = set(list(self.copy_of_self1)) - set(list(self)) + deleted_nodes = set(list(self.cpy)) - set(list(self)) for v in deleted_nodes: - self.copy_of_self1.nodes[v]["final_local_eff"] = " " + self.cpy.nodes[v]["final_local_eff"] = " " for v in self: subgraph = list(self.successors(v)) @@ -659,15 +667,14 @@ def local_efficiency(self): if denom_subg != 0: sum_efficiencies = 0 for w in list(subgraph): - kv_efficiency = self.copy_of_self1.nodes[w][ - "final_nodal_eff"] + kv_efficiency = self.cpy.nodes[w]["final_nodal_eff"] sum_efficiencies = sum_efficiencies + kv_efficiency loc_eff = sum_efficiencies / denom_subg - self.copy_of_self1.nodes[v]["final_local_eff"] = loc_eff + self.cpy.nodes[v]["final_local_eff"] = loc_eff else: - self.copy_of_self1.nodes[v]["final_local_eff"] = 0 + self.cpy.nodes[v]["final_local_eff"] = 0 else: for v in self: subgraph = list(self.successors(v)) @@ -709,8 +716,8 @@ def global_efficiency(self): sum_eff = sum_eff + kv_efficiency if "original_avg_global_eff" in all_attributes: - for v in self.copy_of_self1: - self.copy_of_self1.nodes[v]["final_avg_global_eff"] = sum_eff / g_len + for v in self.cpy: + self.cpy.nodes[v]["final_avg_global_eff"] = sum_eff / g_len else: for v in self: self.nodes[v]["original_avg_global_eff"] = sum_eff / g_len @@ -870,7 +877,8 @@ def calculate_shortest_path(self): For small graphs go serial. - .. note:: Edge weights of the graph are taken into account in the computation. + .. note:: Edge weights of the graph are taken into account + in the computation. """ n_of_nodes = self.order() @@ -912,8 +920,8 @@ def check_before(self): self.global_efficiency() self.local_efficiency() - for source in self.services_SOURCE: - for user in self.services_USER: + for source in self.SOURCE: + for user in self.USER: if nx.has_path(self, source, user): osip = list(nx.all_simple_paths(self, source, user)) @@ -960,8 +968,8 @@ def check_after(self): self.global_efficiency() self.local_efficiency() - for source in self.services_SOURCE: - for user in self.services_USER: + for source in self.SOURCE: + for user in self.USER: if nx.has_path(self, source, user): sip = list(nx.all_simple_paths(self, source, user)) @@ -977,7 +985,8 @@ def check_after(self): logging.debug( "valve %s at node %s, state %s", - self.D[node], node, self.valv[self.D[node]]["1"]) + self.D[node], node, + self.valv[self.D[node]]["1"]) elif self.newstatus[node] == "0": @@ -985,21 +994,25 @@ def check_after(self): logging.debug( "valve %s at node %s, from %s to %s", - self.D[node], node, self.valv[self.D[node]]["0"], + self.D[node], node, + self.valv[self.D[node]]["0"], self.valv[self.D[node]]["1"]) else: if self.status[node] == "1": logging.debug( "valve %s at node %s, state %s", - self.D[node], node, self.valv[self.D[node]]["1"]) + self.D[node], node, + self.valv[self.D[node]]["1"]) + elif self.status[node] == "0": self.finalstatus.update({node: "1"}) logging.debug( "valve %s at node %s, from %s to %s", - self.D[node], node, self.valv[self.D[node]]["0"], + self.D[node], node, + self.valv[self.D[node]]["0"], self.valv[self.D[node]]["1"]) shp = self.nodes[source]["shortest_path"][user] @@ -1140,17 +1153,17 @@ def update_areas(self, deleted_nodes, damaged_areas): of the elements """ - for n in self.copy_of_self1: + for n in self.cpy: if n in deleted_nodes: - self.copy_of_self1.nodes[n]["Mark_Status"] = "NOT_ACTIVE" + self.cpy.nodes[n]["Mark_Status"] = "NOT_ACTIVE" else: - self.copy_of_self1.nodes[n]["Mark_Status"] = "ACTIVE" + self.cpy.nodes[n]["Mark_Status"] = "ACTIVE" - if self.copy_of_self1.nodes[n]["Area"] in damaged_areas: - self.copy_of_self1.nodes[n]["Status_Area"] = "DAMAGED" + if self.cpy.nodes[n]["Area"] in damaged_areas: + self.cpy.nodes[n]["Status_Area"] = "DAMAGED" else: - self.copy_of_self1.nodes[n]["Status_Area"] = "AVAILABLE" + self.cpy.nodes[n]["Status_Area"] = "AVAILABLE" def delete_a_node(self, node): """ @@ -1204,18 +1217,18 @@ def simulate_element_perturbation(self, perturbed_nodes): self.indegree_centrality() self.outdegree_centrality() self.degree_centrality() - self.copy_of_self1 = copy.deepcopy(self) + self.cpy = copy.deepcopy(self) for node in perturbed_nodes: self.delete_a_node(node) - deleted_nodes = set(self.copy_of_self1) - set(self) + deleted_nodes = set(self.cpy) - set(self) - del_sources = [s for s in self.services_SOURCE if s in deleted_nodes] - for s in del_sources: self.services_SOURCE.remove(s) + del_sources = [s for s in self.SOURCE if s in deleted_nodes] + for s in del_sources: self.SOURCE.remove(s) - del_users = [u for u in self.services_USER if u in deleted_nodes] - for u in del_users: self.services_USER.remove(u) + del_users = [u for u in self.USER if u in deleted_nodes] + for u in del_users: self.USER.remove(u) self.lst = [] self.check_after() @@ -1225,7 +1238,7 @@ def simulate_element_perturbation(self, perturbed_nodes): self.update_areas(deleted_nodes, self.damaged_areas) self.graph_characterization_to_file("element_perturbation.csv") - def simulate_multi_area_perturbation(self, perturbed_areas): + def simulate_area_perturbation(self, perturbed_areas): """ Simulate a perturbation in one or multiple areas. @@ -1260,24 +1273,24 @@ def simulate_multi_area_perturbation(self, perturbed_areas): self.indegree_centrality() self.outdegree_centrality() self.degree_centrality() - self.copy_of_self1 = copy.deepcopy(self) + self.cpy = copy.deepcopy(self) for node in nodes_in_area: if node in self.nodes(): self.delete_a_node(node) nodes_in_area = list(set(nodes_in_area) - set(self.bn)) - deleted_nodes = set(self.copy_of_self1) - set(self) + deleted_nodes = set(self.cpy) - set(self) - del_sources = [s for s in self.services_SOURCE if s in deleted_nodes] - for s in del_sources: self.services_SOURCE.remove(s) + del_sources = [s for s in self.SOURCE if s in deleted_nodes] + for s in del_sources: self.SOURCE.remove(s) - del_users = [u for u in self.services_USER if u in deleted_nodes] - for u in del_users: self.services_USER.remove(u) + del_users = [u for u in self.USER if u in deleted_nodes] + for u in del_users: self.USER.remove(u) self.lst = [] self.check_after() - self.service_paths_to_file("service_paths_multi_area_perturbation.csv") + self.service_paths_to_file("service_paths_area_perturbation.csv") self.update_status(self.newstatus, "IntermediateStatus", deleted_nodes) self.update_status(self.finalstatus, "FinalStatus", deleted_nodes) self.update_areas(deleted_nodes, self.damaged_areas) @@ -1301,16 +1314,16 @@ def update_status(self, which_status, field, already_updated): for k, v in which_status.items() if k not in already_updated } - ns_keys = which_status.keys() & list(self.copy_of_self1) - os_keys = set(self.copy_of_self1) - set(ns_keys) + ns_keys = which_status.keys() & list(self.cpy) + os_keys = set(self.cpy) - set(ns_keys) for index, updated_status in which_status.items(): - self.copy_of_self1.nodes[index][field] = updated_status + self.cpy.nodes[index][field] = updated_status for index in os_keys: - self.copy_of_self1.nodes[index][field] = " " + self.cpy.nodes[index][field] = " " else: - for index in list(self.copy_of_self1): - self.copy_of_self1.nodes[index][field] = " " + for index in list(self.cpy): + self.cpy.nodes[index][field] = " " def service_paths_to_file(self, filename): """ @@ -1359,44 +1372,44 @@ def graph_characterization_to_file(self, filename): writer = csv.DictWriter(csvFile, fieldnames=fields) writer.writeheader() - for n in self.copy_of_self1: + for n in self.cpy: list_to_print.append({ 'Mark': n, 'Description': - self.copy_of_self1.nodes[n]["Description"], + self.cpy.nodes[n]["Description"], 'InitStatus': - self.copy_of_self1.nodes[n]["InitStatus"], + self.cpy.nodes[n]["InitStatus"], 'IntermediateStatus': - self.copy_of_self1.nodes[n]["IntermediateStatus"], + self.cpy.nodes[n]["IntermediateStatus"], 'FinalStatus': - self.copy_of_self1.nodes[n]["FinalStatus"], + self.cpy.nodes[n]["FinalStatus"], 'Mark_Status': - self.copy_of_self1.nodes[n]["Mark_Status"], + self.cpy.nodes[n]["Mark_Status"], 'PerturbationResistant': - self.copy_of_self1.nodes[n]["PerturbationResistant"], + self.cpy.nodes[n]["PerturbationResistant"], 'Area': - self.copy_of_self1.nodes[n]["Area"], + self.cpy.nodes[n]["Area"], 'Status_Area': - self.copy_of_self1.nodes[n]["Status_Area"], + self.cpy.nodes[n]["Status_Area"], 'closeness_centrality': - self.copy_of_self1.nodes[n]["closeness_centrality"], + self.cpy.nodes[n]["closeness_centrality"], 'betweenness_centrality': - self.copy_of_self1.nodes[n]["betweenness_centrality"], + self.cpy.nodes[n]["betweenness_centrality"], 'indegree_centrality': - self.copy_of_self1.nodes[n]["indegree_centrality"], + self.cpy.nodes[n]["indegree_centrality"], 'original_local_eff': - self.copy_of_self1.nodes[n]["original_local_eff"], + self.cpy.nodes[n]["original_local_eff"], 'final_local_eff': - self.copy_of_self1.nodes[n]["final_local_eff"], + self.cpy.nodes[n]["final_local_eff"], 'original_global_eff': - self.copy_of_self1.nodes[n]["original_nodal_eff"], + self.cpy.nodes[n]["original_nodal_eff"], 'final_global_eff': - self.copy_of_self1.nodes[n]["final_nodal_eff"], + self.cpy.nodes[n]["final_nodal_eff"], 'original_avg_global_eff': - self.copy_of_self1.nodes[n]["original_avg_global_eff"], + self.cpy.nodes[n]["original_avg_global_eff"], 'final_avg_global_eff': - self.copy_of_self1.nodes[n]["final_avg_global_eff"] + self.cpy.nodes[n]["final_avg_global_eff"] }) writer.writerows(list_to_print) csvFile.close() @@ -1409,5 +1422,5 @@ def graph_characterization_to_file(self, filename): g.check_input_with_gephi() g.simulate_element_perturbation(["1"]) - #g.simulate_multi_area_perturbation(['area1']) - ##g.simulate_multi_area_perturbation(['area1','area2','area3']) + #g.simulate_area_perturbation(['area1']) + ##g.simulate_area_perturbation(['area1','area2','area3']) diff --git a/tests/TOY_graph.csv b/tests/TOY_graph.csv index ff1ebaf..4dcd8ef 100644 --- a/tests/TOY_graph.csv +++ b/tests/TOY_graph.csv @@ -1,4 +1,4 @@ -,"Mark","Father_cond","Father_mark","Area","PerturbationResistant","InitStatus","Description","Type","Service" +,"Mark","Father_cond","Father_mark","Area","PerturbationResistant","InitStatus","Description","Type","Weight" ,"1","ORPHAN","NULL","area1","0",,,"SOURCE",0.0 ,"2","SINGLE","1","area1","1","1","isolation_A","HUB",1.0 ,"3","SINGLE","1","area1","1","1","isolation_A","HUB",1.0 diff --git a/tests/test_input_graph.py b/tests/test_input_graph.py index 7d6d3d3..363e9a1 100644 --- a/tests/test_input_graph.py +++ b/tests/test_input_graph.py @@ -278,15 +278,15 @@ def test_Type(self): self.assertDictEqual( Type_dict, g.Type, msg=" Wrong TYPE in input ") - def test_Service(self): + def test_Weight(self): """ - Unittest check for Service attribute of GeneralGraph: + Unittest check for Weight attribute of GeneralGraph: correct input reading. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - Service_dict = { + Weight_dict = { ('1', '2'): 1.0, ('1', '3'): 1.0, ('2', '4'): 1.0, @@ -317,4 +317,4 @@ def test_Service(self): } self.assertDictEqual( - Service_dict, g.Service, msg=" Wrong SERVICE in input ") + Weight_dict, g.Weight, msg=" Wrong WEIGHT in input ") diff --git a/tests/test_output_graph.py b/tests/test_output_graph.py index 9e8b4f4..5bddd3a 100644 --- a/tests/test_output_graph.py +++ b/tests/test_output_graph.py @@ -6,9 +6,9 @@ from grape.general_graph import GeneralGraph -def test_nodal_eff_before(): +def test_nodal_efficiency_before(): """ - The following test checks the nodal efficiency before any perturbation. + The following test checks nodal efficiency before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -43,9 +43,9 @@ def test_nodal_eff_before(): np.asarray(sorted(g_nodal_eff_before.values())), err_msg="ORIGINAL NODAL EFFICIENCY failure") -def test_global_eff_before(): +def test_global_efficiency_before(): """ - The following test checks the global efficiency before any perturbation. + The following test checks global efficiency before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -80,9 +80,9 @@ def test_global_eff_before(): np.asarray(sorted(g_global_eff_before.values())), err_msg="ORIGINAL GLOBAL EFFICIENCY failure") -def test_local_eff_before(): +def test_local_efficiency_before(): """ - The following test checks the local efficiency before any perturbation. + The following test checks local efficiency before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -119,7 +119,7 @@ def test_local_eff_before(): def test_closeness_centrality(): """ - The following test checks the closeness centrality before any perturbation. + The following test checks closeness centrality before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -157,7 +157,7 @@ def test_closeness_centrality(): def test_betweenness_centrality(): """ - The following test checks the betweenness centrality before any perturbation. + The following test checks betweenness centrality before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -195,7 +195,7 @@ def test_betweenness_centrality(): def test_indegree_centrality(): """ - The following test checks the indegree centrality before any perturbation. + The following test checks indegree centrality before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -233,7 +233,7 @@ def test_indegree_centrality(): def test_outdegree_centrality(): """ - The following test checks the outdegree centrality before any perturbation. + The following test checks outdegree centrality before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -271,7 +271,7 @@ def test_outdegree_centrality(): def test_degree_centrality(): """ - The following test checks the degree centrality before any perturbation. + The following test checks degree centrality before any perturbation. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") @@ -307,14 +307,14 @@ def test_degree_centrality(): np.asarray(sorted(g_degree_centrality.values())), err_msg="DEGREE CENTRALITY failure") -def test_global_eff_after_element_perturbation(): +def test_global_efficiency_after_element_perturbation(): """ The following test checks the global efficiency after a perturbation. The perturbation here considered is the perturbation of element '1'. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_element_perturbation("1") + g.simulate_element_perturbation(["1"]) global_eff_after_element_perturbation = { '1': 0.16783899399640145, @@ -338,15 +338,15 @@ def test_global_eff_after_element_perturbation(): '19': 0.16783899399640145 } - g_global_eff_after_element_perturbation = nx.get_node_attributes(g.copy_of_self1, - 'final_avg_global_eff') + g_global_eff_after_element_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_avg_global_eff') np.testing.assert_array_almost_equal( np.asarray(sorted(global_eff_after_element_perturbation.values())), np.asarray(sorted(g_global_eff_after_element_perturbation.values())), err_msg="FINAL GLOBAL EFFICIENCY failure: perturbation of element 1") -def test_global_eff_after_single_area_perturbation(): +def test_global_efficiency_after_single_area_perturbation(): """ The following test checks the global efficiency after a perturbation. The perturbation here considered is the perturbation of a single area, @@ -354,7 +354,7 @@ def test_global_eff_after_single_area_perturbation(): """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1']) + g.simulate_area_perturbation(['area1']) global_eff_after_single_area_perturbation = { '1': 0.16783899399640145, @@ -378,15 +378,15 @@ def test_global_eff_after_single_area_perturbation(): '19': 0.16783899399640145 } - g_global_eff_after_single_area_perturbation = nx.get_node_attributes(g.copy_of_self1, - 'final_avg_global_eff') + g_global_eff_after_single_area_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_avg_global_eff') np.testing.assert_array_almost_equal( np.asarray(sorted(global_eff_after_single_area_perturbation.values())), np.asarray(sorted(g_global_eff_after_single_area_perturbation.values())), err_msg="FINAL GLOBAL EFFICIENCY failure: perturbation in area 1") -def test_global_eff_after_multiple_area_perturbation(): +def test_global_efficiency_after_multi_area_perturbation(): """ The following test checks the global efficiency after a perturbation. The perturbation here considered is the perturbation of multiple areas, @@ -394,9 +394,9 @@ def test_global_eff_after_multiple_area_perturbation(): """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1', 'area2', 'area3']) + g.simulate_area_perturbation(['area1', 'area2', 'area3']) - global_eff_after_multiple_area_perturbation = { + global_eff_after_multi_area_perturbation = { '1': 0.1926593027783504, '2': 0.1926593027783504, '3': 0.1926593027783504, @@ -418,12 +418,12 @@ def test_global_eff_after_multiple_area_perturbation(): '19': 0.1926593027783504 } - g_global_eff_after_multiple_area_perturbation = nx.get_node_attributes(g.copy_of_self1, - 'final_avg_global_eff') + g_global_eff_after_multi_area_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_avg_global_eff') np.testing.assert_array_almost_equal( - np.asarray(sorted(global_eff_after_multiple_area_perturbation.values())), - np.asarray(sorted(g_global_eff_after_multiple_area_perturbation.values())), + np.asarray(sorted(global_eff_after_multi_area_perturbation.values())), + np.asarray(sorted(g_global_eff_after_multi_area_perturbation.values())), err_msg="FINAL GLOBAL EFFICIENCY failure: perturbation in areas 1,2,3") class TestOutputGraph(TestCase): @@ -440,14 +440,14 @@ def setUp(cls): """ cls.maxDiff = None - def test_nodal_eff_after_element_perturbation(self): + def test_nodal_efficiency_after_element_perturbation(self): """ The following test checks the nodal efficiency after a perturbation. The perturbation here considered is the perturbation of element '1'. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_element_perturbation("1") + g.simulate_element_perturbation(["1"]) nodal_eff_after_element_perturbation = { '1': ' ', @@ -471,28 +471,28 @@ def test_nodal_eff_after_element_perturbation(self): '19': 0.17647058823529413 } - g_nodal_eff_after_element_perturbation = nx.get_node_attributes( - g.copy_of_self1, 'final_nodal_eff') + g_nodal_eff_after_element_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_nodal_eff') self.assertEqual( g_nodal_eff_after_element_perturbation['1'], nodal_eff_after_element_perturbation['1'], msg="FINAL NODAL EFFICIENCY failure: perturbation of element 1") - g_nodal_eff_after_element_perturbation_survived = { - k: v - for k, v in g_nodal_eff_after_element_perturbation.items() if k != '1' + g_nodal_eff_survived = { + k: v for k, v in g_nodal_eff_after_element_perturbation.items() + if k != '1' } - nodal_eff_after_element_perturbation_survived = { - k: v - for k, v in nodal_eff_after_element_perturbation.items() if k != '1' + nodal_eff_survived = { + k: v for k, v in nodal_eff_after_element_perturbation.items() + if k != '1' } np.testing.assert_array_almost_equal( - np.asarray(sorted(nodal_eff_after_element_perturbation_survived.values())), - np.asarray(sorted(g_nodal_eff_after_element_perturbation_survived.values())), + np.asarray(sorted(nodal_eff_survived.values())), + np.asarray(sorted(g_nodal_eff_survived.values())), err_msg="FINAL NODAL EFFICIENCY failure: perturbation of element 1") - def test_nodal_eff_after_single_area_perturbation(self): + def test_nodal_efficiency_after_single_area_perturbation(self): """ The following test checks the nodal efficiency after a perturbation. The perturbation here considered is the perturbation of a single area, @@ -500,7 +500,7 @@ def test_nodal_eff_after_single_area_perturbation(self): """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1']) + g.simulate_area_perturbation(['area1']) nodal_eff_after_single_area_perturbation = { '1': ' ', @@ -524,28 +524,28 @@ def test_nodal_eff_after_single_area_perturbation(self): '19': 0.17647058823529413 } - g_nodal_eff_after_single_area_perturbation = nx.get_node_attributes( - g.copy_of_self1, 'final_nodal_eff') + g_nodal_eff_after_single_area_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_nodal_eff') self.assertEqual( g_nodal_eff_after_single_area_perturbation['1'], nodal_eff_after_single_area_perturbation['1'], msg="FINAL NODAL EFFICIENCY failure: perturbation in area 1") - g_nodal_eff_after_single_area_perturbation_survived = { - k: v - for k, v in g_nodal_eff_after_single_area_perturbation.items() if k != '1' + g_nodal_eff_survived = { + k: v for k, v in g_nodal_eff_after_single_area_perturbation.items() + if k != '1' } - nodal_eff_after_single_area_perturbation_survived = { - k: v - for k, v in nodal_eff_after_single_area_perturbation.items() if k != '1' + nodal_eff_survived = { + k: v for k, v in nodal_eff_after_single_area_perturbation.items() + if k != '1' } np.testing.assert_array_almost_equal( - np.asarray(sorted(nodal_eff_after_single_area_perturbation_survived.values())), - np.asarray(sorted(g_nodal_eff_after_single_area_perturbation_survived.values())), + np.asarray(sorted(nodal_eff_survived.values())), + np.asarray(sorted(g_nodal_eff_survived.values())), err_msg="FINAL NODAL EFFICIENCY failure: perturbation in area 1") - def test_nodal_eff_after_multiple_area_perturbation(self): + def test_nodal_efficiency_after_multi_area_perturbation(self): """ The following test checks the nodal efficiency after a perturbation. The perturbation here considered is the perturbation of multiple areas, @@ -553,9 +553,9 @@ def test_nodal_eff_after_multiple_area_perturbation(self): """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1', 'area2', 'area3']) + g.simulate_area_perturbation(['area1', 'area2', 'area3']) - nodal_eff_after_multiple_area_perturbation = { + nodal_eff_after_multi_area_perturbation = { '1': ' ', '2': 0.3611111111111111, '3': 0.16666666666666666, @@ -577,46 +577,46 @@ def test_nodal_eff_after_multiple_area_perturbation(self): '19': ' ' } - g_nodal_eff_after_multiple_area_perturbation = nx.get_node_attributes( - g.copy_of_self1, 'final_nodal_eff') + g_nodal_eff_after_multi_area_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_nodal_eff') survived = ['2', '3', '4', '5', '6', '7', '8'] - g_nodal_eff_after_multiple_area_perturbation_survived = { - k: v - for k, v in g_nodal_eff_after_multiple_area_perturbation.items() if k in survived + g_nodal_eff_survived = { + k: v for k, v in g_nodal_eff_after_multi_area_perturbation.items() + if k in survived } - nodal_eff_after_multiple_area_perturbation_survived = { - k: v - for k, v in nodal_eff_after_multiple_area_perturbation.items() if k in survived + nodal_eff_survived = { + k: v for k, v in nodal_eff_after_multi_area_perturbation.items() + if k in survived } - g_nodal_eff_after_multiple_area_perturbation_deleted = { - k: v - for k, v in g_nodal_eff_after_multiple_area_perturbation.items() if k not in survived + g_nodal_eff_deleted = { + k: v for k, v in g_nodal_eff_after_multi_area_perturbation.items() + if k not in survived } - nodal_eff_after_multiple_area_perturbation_deleted = { - k: v - for k, v in nodal_eff_after_multiple_area_perturbation.items() if k not in survived + nodal_eff_deleted = { + k: v for k, v in nodal_eff_after_multi_area_perturbation.items() + if k not in survived } self.assertDictEqual( - nodal_eff_after_multiple_area_perturbation_deleted, - g_nodal_eff_after_multiple_area_perturbation_deleted, + nodal_eff_deleted, + g_nodal_eff_deleted, msg="FINAL NODAL EFFICIENCY failure: perturbation in areas 1, 2, 3") np.testing.assert_array_almost_equal( - np.asarray(sorted(nodal_eff_after_multiple_area_perturbation_survived.values())), - np.asarray(sorted(g_nodal_eff_after_multiple_area_perturbation_survived.values())), + np.asarray(sorted(nodal_eff_survived.values())), + np.asarray(sorted(g_nodal_eff_survived.values())), err_msg= "FINAL NODAL EFFICIENCY failure: perturbation in areas 1, 2, 3") - def test_local_eff_after_element_perturbation(self): + def test_local_efficiency_after_element_perturbation(self): """ The following test checks the local efficiency after a perturbation. The perturbation here considered is the perturbation of element '1'. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_element_perturbation("1") + g.simulate_element_perturbation(["1"]) local_eff_after_element_perturbation = { '1': ' ', @@ -640,29 +640,29 @@ def test_local_eff_after_element_perturbation(self): '19': 0.18627450980392157 } - g_local_eff_after_element_perturbation = nx.get_node_attributes( - g.copy_of_self1, 'final_local_eff') + g_local_eff_after_element_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_local_eff') self.assertEqual( g_local_eff_after_element_perturbation['1'], local_eff_after_element_perturbation['1'], msg="FINAL LOCAL EFFICIENCY failure: perturbation of element 1") - g_local_eff_after_element_perturbation_survived = { - k: v - for k, v in g_local_eff_after_element_perturbation.items() if k != '1' + g_local_eff_survived = { + k: v for k, v in g_local_eff_after_element_perturbation.items() + if k != '1' } - local_eff_after_element_perturbation_survived = { - k: v - for k, v in local_eff_after_element_perturbation.items() if k != '1' + local_eff_survived = { + k: v for k, v in local_eff_after_element_perturbation.items() + if k != '1' } np.testing.assert_array_almost_equal( - np.asarray(sorted(local_eff_after_element_perturbation_survived.values())), - np.asarray(sorted(g_local_eff_after_element_perturbation_survived.values())), + np.asarray(sorted(local_eff_survived.values())), + np.asarray(sorted(g_local_eff_survived.values())), err_msg="FINAL LOCAL EFFICIENCY failure: perturbation of element 1") - def test_local_eff_after_single_area_perturbation(self): + def test_local_efficiency_after_single_area_perturbation(self): """ The following test checks the local efficiency after a perturbation. The perturbation here considered is the perturbation of a single area, @@ -670,7 +670,7 @@ def test_local_eff_after_single_area_perturbation(self): """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1']) + g.simulate_area_perturbation(['area1']) local_eff_after_single_area_perturbation = { '1': ' ', @@ -694,29 +694,29 @@ def test_local_eff_after_single_area_perturbation(self): '19': 0.18627450980392157 } - g_local_eff_after_single_area_perturbation = nx.get_node_attributes( - g.copy_of_self1, 'final_local_eff') + g_local_eff_after_single_area_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_local_eff') self.assertEqual( g_local_eff_after_single_area_perturbation['1'], local_eff_after_single_area_perturbation['1'], msg="FINAL LOCAL EFFICIENCY failure: perturbation in area 1") - g_local_eff_after_single_area_perturbation_survived = { - k: v - for k, v in g_local_eff_after_single_area_perturbation.items() if k != '1' + g_local_eff_survived = { + k: v for k, v in g_local_eff_after_single_area_perturbation.items() + if k != '1' } - local_eff_after_single_area_perturbation_survived = { - k: v - for k, v in local_eff_after_single_area_perturbation.items() if k != '1' + local_eff_survived = { + k: v for k, v in local_eff_after_single_area_perturbation.items() + if k != '1' } np.testing.assert_array_almost_equal( - np.asarray(sorted(local_eff_after_single_area_perturbation_survived.values())), - np.asarray(sorted(g_local_eff_after_single_area_perturbation_survived.values())), + np.asarray(sorted(local_eff_survived.values())), + np.asarray(sorted(g_local_eff_survived.values())), err_msg="FINAL LOCAL EFFICIENCY failure: perturbation in area 1") - def test_local_eff_after_multiple_area_perturbation(self): + def test_local_efficiency_after_multi_area_perturbation(self): """ The following test checks the local efficiency after a perturbation. The perturbation here considered is the perturbation of multiple areas, @@ -724,9 +724,9 @@ def test_local_eff_after_multiple_area_perturbation(self): """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1', 'area2', 'area3']) + g.simulate_area_perturbation(['area1', 'area2', 'area3']) - local_eff_after_multiple_area_perturbation = { + local_eff_after_multi_area_perturbation = { '1': ' ', '2': 0.3333333333333333, '3': 0.0, @@ -748,34 +748,34 @@ def test_local_eff_after_multiple_area_perturbation(self): '19': ' ' } - g_local_eff_after_multiple_area_perturbation = nx.get_node_attributes( - g.copy_of_self1, 'final_local_eff') + g_local_eff_after_multi_area_perturbation = \ + nx.get_node_attributes(g.cpy, 'final_local_eff') survived = ['2', '3', '4', '5', '6', '7', '8'] - g_local_eff_after_multiple_area_perturbation_survived = { - k: v - for k, v in g_local_eff_after_multiple_area_perturbation.items() if k in survived + g_local_eff_survived = { + k: v for k, v in g_local_eff_after_multi_area_perturbation.items() + if k in survived } - local_eff_after_multiple_area_perturbation_survived = { - k: v - for k, v in local_eff_after_multiple_area_perturbation.items() if k in survived + local_eff_survived = { + k: v for k, v in local_eff_after_multi_area_perturbation.items() + if k in survived } - g_local_eff_after_multiple_area_perturbation_deleted = { - k: v - for k, v in g_local_eff_after_multiple_area_perturbation.items() if k not in survived + g_local_eff_deleted = { + k: v for k, v in g_local_eff_after_multi_area_perturbation.items() + if k not in survived } - local_eff_after_multiple_area_perturbation_deleted = { - k: v - for k, v in local_eff_after_multiple_area_perturbation.items() if k not in survived + local_eff_deleted = { + k: v for k, v in local_eff_after_multi_area_perturbation.items() + if k not in survived } self.assertDictEqual( - local_eff_after_multiple_area_perturbation_deleted, - g_local_eff_after_multiple_area_perturbation_deleted, + local_eff_deleted, + g_local_eff_deleted, msg="FINAL LOCAL EFFICIENCY failure: perturbation in areas 1, 2, 3") np.testing.assert_array_almost_equal( - np.asarray(sorted(local_eff_after_multiple_area_perturbation_survived.values())), - np.asarray(sorted(g_local_eff_after_multiple_area_perturbation_survived.values())), + np.asarray(sorted(local_eff_survived.values())), + np.asarray(sorted(g_local_eff_survived.values())), err_msg= "FINAL LOCAL EFFICIENCY failure: perturbation in areas 1, 2, 3") diff --git a/tests/test_shortest_path.py b/tests/test_shortest_path.py index bf5ce26..cbe5700 100644 --- a/tests/test_shortest_path.py +++ b/tests/test_shortest_path.py @@ -7,20 +7,20 @@ class TestShortestPathGraph(TestCase): """ - Class TestShortestPathGraph to check shortest path calculation of GeneralGraph + Class TestShortestPathGraph to check shortest path calculation + of GeneralGraph """ @classmethod def setUpClass(cls): """ Shortest paths for the toy graph: - - 'initial_shortest_paths': shortest paths before any - perturbation - - 'final_shp_delete_a_node': shortest paths after deletion of node '1' - - 'final_shp_multi_area_perturbation': paths after multi area - perturbation + - 'initial': shortest paths before any perturbation + - 'final_element_perturbation': shortest paths after + element perturbation + - 'final_area_perturbation': shortest paths after area perturbation """ - cls.initial_shortest_paths = { + cls.initial = { '1': { '1': ['1'], '2': ['1', '2'], @@ -235,10 +235,10 @@ def setUpClass(cls): } } - cls.final_shp_element_perturbation = copy.deepcopy(cls.initial_shortest_paths) - cls.final_shp_element_perturbation.pop('1') + cls.final_element_perturbation = copy.deepcopy(cls.initial) + cls.final_element_perturbation.pop('1') - cls.final_shp_multi_area_perturbation = { + cls.final_multi_area_perturbation = { '2': { '2': ['2'], '4': ['2', '4'], @@ -303,14 +303,14 @@ def check_shortest_paths(cls, test, true_path, graph): test.assertEqual( len(path)-1, graph.nodes[source]["shpath_length"][target], - msg="Wrong LENGTH of path from " + str(source) + " to " + - str(target)) + msg="Wrong LENGTH of path from " + str(source) + + " to " + str(target)) else: test.assertEqual( 0.0, graph.nodes[source]["shpath_length"][target], - msg="Wrong LENGTH of path from " + str(source) + " to " + - str(target)) + msg="Wrong LENGTH of path from " + str(source) + + " to " + str(target)) def test_Dijkstra_parallel(self): """ @@ -322,7 +322,7 @@ def test_Dijkstra_parallel(self): g.num = mp.cpu_count() g.parallel_wrapper_proc() - self.check_shortest_paths(self, self.initial_shortest_paths, g) + self.check_shortest_paths(self, self.initial, g) def test_floyd_warshall_parallel(self): """ @@ -333,7 +333,7 @@ def test_floyd_warshall_parallel(self): g.num = mp.cpu_count() g.floyd_warshall_predecessor_and_distance_parallel() - self.check_shortest_paths(self, self.initial_shortest_paths, g) + self.check_shortest_paths(self, self.initial, g) def test_Dijkstra_serial(self): """ @@ -346,7 +346,7 @@ def test_Dijkstra_serial(self): g.num = mp.cpu_count() g.single_source_shortest_path_serial() - self.check_shortest_paths(self, self.initial_shortest_paths, g) + self.check_shortest_paths(self, self.initial, g) def test_floyd_warshall_serial(self): """ @@ -357,39 +357,42 @@ def test_floyd_warshall_serial(self): g.num = mp.cpu_count() g.floyd_warshall_predecessor_and_distance_serial() - self.check_shortest_paths(self, self.initial_shortest_paths, g) + self.check_shortest_paths(self, self.initial, g) def test_element_perturbation(self): """ - The following test checks the topology of the graph after a perturbation. - The perturbation here considered is the perturbation of element '1'. + The following test checks the topology of the graph after + a perturbation. The perturbation here considered is the + perturbation of element '1'. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_element_perturbation("1") + g.simulate_element_perturbation(["1"]) - self.check_shortest_paths(self, self.final_shp_element_perturbation, g) + self.check_shortest_paths(self, self.final_element_perturbation, g) def test_single_area_perturbation(self): """ - The following test checks the topology of the graph after a perturbation. - The perturbation here considered is the perturbation in one area. - The shortest paths is going to be the same as in single element perturbation - because all the nodes in area 1 but node '1' are perturbation resistant. + The following test checks the topology of the graph after + a perturbation. The perturbation here considered is the + perturbation in one area. + Shortest paths are going to be the same as in element perturbation + because all nodes in area 1 but node '1' are perturbation resistant. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1']) + g.simulate_area_perturbation(['area1']) - self.check_shortest_paths(self, self.final_shp_element_perturbation, g) + self.check_shortest_paths(self, self.final_element_perturbation, g) def test_multi_area_perturbation(self): """ - The following test checks the topology of the graph after a perturbation. - The perturbation here considered is the perturbation in multiple areas. + The following test checks the topology of the graph after + a perturbation. The perturbation here considered is the + perturbation in multiple areas. """ g = GeneralGraph() g.load("tests/TOY_graph.csv") - g.simulate_multi_area_perturbation(['area1', 'area2', 'area3']) + g.simulate_area_perturbation(['area1', 'area2', 'area3']) - self.check_shortest_paths(self, self.final_shp_multi_area_perturbation, g) + self.check_shortest_paths(self, self.final_multi_area_perturbation, g)