Skill Tracer
Skills › Scientific Agent Skills › networkx › algorithms.md

algorithms.md

433 lines · skills/networkx/references/algorithms.md at 5f2bc03

Open on GitHub
1# NetworkX Graph Algorithms
2
3The snippets are API patterns using a supplied graph `G`; choose the required graph class before each section. Use finite numeric weights with explicit units. Missing weight attributes generally default to one. See [review.md](review.md) for release sources and executed examples.
4

NetworkX Graph Algorithms

The snippets are API patterns using a supplied graph G; choose the required graph class before each section. Use finite numeric weights with explicit units. Missing weight attributes generally default to one. See review.md for release sources and executed examples.

Raw lines 1 to 4
5## Shortest Paths
6

Shortest Paths

Raw lines 5 to 6
7### Single Source Shortest Paths
8```python
9# Dijkstra: distance/cost weights must be nonnegative
10path = nx.shortest_path(G, source=1, target=5, weight='weight')
11length = nx.shortest_path_length(G, source=1, target=5, weight='weight')
13# All shortest paths from source
14paths = nx.single_source_shortest_path(G, source=1)
15lengths = nx.single_source_shortest_path_length(G, source=1)
17# Bellman-Ford handles negative edges, but not a reachable negative cycle
18path = nx.bellman_ford_path(G, source=1, target=5, weight='weight')
19```

Single Source Shortest Paths

# Dijkstra: distance/cost weights must be nonnegative
path = nx.shortest_path(G, source=1, target=5, weight='weight')
length = nx.shortest_path_length(G, source=1, target=5, weight='weight')

# All shortest paths from source
paths = nx.single_source_shortest_path(G, source=1)
lengths = nx.single_source_shortest_path_length(G, source=1)

# Bellman-Ford handles negative edges, but not a reachable negative cycle
path = nx.bellman_ford_path(G, source=1, target=5, weight='weight')
Raw lines 7 to 20
21### All Pairs Shortest Paths
22```python
23# All pairs (returns iterator)
24for source, paths in nx.all_pairs_shortest_path(G):
25 print(f"From {source}: {paths}")
27# Floyd-Warshall weighted distances (all-pairs unweighted BFS is different)
28lengths = dict(nx.floyd_warshall(G, weight="distance"))
29```

All Pairs Shortest Paths

# All pairs (returns iterator)
for source, paths in nx.all_pairs_shortest_path(G):
    print(f"From {source}: {paths}")

# Floyd-Warshall weighted distances (all-pairs unweighted BFS is different)
lengths = dict(nx.floyd_warshall(G, weight="distance"))
Raw lines 21 to 30
31### Specialized Shortest Path Algorithms
32```python
33# A* algorithm (with heuristic)
34def heuristic(u, v):
35 # Zero is admissible without a proven geometric lower bound
36 return 0
38path = nx.astar_path(G, source=1, target=5, heuristic=heuristic, weight='weight')
40# Average shortest path length
41avg_length = nx.average_shortest_path_length(G)
42```
44Average path length requires a connected undirected or strongly connected directed graph. For disconnected inputs, report component coverage and define whether component summaries are node- or pair-weighted; do not silently discard unreachable pairs.

Specialized Shortest Path Algorithms

# A* algorithm (with heuristic)
def heuristic(u, v):
    # Zero is admissible without a proven geometric lower bound
    return 0

path = nx.astar_path(G, source=1, target=5, heuristic=heuristic, weight='weight')

# Average shortest path length
avg_length = nx.average_shortest_path_length(G)

Average path length requires a connected undirected or strongly connected directed graph. For disconnected inputs, report component coverage and define whether component summaries are node- or pair-weighted; do not silently discard unreachable pairs.

Raw lines 31 to 45
46## Connectivity

Connectivity

Raw lines 46 to 47
48### Connected Components (Undirected)
49```python
50# Check if connected
51is_connected = nx.is_connected(G)
53# Number of components
54num_components = nx.number_connected_components(G)
56# Get all components (returns iterator of sets)
57components = list(nx.connected_components(G))
58largest_component = max(components, key=len, default=set())
60# Get component containing specific node
61component = nx.node_connected_component(G, n=1)
62```

Connected Components (Undirected)

# Check if connected
is_connected = nx.is_connected(G)

