1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
"""Operations on many graphs.
"""
# Copyright (C) 2012 by
# Aric Hagberg <hagberg@lanl.gov>
# Dan Schult <dschult@colgate.edu>
# Pieter Swart <swart@lanl.gov>
# All rights reserved.
# BSD license.
try:
from itertools import izip_longest as zip_longest
except ImportError: # Python3 has zip_longest
from itertools import zip_longest
import networkx as nx
from networkx.utils import is_string_like
__author__ = """\n""".join([ 'Robert King <kingrobertking@gmail.com>',
'Aric Hagberg <aric.hagberg@gmail.com>'])
__all__ = ['union_all', 'compose_all', 'disjoint_union_all',
'intersection_all']
def union_all(graphs, rename=(None,) , name=None):
"""Return the union of all graphs.
The graphs must be disjoint, otherwise an exception is raised.
Parameters
----------
graphs : list of graphs
List of NetworkX graphs
rename : bool , default=(None, None)
Node names of G and H can be changed by specifying the tuple
rename=('G-','H-') (for example). Node "u" in G is then renamed
"G-u" and "v" in H is renamed "H-v".
name : string
Specify the name for the union graph@not_implemnted_for('direct
Returns
-------
U : a graph with the same type as the first graph in list
Notes
-----
To force a disjoint union with node relabeling, use
disjoint_union_all(G,H) or convert_node_labels_to integers().
Graph, edge, and node attributes are propagated to the union graph.
If a graph attribute is present in multiple graphs, then the value
from the last graph in the list with that attribute is used.
See Also
--------
union
disjoint_union_all
"""
graphs_names = zip_longest(graphs,rename)
U, gname = next(graphs_names)
for H,hname in graphs_names:
U = nx.union(U, H, (gname,hname),name=name)
gname = None
return U
def disjoint_union_all(graphs):
"""Return the disjoint union of all graphs.
This operation forces distinct integer node labels starting with 0
for the first graph in the list and numbering consecutively.
Parameters
----------
graphs : list
List of NetworkX graphs
Returns
-------
U : A graph with the same type as the first graph in list
Notes
-----
It is recommended that the graphs be either all directed or all undirected.
Graph, edge, and node attributes are propagated to the union graph.
If a graph attribute is present in multiple graphs, then the value
from the last graph in the list with that attribute is used.
"""
U = graphs.pop(0)
for H in graphs:
U = nx.disjoint_union(U, H)
return U
def compose_all(graphs, name=None):
"""Return the composition of all graphs.
Composition is the simple union of the node sets and edge sets.
The node sets of the supplied graphs need not be disjoint.
Parameters
----------
graphs : list
List of NetworkX graphs
name : string
Specify name for new graph
Returns
-------
C : A graph with the same type as the first graph in list
Notes
-----
It is recommended that the supplied graphs be either all directed or all
undirected.
Graph, edge, and node attributes are propagated to the union graph.
If a graph attribute is present in multiple graphs, then the value
from the last graph in the list with that attribute is used.
"""
C = graphs.pop(0)
for H in graphs:
C = nx.compose(C, H, name=name)
return C
def intersection_all(graphs):
"""Return a new graph that contains only the edges that exist in
all graphs.
All supplied graphs must have the same node set.
Parameters
----------
graphs_list : list
List of NetworkX graphs
Returns
-------
R : A new graph with the same type as the first graph in list
Notes
-----
Attributes from the graph, nodes, and edges are not copied to the new
graph.
"""
R = graphs.pop(0)
for H in graphs:
R = nx.intersection(R, H)
return R
|