Following the idea in this answer, we can iterate over the combinations
of connected components and connect random pairs of nodes. The advantage of taking the combinations
, is that we only need to iterate once over the components, and we ensure that on each iteration, previously seen components are ignored, since in combinations
order does not matter, i.e. if we've seen the combination (1,2)
we won't be seing (2,1)
, which could lead to two components being connected through two different nodes, and possibly isolated from the rest of the graph.
So using a reduced version of your example:
G = nx.fast_gnp_random_graph(100,0.02,seed=1)
plt.figure(figsize=(12,6))
nx.draw(G, node_size=100, node_color='lightgreen')

import random
from itertools import combinations, groupby
components = dict(enumerate(nx.connected_components(G)))
components_combs = combinations(components.keys(), r=2)
for _, node_edges in groupby(components_combs, key=lambda x: x[0]):
node_edges = list(node_edges)
random_comps = random.choice(node_edges)
source = random.choice(list(components[random_comps[0]]))
target = random.choice(list(components[random_comps[1]]))
G.add_edge(source, target)
plt.figure(figsize=(12,6))
nx.draw(G, node_size=100, node_color='lightgreen')