# Number of components
num_components = nx.number_connected_components(G)

# Get all components (returns iterator of sets)
components = list(nx.connected_components(G))
largest_component = max(components, key=len, default=set())

# Get component containing specific node
component = nx.node_connected_component(G, n=1)
Raw lines 48 to 63
64### Strong/Weak Connectivity (Directed)
65```python
66# Strong connectivity (mutually reachable)
67is_strongly_connected = nx.is_strongly_connected(G)
68strong_components = list(nx.strongly_connected_components(G))
69largest_scc = max(strong_components, key=len, default=set())
71# Weak connectivity (ignoring direction)
72is_weakly_connected = nx.is_weakly_connected(G)
73weak_components = list(nx.weakly_connected_components(G))
75# Condensation (DAG of strongly connected components)
76condensed = nx.condensation(G)
77```

Strong/Weak Connectivity (Directed)

# Strong connectivity (mutually reachable)
is_strongly_connected = nx.is_strongly_connected(G)
strong_components = list(nx.strongly_connected_components(G))
largest_scc = max(strong_components, key=len, default=set())

# Weak connectivity (ignoring direction)
is_weakly_connected = nx.is_weakly_connected(G)
weak_components = list(nx.weakly_connected_components(G))

# Condensation (DAG of strongly connected components)
condensed = nx.condensation(G)
Raw lines 64 to 78
79### Cuts and Connectivity
80```python
81# Minimum node/edge cut
82min_node_cut = nx.minimum_node_cut(G, s=1, t=5)
83min_edge_cut = nx.minimum_edge_cut(G, s=1, t=5)
85# Node/edge connectivity
86node_connectivity = nx.node_connectivity(G)
87edge_connectivity = nx.edge_connectivity(G)
88```

Cuts and Connectivity

# Minimum node/edge cut
min_node_cut = nx.minimum_node_cut(G, s=1, t=5)
min_edge_cut = nx.minimum_edge_cut(G, s=1, t=5)

# Node/edge connectivity
node_connectivity = nx.node_connectivity(G)
edge_connectivity = nx.edge_connectivity(G)
Raw lines 79 to 89
90## Centrality Measures

Centrality Measures

Raw lines 90 to 91
92### Degree Centrality
93```python
94# Fraction of nodes each node is connected to
95degree_cent = nx.degree_centrality(G)
97# For directed graphs
98in_degree_cent = nx.in_degree_centrality(G)
99out_degree_cent = nx.out_degree_centrality(G)
100```

Degree Centrality

# Fraction of nodes each node is connected to
degree_cent = nx.degree_centrality(G)

# For directed graphs
in_degree_cent = nx.in_degree_centrality(G)
out_degree_cent = nx.out_degree_centrality(G)
Raw lines 92 to 101
102### Betweenness Centrality
103```python
104# Fraction of shortest paths passing through node
105betweenness = nx.betweenness_centrality(G, weight='weight')
107# Edge betweenness
108edge_betweenness = nx.edge_betweenness_centrality(G, weight='weight')
110# Approximate for large graphs
111approx_betweenness = nx.betweenness_centrality(
112 G, k=min(100, len(G)), weight="distance", seed=42
113) # Repeat seeds to assess approximation variability
114```
116Weighted betweenness interprets weights as distances and requires strictly positive values. Zero distances permit infinitely many equal-length paths; floating-point ties can alter counts. Document any justified scaling to integer costs.

Betweenness Centrality

# Fraction of shortest paths passing through node
betweenness = nx.betweenness_centrality(G, weight='weight')

# Edge betweenness
edge_betweenness = nx.edge_betweenness_centrality(G, weight='weight')

# Approximate for large graphs
approx_betweenness = nx.betweenness_centrality(
    G, k=min(100, len(G)), weight="distance", seed=42
)  # Repeat seeds to assess approximation variability

Weighted betweenness interprets weights as distances and requires strictly positive values. Zero distances permit infinitely many equal-length paths; floating-point ties can alter counts. Document any justified scaling to integer costs.

Raw lines 102 to 117
118### Closeness Centrality
119```python
120# Reciprocal of average shortest path length
121closeness = nx.closeness_centrality(G)
123# For disconnected graphs
124closeness = nx.closeness_centrality(G, wf_improved=True)
125```
127On a directed graph, closeness uses distances **into** each node. For outward reach use `nx.closeness_centrality(G.reverse(copy=False), distance="distance")`. `wf_improved=True` scales for the reachable fraction; it does not make disconnected graphs connected.

