__init__.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. r"""
  2. Compressed sparse graph routines (:mod:`scipy.sparse.csgraph`)
  3. ==============================================================
  4. .. currentmodule:: scipy.sparse.csgraph
  5. Fast graph algorithms based on sparse matrix representations.
  6. Contents
  7. --------
  8. .. autosummary::
  9. :toctree: generated/
  10. connected_components -- determine connected components of a graph
  11. laplacian -- compute the laplacian of a graph
  12. shortest_path -- compute the shortest path between points on a positive graph
  13. dijkstra -- use Dijkstra's algorithm for shortest path
  14. floyd_warshall -- use the Floyd-Warshall algorithm for shortest path
  15. bellman_ford -- use the Bellman-Ford algorithm for shortest path
  16. johnson -- use Johnson's algorithm for shortest path
  17. yen -- use Yen's algorithm for K-shortest paths between to nodes.
  18. breadth_first_order -- compute a breadth-first order of nodes
  19. depth_first_order -- compute a depth-first order of nodes
  20. breadth_first_tree -- construct the breadth-first tree from a given node
  21. depth_first_tree -- construct a depth-first tree from a given node
  22. minimum_spanning_tree -- construct the minimum spanning tree of a graph
  23. reverse_cuthill_mckee -- compute permutation for reverse Cuthill-McKee ordering
  24. maximum_flow -- solve the maximum flow problem for a graph
  25. maximum_bipartite_matching -- compute a maximum matching of a bipartite graph
  26. min_weight_full_bipartite_matching - compute a minimum weight full matching of a bipartite graph
  27. structural_rank -- compute the structural rank of a graph
  28. NegativeCycleError
  29. .. autosummary::
  30. :toctree: generated/
  31. construct_dist_matrix
  32. csgraph_from_dense
  33. csgraph_from_masked
  34. csgraph_masked_from_dense
  35. csgraph_to_dense
  36. csgraph_to_masked
  37. reconstruct_path
  38. Graph Representations
  39. ---------------------
  40. This module uses graphs which are stored in a matrix format. A
  41. graph with N nodes can be represented by an (N x N) adjacency matrix G.
  42. If there is a connection from node i to node j, then G[i, j] = w, where
  43. w is the weight of the connection. For nodes i and j which are
  44. not connected, the value depends on the representation:
  45. - for dense array representations, non-edges are represented by
  46. G[i, j] = 0, infinity, or NaN.
  47. - for dense masked representations (of type np.ma.MaskedArray), non-edges
  48. are represented by masked values. This can be useful when graphs with
  49. zero-weight edges are desired.
  50. - for sparse array representations, non-edges are represented by
  51. non-entries in the matrix. This sort of sparse representation also
  52. allows for edges with zero weights.
  53. As a concrete example, imagine that you would like to represent the following
  54. undirected graph::
  55. G
  56. (0)
  57. / \
  58. 1 2
  59. / \
  60. (2) (1)
  61. This graph has three nodes, where node 0 and 1 are connected by an edge of
  62. weight 2, and nodes 0 and 2 are connected by an edge of weight 1.
  63. We can construct the dense, masked, and sparse representations as follows,
  64. keeping in mind that an undirected graph is represented by a symmetric matrix::
  65. >>> import numpy as np
  66. >>> G_dense = np.array([[0, 2, 1],
  67. ... [2, 0, 0],
  68. ... [1, 0, 0]])
  69. >>> G_masked = np.ma.masked_values(G_dense, 0)
  70. >>> from scipy.sparse import csr_array
  71. >>> G_sparse = csr_array(G_dense)
  72. This becomes more difficult when zero edges are significant. For example,
  73. consider the situation when we slightly modify the above graph::
  74. G2
  75. (0)
  76. / \
  77. 0 2
  78. / \
  79. (2) (1)
  80. This is identical to the previous graph, except nodes 0 and 2 are connected
  81. by an edge of zero weight. In this case, the dense representation above
  82. leads to ambiguities: how can non-edges be represented if zero is a meaningful
  83. value? In this case, either a masked or sparse representation must be used
  84. to eliminate the ambiguity::
  85. >>> import numpy as np
  86. >>> G2_data = np.array([[np.inf, 2, 0 ],
  87. ... [2, np.inf, np.inf],
  88. ... [0, np.inf, np.inf]])
  89. >>> G2_masked = np.ma.masked_invalid(G2_data)
  90. >>> from scipy.sparse.csgraph import csgraph_from_dense
  91. >>> # G2_sparse = csr_array(G2_data) would give the wrong result
  92. >>> G2_sparse = csgraph_from_dense(G2_data, null_value=np.inf)
  93. >>> G2_sparse.data
  94. array([ 2., 0., 2., 0.])
  95. Here we have used a utility routine from the csgraph submodule in order to
  96. convert the dense representation to a sparse representation which can be
  97. understood by the algorithms in submodule. By viewing the data array, we
  98. can see that the zero values are explicitly encoded in the graph.
  99. Directed vs. undirected
  100. ^^^^^^^^^^^^^^^^^^^^^^^
  101. Matrices may represent either directed or undirected graphs. This is
  102. specified throughout the csgraph module by a boolean keyword. Graphs are
  103. assumed to be directed by default. In a directed graph, traversal from node
  104. i to node j can be accomplished over the edge G[i, j], but not the edge
  105. G[j, i]. Consider the following dense graph::
  106. >>> import numpy as np
  107. >>> G_dense = np.array([[0, 1, 0],
  108. ... [2, 0, 3],
  109. ... [0, 4, 0]])
  110. When ``directed=True`` we get the graph::
  111. ---1--> ---3-->
  112. (0) (1) (2)
  113. <--2--- <--4---
  114. In a non-directed graph, traversal from node i to node j can be
  115. accomplished over either G[i, j] or G[j, i]. If both edges are not null,
  116. and the two have unequal weights, then the smaller of the two is used.
  117. So for the same graph, when ``directed=False`` we get the graph::
  118. (0)--1--(1)--3--(2)
  119. Note that a symmetric matrix will represent an undirected graph, regardless
  120. of whether the 'directed' keyword is set to True or False. In this case,
  121. using ``directed=True`` generally leads to more efficient computation.
  122. The routines in this module accept as input either scipy.sparse representations
  123. (csr, csc, or lil format), masked representations, or dense representations
  124. with non-edges indicated by zeros, infinities, and NaN entries.
  125. """ # noqa: E501
  126. __docformat__ = "restructuredtext en"
  127. __all__ = ['connected_components',
  128. 'laplacian',
  129. 'shortest_path',
  130. 'floyd_warshall',
  131. 'dijkstra',
  132. 'bellman_ford',
  133. 'johnson',
  134. 'yen',
  135. 'breadth_first_order',
  136. 'depth_first_order',
  137. 'breadth_first_tree',
  138. 'depth_first_tree',
  139. 'minimum_spanning_tree',
  140. 'reverse_cuthill_mckee',
  141. 'maximum_flow',
  142. 'maximum_bipartite_matching',
  143. 'min_weight_full_bipartite_matching',
  144. 'structural_rank',
  145. 'construct_dist_matrix',
  146. 'reconstruct_path',
  147. 'csgraph_masked_from_dense',
  148. 'csgraph_from_dense',
  149. 'csgraph_from_masked',
  150. 'csgraph_to_dense',
  151. 'csgraph_to_masked',
  152. 'NegativeCycleError']
  153. from ._laplacian import laplacian
  154. from ._shortest_path import (
  155. shortest_path, floyd_warshall, dijkstra, bellman_ford, johnson, yen,
  156. NegativeCycleError
  157. )
  158. from ._traversal import (
  159. breadth_first_order, depth_first_order, breadth_first_tree,
  160. depth_first_tree, connected_components
  161. )
  162. from ._min_spanning_tree import minimum_spanning_tree
  163. from ._flow import maximum_flow
  164. from ._matching import (
  165. maximum_bipartite_matching, min_weight_full_bipartite_matching
  166. )
  167. from ._reordering import reverse_cuthill_mckee, structural_rank
  168. from ._tools import (
  169. construct_dist_matrix, reconstruct_path, csgraph_from_dense,
  170. csgraph_to_dense, csgraph_masked_from_dense, csgraph_from_masked,
  171. csgraph_to_masked
  172. )
  173. from scipy._lib._testutils import PytestTester
  174. test = PytestTester(__name__)
  175. del PytestTester