13

according to networkx documentation, connected_component_subgraphs(G) returns a sorted list of all components. Thus the very first one should be the largest component.

However, when I try to get the largest component of a graph G using the example code on the documentation page

G=nx.path_graph(4)
G.add_edge(5,6)
H=nx.connected_component_subgraphs(G)[0]

I get

TypeError: 'generator' object has no attribute '__getitem__'

It used to work on my other computer with earlier versions of networkx (1.7 I think, not 100% sure)

Now I am using a different computer with python 2.7.7 and networkx 1.9. Is it a version problem?

I have written a small function with a couple lines myself to find the largest component, just wondering why this error came out.

BTW, I can get the components by converting the generator object to a list.

components = [comp for comp in nx.connected_components(G)]

But the list is not sorted by component size as stated in the documentation.

example:

G = nx.Graph()
G.add_edges_from([(1,2),(1,3),(4,5)])
G.add_nodes_from(range(6,20))
components = [comp for comp in nx.connected_components(G)]
component_size = [len(comp) for comp in components]
print G.number_of_nodes(), G.number_of_edges(), component_size

G = nx.Graph()
G.add_edges_from([(1000,2000),(1000,3000),(4000,5000)])
G.add_nodes_from(range(6,20))
components = [comp for comp in nx.connected_components(G)]
component_size = [len(comp) for comp in components]
print G.number_of_nodes(), G.number_of_edges(), component_size

output:

19 3 [3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
19 3 [2, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

looks like when the node names are large numbers and when there are a bunch of single nodes, the returned subgraphs are not sorted properly

sophiadw
  • 557
  • 3
  • 10
  • The components in your example are returned in order of size (largest to smallest) on my machine, using NetworkX 1.9. This matches [the documentation](http://networkx.lanl.gov/reference/generated/networkx.algorithms.components.connected.connected_component_subgraphs.html#networkx.algorithms.components.connected.connected_component_subgraphs) which says the components will be returned in descending order by size. – mdml Jun 23 '14 at 20:44
  • Aside: if you want to materialize a generator into a `list`, simply call `list`, e.g. `list(nx.connected_components(G))`. If you only want the first element yielded by the generator, you can use `next`, e.g. `next(nx.connected_components(G))`. – DSM Jun 23 '14 at 20:46
  • Thanks @DSM! I found how to get elements from generator here. http://stackoverflow.com/questions/12556090/how-can-i-cannot-index-into-the-values-list-of-reduce – sophiadw Jun 23 '14 at 21:41
  • @mdml I edited my post to put in an example – sophiadw Jun 23 '14 at 21:45
  • @sophiadw: the example in your post also works perfectly for me. – mdml Jun 23 '14 at 22:52
  • `print pkg_resources.get_distribution("networkx").version` gives me 1.9rc1, did I get the wrong version? – sophiadw Jun 23 '14 at 23:20
  • btw, do you get error msg when using `nx.connected_component_subgraphs(G)[0]`? – sophiadw Jun 23 '14 at 23:22

2 Answers2

19

The networkx-1.9 documentation is here http://networkx.github.io/documentation/networkx-1.9/reference/generated/networkx.algorithms.components.connected.connected_components.html#networkx.algorithms.components.connected.connected_components

The interface was changed to return a generator (as you figured out). The example in the documentation shows how to do what you ask.

Generate a sorted list of connected components, largest first.

>> G = nx.path_graph(4)
>>> G.add_path([10, 11, 12])
>>> sorted(nx.connected_components(G), key = len, reverse=True)
[[0, 1, 2, 3], [10, 11, 12]]

or

>>> sorted(nx.connected_component_subgraphs(G), key = len, reverse=True)
Aric
  • 24,511
  • 5
  • 78
  • 77
  • Thanks! so the sorted feature IS taken away in 1.9 – sophiadw Jun 24 '14 at 14:01
  • Yes, the connected components functions now longer return lists or sorted lists. The change is documented here http://networkx.github.io/documentation/networkx-1.9/reference/api_1.9.html#miscellaneous-changes – Aric Jun 24 '14 at 18:23
  • Just run into this. I expected to get actual components (immediately accessible), not a "generators". Having to go through `sorted` is quite unintuitive, so thanks for the answer. – Agostino Mar 20 '15 at 03:24
  • http://stackoverflow.com/a/26105849/194586 provides a more efficient method if you just want the giant (largest) component: replace `sorted(..., reverse=True)` with `max(...)`. `max()` also takes a `key` kwarg which you'd keep as `len`. – Nick T Nov 19 '15 at 07:21
6

As for version 2.4: nx.connected_component_subgraphs(G) is removed.

Instead to get the same result use:

connected_subgraphs = [G.subgraph(cc) for cc in nx.connected_components(G)]

And to get the giant component:

gcc = max(nx.connected_components(G), key=len)
giantC = G.subgraph(gcc)
willcrack
  • 1,794
  • 11
  • 20