Closeness Centrality

# Reciprocal of average shortest path length
closeness = nx.closeness_centrality(G)

# For disconnected graphs
closeness = nx.closeness_centrality(G, wf_improved=True)

On a directed graph, closeness uses distances into each node. For outward reach use nx.closeness_centrality(G.reverse(copy=False), distance="distance"). wf_improved=True scales for the reachable fraction; it does not make disconnected graphs connected.

Raw lines 118 to 128
129### Eigenvector Centrality
130```python
131# Centrality based on connections to high-centrality nodes
132eigenvector = nx.eigenvector_centrality(G, max_iter=1000)
134# Katz centrality (variant with attenuation factor)
135katz = nx.katz_centrality(G, alpha=0.1, beta=1.0)
136```
138Eigenvector/Katz weights represent connection strength, unlike shortest-path costs. Directed eigenvector centrality uses incoming links; disconnected/reducible graphs can give nonunique or zero scores. Katz requires `alpha < 1 / spectral_radius(A)`, so 0.1 is only illustrative. Catch `PowerIterationFailedConvergence`; raising `max_iter` alone does not establish a meaningful solution.

Eigenvector Centrality

# Centrality based on connections to high-centrality nodes
eigenvector = nx.eigenvector_centrality(G, max_iter=1000)

# Katz centrality (variant with attenuation factor)
katz = nx.katz_centrality(G, alpha=0.1, beta=1.0)

Eigenvector/Katz weights represent connection strength, unlike shortest-path costs. Directed eigenvector centrality uses incoming links; disconnected/reducible graphs can give nonunique or zero scores. Katz requires alpha < 1 / spectral_radius(A), so 0.1 is only illustrative. Catch PowerIterationFailedConvergence; raising max_iter alone does not establish a meaningful solution.

Raw lines 129 to 139
140### PageRank
141```python
142# Google's PageRank algorithm
143pagerank = nx.pagerank(G, alpha=0.85)
145# Personalized PageRank
146personalization = {node: 1.0 if node in [1, 2] else 0.0 for node in G}
147if sum(personalization.values()) == 0:
148 raise ValueError("Personalization must include a node present in G")
149ppr = nx.pagerank(G, personalization=personalization)
150```
152PageRank uses outgoing transition strengths (nonnegative weights) and SciPy; it treats each undirected edge as two directed edges. Personalization must have positive total mass. Record `alpha`, weight, dangling-node handling and convergence tolerance.

PageRank

# Google's PageRank algorithm
pagerank = nx.pagerank(G, alpha=0.85)

# Personalized PageRank
personalization = {node: 1.0 if node in [1, 2] else 0.0 for node in G}
if sum(personalization.values()) == 0:
    raise ValueError("Personalization must include a node present in G")
ppr = nx.pagerank(G, personalization=personalization)

PageRank uses outgoing transition strengths (nonnegative weights) and SciPy; it treats each undirected edge as two directed edges. Personalization must have positive total mass. Record alpha, weight, dangling-node handling and convergence tolerance.

Raw lines 140 to 153
154## Clustering
156### Clustering Coefficients
157```python
158# Clustering coefficient for each node
159clustering = nx.clustering(G)
161# Average clustering coefficient
162avg_clustering = nx.average_clustering(G)
164# Weighted clustering
165weighted_clustering = nx.clustering(G, weight='weight')
166```

Clustering Coefficients

# Clustering coefficient for each node
clustering = nx.clustering(G)

# Average clustering coefficient
avg_clustering = nx.average_clustering(G)

# Weighted clustering
weighted_clustering = nx.clustering(G, weight='weight')
Raw lines 156 to 167
168### Transitivity
169```python
170# Overall clustering (ratio of triangles to triads)
171transitivity = nx.transitivity(G)
172```

Transitivity

# Overall clustering (ratio of triangles to triads)
transitivity = nx.transitivity(G)
Raw lines 168 to 173
174### Triangles
175```python
176# Count triangles per node
177triangles = nx.triangles(G)
179# Total number of triangles
180total_triangles = sum(triangles.values()) // 3
181```
183Clustering/triangles are not supported for multigraphs. `triangles` and transitivity examples here use simple undirected graphs; weighted clustering uses strength, not distance. State whether low-degree nodes count in an average (`count_zeros`).

