I have a graph called testg
testg = nx.Graph()
testg.add_nodes_from([1,2,3,4])
testg.add_edges_from([(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)])
I want to remove each node, using a loop, and see if the resulting graph is connected. I know it will be, but in my real problem that’s not the case. I think it makes sense to recreate the graph as a different object.
testg2 = nx.Graph()
testg2.add_nodes_from([1,2,3,4])
testg2.add_edges_from([(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)])
If I want to remove node 3 from the graph, and then put the graph back together, the below works:
testg2.remove_node(3)
testg2.add_node(3)
testg2.add_edges_from(testg.edges(3))
I’m wondering how to do this in a loop, and store the boolean results of is_connected in a list? In other words: remove edge –> is resulting graph connected? store response for each node –> put graph back together –> repeat.
nodez = list(range(1,5,1))
for i in nodez:
c = testg2.remove_node(i)
stor = nx.is_connected(c)
back = c.add_node(i)
beck = c.add_edges_from(testg.edges(i))
print (stor[i])
I don’t think I’m "putting the graph back together" correctly in the loop. I’m new to python, so nay help would be great. Thank you.
>Solution :
I would use a subgraph
to avoid the deletion/insertion.
You can easily do this with set operations:
out = {n: nx.is_connected(testg.subgraph(testg.nodes-{n})) for n in testg.nodes}
Output:
{1: True, 2: True, 3: True, 4: True}
Example with another graph:
testg = nx.Graph()
testg.add_nodes_from([1,2,3,4])
testg.add_edges_from([(1,2),(1,3),(1,4),(2,3)])
{n: nx.is_connected(testg.subgraph(testg.nodes-{n})) for n in testg.nodes}
# {1: False, 2: True, 3: True, 4: True}
graph:
generalization
If you want, you can also easily generalize to test "removal" of combinations of nodes (here n=2
nodes):
from itertools import combinations
n = 2
out = {c: nx.is_connected(testg.subgraph(testg.nodes-set(c)))
for c in combinations(testg.nodes, n)}
Output:
{(1, 2): True,
(1, 3): True,
(1, 4): True,
(2, 3): True,
(2, 4): True,
(3, 4): True}