quotient_graph

quotient_graph(G, partition, edge_relation=None, node_data=None, edge_data=None, relabel=False, create_using=None)[source]

Returns the quotient graph of G under the specified equivalence relation on nodes.

Parameters:
  • G (NetworkX graph) – The graph for which to return the quotient graph with the specified node relation.

  • partition (function or list of sets) – If a function, this function must represent an equivalence relation on the nodes of G. It must take two arguments u and v and return True exactly when u and v are in the same equivalence class. The equivalence classes form the nodes in the returned graph.

    If a list of sets, the list must form a valid partition of the nodes of the graph. That is, each node must be in exactly one block of the partition.

  • edge_relation (Boolean function with two arguments) – This function must represent an edge relation on the blocks of G in the partition induced by node_relation. It must take two arguments, B and C, each one a set of nodes, and return True exactly when there should be an edge joining block B to block C in the returned graph.

    If edge_relation is not specified, it is assumed to be the following relation. Block B is related to block C if and only if some node in B is adjacent to some node in C, according to the edge set of G.

  • edge_data (function) – This function takes two arguments, B and C, each one a set of nodes, and must return a dictionary representing the edge data attributes to set on the edge joining B and C, should there be an edge joining B and C in the quotient graph (if no such edge occurs in the quotient graph as determined by edge_relation, then the output of this function is ignored).

    If the quotient graph would be a multigraph, this function is not applied, since the edge data from each edge in the graph G appears in the edges of the quotient graph.

  • node_data (function) – This function takes one argument, B, a set of nodes in G, and must return a dictionary representing the node data attributes to set on the node representing B in the quotient graph. If None, the following node attributes will be set:

    • ‘graph’, the subgraph of the graph G that this block represents,
    • ‘nnodes’, the number of nodes in this block,
    • ‘nedges’, the number of edges within this block,
    • ‘density’, the density of the subgraph of G that this block represents.
  • relabel (bool) – If True, relabel the nodes of the quotient graph to be nonnegative integers. Otherwise, the nodes are identified with frozenset instances representing the blocks given in partition.

  • create_using (NetworkX graph) – If specified, this must be an instance of a NetworkX graph class. The nodes and edges of the quotient graph will be added to this graph and returned. If not specified, the returned graph will have the same type as the input graph.

Returns:

The quotient graph of G under the equivalence relation specified by partition. If the partition were given as a list of set instances and relabel is False, each node will be a frozenset corresponding to the same set.

Return type:

NetworkX graph

Raises:

NetworkXException – If the given partition is not a valid partition of the nodes of G.

Examples

The quotient graph of the complete bipartite graph under the “same neighbors” equivalence relation is K_2. Under this relation, two nodes are equivalent if they are not adjacent but have the same neighbor set:

>>> import networkx as nx
>>> G = nx.complete_bipartite_graph(2, 3)
>>> same_neighbors = lambda u, v: (u not in G[v] and v not in G[u]
...                                and G[u] == G[v])
>>> Q = nx.quotient_graph(G, same_neighbors)
>>> K2 = nx.complete_graph(2)
>>> nx.is_isomorphic(Q, K2)
True

The quotient graph of a directed graph under the “same strongly connected component” equivalence relation is the condensation of the graph (see condensation()). This example comes from the Wikipedia article `Strongly connected component`_:

>>> import networkx as nx
>>> G = nx.DiGraph()
>>> edges = ['ab', 'be', 'bf', 'bc', 'cg', 'cd', 'dc', 'dh', 'ea',
...          'ef', 'fg', 'gf', 'hd', 'hf']
>>> G.add_edges_from(tuple(x) for x in edges)
>>> components = list(nx.strongly_connected_components(G))
>>> sorted(sorted(component) for component in components)
[['a', 'b', 'e'], ['c', 'd', 'h'], ['f', 'g']]
>>>
>>> C = nx.condensation(G, components)
>>> component_of = C.graph['mapping']
>>> same_component = lambda u, v: component_of[u] == component_of[v]
>>> Q = nx.quotient_graph(G, same_component)
>>> nx.is_isomorphic(C, Q)
True

Node identification can be represented as the quotient of a graph under the equivalence relation that places the two nodes in one block and each other node in its own singleton block:

>>> import networkx as nx
>>> K24 = nx.complete_bipartite_graph(2, 4)
>>> K34 = nx.complete_bipartite_graph(3, 4)
>>> C = nx.contracted_nodes(K34, 1, 2)
>>> nodes = {1, 2}
>>> is_contracted = lambda u, v: u in nodes and v in nodes
>>> Q = nx.quotient_graph(K34, is_contracted)
>>> nx.is_isomorphic(Q, C)
True
>>> nx.is_isomorphic(Q, K24)
True

The blockmodeling technique described in [1] can be implemented as a quotient graph:

>>> G = nx.path_graph(6)
>>> partition = [{0, 1}, {2, 3}, {4, 5}]
>>> M = nx.quotient_graph(G, partition, relabel=True)
>>> list(M.edges())
[(0, 1), (1, 2)]

References

[1]Patrick Doreian, Vladimir Batagelj, and Anuska Ferligoj. Generalized Blockmodeling. Cambridge University Press, 2004.