1"""Unary operations on graphs"""
2
3import networkx as nx
4
5__all__ = ["complement", "reverse"]
6
7
8@nx._dispatchable(returns_graph=True)
9def complement(G):
10 """Returns the graph complement of G.
11
12 Parameters
13 ----------
14 G : graph
15 A NetworkX graph
16
17 Returns
18 -------
19 GC : A new graph.
20
21 Notes
22 -----
23 Note that `complement` does not create self-loops and also
24 does not produce parallel edges for MultiGraphs.
25
26 Graph, node, and edge data are not propagated to the new graph.
27
28 Examples
29 --------
30 >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (3, 4), (3, 5)])
31 >>> G_complement = nx.complement(G)
32 >>> G_complement.edges() # This shows the edges of the complemented graph
33 EdgeView([(1, 4), (1, 5), (2, 4), (2, 5), (4, 5)])
34
35 """
36 R = G.__class__()
37 R.add_nodes_from(G)
38 R.add_edges_from(
39 ((n, n2) for n, nbrs in G.adjacency() for n2 in G if n2 not in nbrs if n != n2)
40 )
41 return R
42
43
44@nx._dispatchable(returns_graph=True)
45def reverse(G, copy=True):
46 """Returns the reverse directed graph of G.
47
48 Parameters
49 ----------
50 G : directed graph
51 A NetworkX directed graph
52 copy : bool
53 If True, then a new graph is returned. If False, then the graph is
54 reversed in place.
55
56 Returns
57 -------
58 H : directed graph
59 The reversed G.
60
61 Raises
62 ------
63 NetworkXError
64 If graph is undirected.
65
66 Examples
67 --------
68 >>> G = nx.DiGraph([(1, 2), (1, 3), (2, 3), (3, 4), (3, 5)])
69 >>> G_reversed = nx.reverse(G)
70 >>> G_reversed.edges()
71 OutEdgeView([(2, 1), (3, 1), (3, 2), (4, 3), (5, 3)])
72
73 """
74 if not G.is_directed():
75 raise nx.NetworkXError("Cannot reverse an undirected graph.")
76 else:
77 return G.reverse(copy=copy)