Triangles

# Count triangles per node
triangles = nx.triangles(G)

# Total number of triangles
total_triangles = sum(triangles.values()) // 3

Clustering/triangles are not supported for multigraphs. triangles and transitivity examples here use simple undirected graphs; weighted clustering uses strength, not distance. State whether low-degree nodes count in an average (count_zeros).

Raw lines 174 to 184
185## Community Detection

Community Detection

Raw lines 185 to 186
187### Modularity-Based
188```python
189from networkx.algorithms import community
191# Greedy modularity maximization
192communities = community.greedy_modularity_communities(G, weight="strength", resolution=1.0)
194# Evaluate with the same weight and resolution as optimization
195modularity = community.modularity(G, communities, weight="strength", resolution=1.0)
196```

Modularity-Based

from networkx.algorithms import community

# Greedy modularity maximization
communities = community.greedy_modularity_communities(G, weight="strength", resolution=1.0)

# Evaluate with the same weight and resolution as optimization
modularity = community.modularity(G, communities, weight="strength", resolution=1.0)
Raw lines 187 to 197
198### Leiden (native in NetworkX 3.7)
199```python
200G = nx.barbell_graph(4, 1)
201communities = community.leiden_communities(
202 G, weight=None, metric="modularity", resolution=1.0, seed=42
204assert set().union(*communities) == set(G)
205assert sum(map(len, communities)) == len(G)
206score = community.modularity(G, communities, weight=None, resolution=1.0)
207```
209Leiden defaults to the **Constant Potts Model** (`metric="cpm"`), so specify the metric when comparing with modularity methods. Seeds, graph ordering, resolution and self-loops affect partitions. Modularity compares against a degree-based expectation; its value is not a p-value or evidence of biological function. Repeat seeds/resolutions, assess stability and use a justified null model.

Leiden (native in NetworkX 3.7)

G = nx.barbell_graph(4, 1)
communities = community.leiden_communities(
    G, weight=None, metric="modularity", resolution=1.0, seed=42
)
assert set().union(*communities) == set(G)
assert sum(map(len, communities)) == len(G)
score = community.modularity(G, communities, weight=None, resolution=1.0)

Leiden defaults to the Constant Potts Model (metric="cpm"), so specify the metric when comparing with modularity methods. Seeds, graph ordering, resolution and self-loops affect partitions. Modularity compares against a degree-based expectation; its value is not a p-value or evidence of biological function. Repeat seeds/resolutions, assess stability and use a justified null model.

Raw lines 198 to 210
211### Label Propagation
212```python
213# Fast community detection
214communities = community.label_propagation_communities(G)
215```

Label Propagation

# Fast community detection
communities = community.label_propagation_communities(G)
Raw lines 211 to 216
217### Girvan-Newman
218```python
219# Hierarchical community detection via edge betweenness
220import itertools
221comp = community.girvan_newman(G)
222limited = itertools.takewhile(lambda c: len(c) <= 10, comp)
223for communities in limited:
224 print(tuple(sorted(c) for c in communities))
225```

Girvan-Newman

# Hierarchical community detection via edge betweenness
import itertools
comp = community.girvan_newman(G)
limited = itertools.takewhile(lambda c: len(c) <= 10, comp)
for communities in limited:
    print(tuple(sorted(c) for c in communities))
Raw lines 217 to 226
227## Matching and Covering

Matching and Covering

Raw lines 227 to 228
229### Maximum Matching
230```python
231# Maximum cardinality, then maximum weight among equally large matchings
232matching = nx.max_weight_matching(G, maxcardinality=True)
234# Check if matching is valid
235is_matching = nx.is_matching(G, matching)
236is_perfect = nx.is_perfect_matching(G, matching)
237```

Maximum Matching

# Maximum cardinality, then maximum weight among equally large matchings
matching = nx.max_weight_matching(G, maxcardinality=True)

