Skip to content

Commit

Permalink
Delete multiple nodes (#40)
Browse files Browse the repository at this point in the history
* Add multiple element perturbation list

* Delete SOURCEs and USERs from list if damaged

* Change output accordingly

* Fix typo in simulate element perturbation docstring

* Move lst0 append after if..else

* Fix spaces alignment
  • Loading branch information
martinateruzzi committed Nov 13, 2020
1 parent ec4b875 commit 32fe624
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 159 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from,to,final_simple_path,final_shortest_path,final_shortest_path_length,final_pair_efficiency,area,ids,original_simple path,original_shortest_path_length,original_pair_efficiency,original_shortest_path
1,18,NO_PATH,NO_PATH,NO_PATH,NO_PATH,area1,118,"[['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '14', '18'], ['1', '3', '5', '11', '19', '12', '13', '14', '18'], ['1', '3', '5', '11', '19', '14', '18']]",6.0,0.16666666666666666,"['1', '3', '5', '11', '19', '14', '18']"
1,18,,,,,,118,"[['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '14', '18'], ['1', '3', '5', '11', '19', '12', '13', '14', '18'], ['1', '3', '5', '11', '19', '14', '18']]",6.0,0.16666666666666666,"['1', '3', '5', '11', '19', '14', '18']"
15,18,"[['15', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['15', '9', '16', '17', '10', '11', '19', '14', '18']]","['15', '9', '16', '17', '10', '11', '19', '14', '18']",8.0,0.125,area3,1518,"[['15', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['15', '9', '16', '17', '10', '11', '19', '14', '18']]",8.0,0.125,"['15', '9', '16', '17', '10', '11', '19', '14', '18']"
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from,to,final_simple_path,final_shortest_path,final_shortest_path_length,final_pair_efficiency,area,ids,original_simple path,original_shortest_path_length,original_pair_efficiency,original_shortest_path
1,18,NO_PATH,NO_PATH,NO_PATH,NO_PATH,area1,118,"[['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '14', '18'], ['1', '3', '5', '11', '19', '12', '13', '14', '18'], ['1', '3', '5', '11', '19', '14', '18']]",6.0,0.16666666666666666,"['1', '3', '5', '11', '19', '14', '18']"
1,18,,,,,,118,"[['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['1', '2', '4', '6', '8', '9', '16', '17', '10', '11', '19', '14', '18'], ['1', '3', '5', '11', '19', '12', '13', '14', '18'], ['1', '3', '5', '11', '19', '14', '18']]",6.0,0.16666666666666666,"['1', '3', '5', '11', '19', '14', '18']"
15,18,"[['15', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['15', '9', '16', '17', '10', '11', '19', '14', '18']]","['15', '9', '16', '17', '10', '11', '19', '14', '18']",8.0,0.125,area3,1518,"[['15', '9', '16', '17', '10', '11', '19', '12', '13', '14', '18'], ['15', '9', '16', '17', '10', '11', '19', '14', '18']]",8.0,0.125,"['15', '9', '16', '17', '10', '11', '19', '14', '18']"
284 changes: 127 additions & 157 deletions grape/general_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,10 @@ def load(self, filename):
self.Service = nx.get_edge_attributes(self, 'weight')

self.services_SOURCE = []
self.services_HUB = []
self.services_USER = []
for id, Type in self.Type.items():
if Type == "SOURCE":
self.services_SOURCE.append(id)
elif Type == "HUB":
self.services_HUB.append(id)
elif Type == "USER":
self.services_USER.append(id)

Expand Down Expand Up @@ -915,77 +912,39 @@ def check_before(self):
self.global_efficiency()
self.local_efficiency()

for ii in self.services_SOURCE:
i = list(self.Mark.keys())[list(self.Mark.values()).index(ii)]
for jj in self.services_USER:
j = list(self.Mark.keys())[list(self.Mark.values()).index(jj)]
if i in self.nodes() and j in self.nodes():
if nx.has_path(self, i, j):

osip = list(nx.all_simple_paths(self, i, j))
oshp = self.nodes[i]["shortest_path"][j]
oshpl = self.nodes[i]["shpath_length"][j]
oeff = 1 / oshpl
ids = ii + jj

self.lst0.append({
'from':
ii,
'to':
jj,
'original_shortest_path_length':
oshpl,
'original_shortest_path':
oshp,
'original_simple path':
osip,
'original_pair_efficiency':
oeff,
'ids':
ids
})

else:
oshpl = "NO_PATH"
osip = "NO_PATH"
oshp = "NO_PATH"
oeff = "NO_PATH"
ids = ii + jj

self.lst0.append({
'from':
ii,
'to':
jj,
'original_shortest_path_length':
oshpl,
'original_shortest_path':
oshp,
'original_simple path':
osip,
'original_pair_efficiency':
oeff,
'ids':
ids
})

else:

oshpl = "NO_PATH"
osip = "NO_PATH"
oshp = "NO_PATH"
oeff = "NO_PATH"
ids = ii + jj

self.lst0.append({
'from': ii,
'to': jj,
'original_shortest_path_length': oshpl,
'original_shortest_path': oshp,
'original_simple path': osip,
'original_pair_efficiency': oeff,
'ids': ids
})
for source in self.services_SOURCE:
for user in self.services_USER:
if nx.has_path(self, source, user):

osip = list(nx.all_simple_paths(self, source, user))
oshp = self.nodes[source]["shortest_path"][user]
oshpl = self.nodes[source]["shpath_length"][user]
oeff = 1 / oshpl
ids = source + user

else:
oshpl = "NO_PATH"
osip = "NO_PATH"
oshp = "NO_PATH"
oeff = "NO_PATH"
ids = source + user

self.lst0.append({
'from':
source,
'to':
user,
'original_shortest_path_length':
oshpl,
'original_shortest_path':
oshp,
'original_simple path':
osip,
'original_pair_efficiency':
oeff,
'ids':
ids
})

def check_after(self):
"""
Expand All @@ -1001,78 +960,65 @@ def check_after(self):
self.global_efficiency()
self.local_efficiency()

for nn in self.services_SOURCE:
n = list(self.Mark.keys())[list(self.Mark.values()).index(nn)]
for OODD in self.services_USER:
OD = list(self.Mark.keys())[list(
self.Mark.values()).index(OODD)]

if n in self.nodes() and OD in self.nodes():
if nx.has_path(self, n, OD):

sip = list(nx.all_simple_paths(self, n, OD))
for source in self.services_SOURCE:
for user in self.services_USER:
if nx.has_path(self, source, user):

set_sip = set(x for lst in sip for x in lst)
sip = list(nx.all_simple_paths(self, source, user))
set_sip = set(x for lst in sip for x in lst)

for node in set_sip:
for node in set_sip:

if self.D[node] in self.valv:
if self.D[node] in self.valv:

if node in self.newstatus:
if node in self.newstatus:

if self.newstatus[node] == "1":
if self.newstatus[node] == "1":

logging.debug(
"valve %s at node %s, state %s",
self.D[node], node, self.valv[self.D[node]]["1"])
logging.debug(
"valve %s at node %s, state %s",
self.D[node], node, self.valv[self.D[node]]["1"])

elif self.newstatus[node] == "0":
elif self.newstatus[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.valv[self.D[node]]["1"])
else:
if self.status[node] == "1":
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.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"])
elif self.status[node] == "0":
logging.debug(
"valve %s at node %s, state %s",
self.D[node], node, self.valv[self.D[node]]["1"])
elif self.status[node] == "0":

self.finalstatus.update({node: "1"})
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.valv[self.D[node]]["1"])
logging.debug(
"valve %s at node %s, from %s to %s",
self.D[node], node, self.valv[self.D[node]]["0"],
self.valv[self.D[node]]["1"])

shp = self.nodes[n]["shortest_path"][OD]
shpl = self.nodes[n]["shpath_length"][OD]
neff = 1 / shpl
ids = nn + OODD

else:

shpl = "NO_PATH"
sip = "NO_PATH"
shp = "NO_PATH"
neff = "NO_PATH"
ids = nn + OODD
shp = self.nodes[source]["shortest_path"][user]
shpl = self.nodes[source]["shpath_length"][user]
neff = 1 / shpl
ids = source + user

else:

shpl = "NO_PATH"
sip = "NO_PATH"
shp = "NO_PATH"
neff = "NO_PATH"
ids = nn + OODD
ids = source + user

self.lst.append({
'from': nn,
'area': self.area[n],
'to': OODD,
'from': source,
'area': self.area[source],
'to': user,
'final_shortest_path_length': shpl,
'final_shortest_path': shp,
'final_simple_path': sip,
Expand Down Expand Up @@ -1229,40 +1175,55 @@ def delete_a_node(self, node):
self.damaged_areas.add(self.nodes[n]["Area"])
self.remove_node(n)

def simulate_element_perturbation(self, node):
def simulate_element_perturbation(self, perturbed_nodes):
"""
Simulate a perturbation to a single element in
a plant and start to propagate the perturbation.
Simulate a perturbation of one or multiple nodes.
Nodes' "IntermediateStatus", "FinalStatus", "Mark_Status"
and "Status_Area" attributes are evaluated.
:param str node: the id of the node to remove
:param list perturbed_nodes: nodes(s) involved in the
perturbing event
.. note:: A perturbation, depending on the considered system,
may spread in all directions starting from the damaged
component(s) and may be affect nearby areas.
"""

if node in self.nodes():
for node in perturbed_nodes:

self.check_before()
self.closeness_centrality()
self.betweenness_centrality()
self.indegree_centrality()
self.outdegree_centrality()
self.degree_centrality()
self.copy_of_self1 = copy.deepcopy(self)
if node not in self.nodes():
print('The node ', node, ' is not in the graph')
print('Insert a valid node')
print("Valid nodes:", self.nodes())
sys.exit()

self.check_before()
self.closeness_centrality()
self.betweenness_centrality()
self.indegree_centrality()
self.outdegree_centrality()
self.degree_centrality()
self.copy_of_self1 = copy.deepcopy(self)

for node in perturbed_nodes:
self.delete_a_node(node)

self.lst = []
self.check_after()
self.service_paths_to_file("service_paths_element_perturbation.csv")
self.update_status(self.newstatus, "IntermediateStatus", self.bn)
self.update_status(self.finalstatus, "FinalStatus", self.bn)
self.update_areas(self.bn, self.damaged_areas)
self.graph_characterization_to_file("element_perturbation.csv")
deleted_nodes = set(self.copy_of_self1) - 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)

else:
print('The node ', node, 'is not in the graph.')
print('Insert a valid node')
del_users = [u for u in self.services_USER if u in deleted_nodes]
for u in del_users: self.services_USER.remove(u)

self.lst = []
self.check_after()
self.service_paths_to_file("service_paths_element_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)
self.graph_characterization_to_file("element_perturbation.csv")

def simulate_multi_area_perturbation(self, perturbed_areas):
"""
Expand All @@ -1271,16 +1232,20 @@ def simulate_multi_area_perturbation(self, perturbed_areas):
Nodes' "IntermediateStatus", "FinalStatus", "Mark_Status"
and "Status_Area" attributes are evaluated.
:param list perturbed_areas: area(s) in which the perturbing event
occurred
:param list perturbed_areas: area(s) involved in the
perturbing event
.. note:: A perturbation, depending on the considered system,
may spread in all directions starting from the damaged
component(s) and may be affect nearby areas
"""

nodes_in_area = []

for area in perturbed_areas:

if area not in list(self.area.values()):
print('The area is not in the graph')
print('The area ', area, ' is not in the graph')
print('Insert a valid area')
print("Valid areas:", set(self.area.values()))
sys.exit()
Expand All @@ -1302,14 +1267,19 @@ def simulate_multi_area_perturbation(self, perturbed_areas):
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)

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_users = [u for u in self.services_USER if u in deleted_nodes]
for u in del_users: self.services_USER.remove(u)

self.lst = []
self.check_after()
self.service_paths_to_file("service_paths_multi_area_perturbation.csv")
self.update_status(self.newstatus, "IntermediateStatus", nodes_in_area)
self.update_status(self.finalstatus, "FinalStatus", nodes_in_area)

deleted_nodes = set(self.copy_of_self1) - set(self)

self.update_status(self.newstatus, "IntermediateStatus", deleted_nodes)
self.update_status(self.finalstatus, "FinalStatus", deleted_nodes)
self.update_areas(deleted_nodes, self.damaged_areas)
self.graph_characterization_to_file("area_perturbation.csv")

Expand Down Expand Up @@ -1438,6 +1408,6 @@ def graph_characterization_to_file(self, filename):
g.load(sys.argv[1])

g.check_input_with_gephi()
g.simulate_element_perturbation("1")
g.simulate_element_perturbation(["1"])
#g.simulate_multi_area_perturbation(['area1'])
##g.simulate_multi_area_perturbation(['area1','area2','area3'])

0 comments on commit 32fe624

Please sign in to comment.