# Check if matching is valid
is_matching = nx.is_matching(G, matching)
is_perfect = nx.is_perfect_matching(G, matching)
Raw lines 229 to 238
239### Minimum Vertex/Edge Cover
240```python
241# Approximate weighted vertex cover (not guaranteed minimum)
242min_vertex_cover = nx.approximation.min_weighted_vertex_cover(G)
244# Approximate edge dominating set (not guaranteed minimum)
245min_edge_dom = nx.approximation.min_edge_dominating_set(G)
246```

Minimum Vertex/Edge Cover

# Approximate weighted vertex cover (not guaranteed minimum)
min_vertex_cover = nx.approximation.min_weighted_vertex_cover(G)

# Approximate edge dominating set (not guaranteed minimum)
min_edge_dom = nx.approximation.min_edge_dominating_set(G)
Raw lines 239 to 247
248## Tree Algorithms

Tree Algorithms

Raw lines 248 to 249
250### Minimum Spanning Tree
251```python
252# Kruskal's or Prim's algorithm
253mst = nx.minimum_spanning_tree(G, weight='weight')
255# Maximum spanning tree
256mst_max = nx.maximum_spanning_tree(G, weight='weight')
258# Potentially exponential: bound consumption on large graphs
259# Iterate over spanning trees in order of increasing total weight
260for tree in nx.SpanningTreeIterator(G):
261 process(tree)
262```

Minimum Spanning Tree

# Kruskal's or Prim's algorithm
mst = nx.minimum_spanning_tree(G, weight='weight')

# Maximum spanning tree
mst_max = nx.maximum_spanning_tree(G, weight='weight')

# Potentially exponential: bound consumption on large graphs
# Iterate over spanning trees in order of increasing total weight
for tree in nx.SpanningTreeIterator(G):
    process(tree)
Raw lines 250 to 263
264### Tree Properties
265```python
266# Check if graph is tree
267is_tree = nx.is_tree(G)
268is_forest = nx.is_forest(G)
270# For directed graphs
271T = nx.bfs_tree(G, source=1)
272is_arborescence = nx.is_arborescence(T)
273```
275Spanning-tree routines require undirected graphs; disconnected input yields a spanning **forest**. Do not interpret it as a connected route covering all nodes.

Tree Properties

# Check if graph is tree
is_tree = nx.is_tree(G)
is_forest = nx.is_forest(G)

# For directed graphs
T = nx.bfs_tree(G, source=1)
is_arborescence = nx.is_arborescence(T)

Spanning-tree routines require undirected graphs; disconnected input yields a spanning forest. Do not interpret it as a connected route covering all nodes.

Raw lines 264 to 276
277## Flow and Capacity

Flow and Capacity

Raw lines 277 to 278
279### Maximum Flow
280```python
281# Maximum flow value
282flow_value = nx.maximum_flow_value(G, 1, 5, capacity='capacity')
284# Maximum flow with flow dict
285flow_value, flow_dict = nx.maximum_flow(G, 1, 5, capacity='capacity')
287# Minimum cut
288cut_value, partition = nx.minimum_cut(G, 1, 5, capacity='capacity')
289```
291The maximum-flow/minimum-cut routines above do not accept multigraphs. Missing capacity means infinity; validate finite nonnegative capacities if that is the scientific model.

Maximum Flow

# Maximum flow value
flow_value = nx.maximum_flow_value(G, 1, 5, capacity='capacity')

# Maximum flow with flow dict
flow_value, flow_dict = nx.maximum_flow(G, 1, 5, capacity='capacity')

# Minimum cut
cut_value, partition = nx.minimum_cut(G, 1, 5, capacity='capacity')

The maximum-flow/minimum-cut routines above do not accept multigraphs. Missing capacity means infinity; validate finite nonnegative capacities if that is the scientific model.

Raw lines 279 to 292
293### Cost Flow
294```python
295# Minimum cost flow on a directed graph with integer units
296G = nx.DiGraph()
297G.add_node("s", demand=-2)
298G.add_node("t", demand=2)
299G.add_edge("s", "t", capacity=3, weight=4)
300flow_dict = nx.min_cost_flow(G, demand='demand', capacity='capacity', weight='weight')
301cost = nx.cost_of_flow(G, flow_dict, weight='weight')
302```
304Minimum-cost flow demands must sum to zero (negative = supply; positive = consumption). Use justified integer units for demands, capacities and costs; floating-point min-cost flow is not guaranteed reliable.

Cost Flow

# Minimum cost flow on a directed graph with integer units
G = nx.DiGraph()
G.add_node("s", demand=-2)
G.add_node("t", demand=2)
G.add_edge("s", "t", capacity=3, weight=4)
flow_dict = nx.min_cost_flow(G, demand='demand', capacity='capacity', weight='weight')
cost = nx.cost_of_flow(G, flow_dict, weight='weight')

Minimum-cost flow demands must sum to zero (negative = supply; positive = consumption). Use justified integer units for demands, capacities and costs; floating-point min-cost flow is not guaranteed reliable.

Raw lines 293 to 305
308### Finding Cycles
309```python
310# Simple cycles (directed or undirected; enumeration can be exponential)
311cycles = list(nx.simple_cycles(G))
313# Cycle basis (for undirected graphs)
314basis = nx.cycle_basis(G)
316# Check if acyclic
317is_dag = nx.is_directed_acyclic_graph(G)
318```

Finding Cycles

# Simple cycles (directed or undirected; enumeration can be exponential)
cycles = list(nx.simple_cycles(G))

# Cycle basis (for undirected graphs)
basis = nx.cycle_basis(G)

# Check if acyclic
is_dag = nx.is_directed_acyclic_graph(G)
Raw lines 308 to 319
320### Topological Sorting
321```python
322# Only for DAGs
323try:
324 topo_order = list(nx.topological_sort(G))
325except nx.NetworkXUnfeasible:
326 print("Graph has cycles")
328# All topological sorts
329all_topo = nx.all_topological_sorts(G)
330```

Topological Sorting

# Only for DAGs
try:
    topo_order = list(nx.topological_sort(G))
except nx.NetworkXUnfeasible:
    print("Graph has cycles")

# All topological sorts
all_topo = nx.all_topological_sorts(G)
Raw lines 320 to 331
332## Cliques
334### Finding Cliques
335```python
336# All maximal cliques
337cliques = list(nx.find_cliques(G))
339# Maximum clique (NP-complete, approximate)
340max_clique = nx.approximation.max_clique(G)
342# Clique number (nx.graph_clique_number was removed in NetworkX 3.0)
343clique_number = max((len(c) for c in nx.find_cliques(G)), default=0)
345# Size of the largest maximal clique containing each node
346clique_sizes = nx.node_clique_number(G)
347```

Finding Cliques

# All maximal cliques
cliques = list(nx.find_cliques(G))

# Maximum clique (NP-complete, approximate)
max_clique = nx.approximation.max_clique(G)

# Clique number (nx.graph_clique_number was removed in NetworkX 3.0)
clique_number = max((len(c) for c in nx.find_cliques(G)), default=0)

# Size of the largest maximal clique containing each node
clique_sizes = nx.node_clique_number(G)
Raw lines 334 to 348
349## Graph Coloring

Graph Coloring

Raw lines 349 to 350
351### Node Coloring
352```python
353# Greedy coloring
354coloring = nx.greedy_color(G, strategy='largest_first')
356# Different strategies: 'largest_first', 'smallest_last', 'random_sequential'
357coloring = nx.greedy_color(G, strategy='smallest_last')
358```

Node Coloring

# Greedy coloring
coloring = nx.greedy_color(G, strategy='largest_first')

# Different strategies: 'largest_first', 'smallest_last', 'random_sequential'
coloring = nx.greedy_color(G, strategy='smallest_last')
Raw lines 351 to 359
360## Isomorphism
362### Graph Isomorphism
363```python
364# Check if graphs are isomorphic
365is_isomorphic = nx.is_isomorphic(G1, G2)
367# Get isomorphism mapping
368from networkx.algorithms import isomorphism
369GM = isomorphism.GraphMatcher(G1, G2)
370if GM.is_isomorphic():
371 mapping = GM.mapping
372```

Graph Isomorphism

# Check if graphs are isomorphic
is_isomorphic = nx.is_isomorphic(G1, G2)

# Get isomorphism mapping
from networkx.algorithms import isomorphism
GM = isomorphism.GraphMatcher(G1, G2)
if GM.is_isomorphic():
    mapping = GM.mapping
Raw lines 362 to 373
374### Subgraph Isomorphism
375```python
376# Search for an induced copy of pattern G2 inside host G1
377GM = isomorphism.GraphMatcher(G1, G2) # DiGraphMatcher for directed graphs
378is_subgraph_iso = GM.subgraph_is_isomorphic()
379# Use GM.subgraph_is_monomorphic() when extra host edges are allowed
380```
382By default isomorphism ignores attributes. Supply `node_match`/`edge_match` when identity depends on labels, types or weights; use the matching class for directed/multigraph inputs.

Subgraph Isomorphism

# Search for an induced copy of pattern G2 inside host G1
GM = isomorphism.GraphMatcher(G1, G2)  # DiGraphMatcher for directed graphs
is_subgraph_iso = GM.subgraph_is_isomorphic()
# Use GM.subgraph_is_monomorphic() when extra host edges are allowed

By default isomorphism ignores attributes. Supply node_match/edge_match when identity depends on labels, types or weights; use the matching class for directed/multigraph inputs.

Raw lines 374 to 383
384## Traversal Algorithms

Traversal Algorithms

Raw lines 384 to 385
386### Depth-First Search (DFS)
387```python
388# DFS edges
389dfs_edges = list(nx.dfs_edges(G, source=1))
391# DFS tree
392dfs_tree = nx.dfs_tree(G, source=1)
394# DFS predecessors
395dfs_pred = nx.dfs_predecessors(G, source=1)
397# Preorder and postorder
398preorder = list(nx.dfs_preorder_nodes(G, source=1))
399postorder = list(nx.dfs_postorder_nodes(G, source=1))
400```

Depth-First Search (DFS)

# DFS edges
dfs_edges = list(nx.dfs_edges(G, source=1))

# DFS tree
dfs_tree = nx.dfs_tree(G, source=1)

# DFS predecessors
dfs_pred = nx.dfs_predecessors(G, source=1)

# Preorder and postorder
preorder = list(nx.dfs_preorder_nodes(G, source=1))
postorder = list(nx.dfs_postorder_nodes(G, source=1))
Raw lines 386 to 401
402### Breadth-First Search (BFS)
403```python
404# BFS edges
405bfs_edges = list(nx.bfs_edges(G, source=1))
407# BFS tree
408bfs_tree = nx.bfs_tree(G, source=1)
410# BFS predecessors and successors
411# bfs_predecessors is deprecated in 3.7; these are BFS tree parents
412bfs_pred = {child: parent for parent, child in nx.bfs_edges(G, source=1)}
413bfs_succ = nx.bfs_successors(G, source=1)
414```

Breadth-First Search (BFS)

# BFS edges
bfs_edges = list(nx.bfs_edges(G, source=1))

# BFS tree
bfs_tree = nx.bfs_tree(G, source=1)

# BFS predecessors and successors
# bfs_predecessors is deprecated in 3.7; these are BFS tree parents
bfs_pred = {child: parent for parent, child in nx.bfs_edges(G, source=1)}
bfs_succ = nx.bfs_successors(G, source=1)
Raw lines 402 to 415
416## Efficiency Considerations

Efficiency Considerations

Raw lines 416 to 417
418### Algorithm Complexity
419- Many algorithms have parameters to control computation time
420- For large graphs, consider approximate algorithms
421- Use `k` parameter to sample nodes in centrality calculations
422- Set `max_iter` for iterative algorithms

Algorithm Complexity

  • Many algorithms have parameters to control computation time
  • For large graphs, consider approximate algorithms
  • Use k parameter to sample nodes in centrality calculations
  • Set max_iter for iterative algorithms
Raw lines 418 to 423
424### Memory Usage
425- Iterator-based functions (e.g., `nx.simple_cycles()`) save memory
426- Convert to list only when necessary
427- Use generators for large result sets

Memory Usage

  • Iterator-based functions (e.g., nx.simple_cycles()) save memory
  • Convert to list only when necessary
  • Use generators for large result sets
Raw lines 424 to 428
429### Numerical Precision
430When using weighted algorithms with floating-point numbers, results are approximate. Consider:
431- Using integer weights when possible
432- Setting appropriate tolerance parameters
433- Being aware of accumulated rounding errors in iterative algorithms

Numerical Precision

When using weighted algorithms with floating-point numbers, results are approximate. Consider:

  • Using integer weights when possible
  • Setting appropriate tolerance parameters
  • Being aware of accumulated rounding errors in iterative algorithms
Raw lines 429 to 433