clique.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. """Functions for computing large cliques and maximum independent sets."""
  2. import networkx as nx
  3. from networkx.algorithms.approximation import ramsey
  4. from networkx.utils import not_implemented_for
  5. __all__ = [
  6. "clique_removal",
  7. "max_clique",
  8. "large_clique_size",
  9. "maximum_independent_set",
  10. ]
  11. @not_implemented_for("directed")
  12. @not_implemented_for("multigraph")
  13. def maximum_independent_set(G):
  14. """Returns an approximate maximum independent set.
  15. Independent set or stable set is a set of vertices in a graph, no two of
  16. which are adjacent. That is, it is a set I of vertices such that for every
  17. two vertices in I, there is no edge connecting the two. Equivalently, each
  18. edge in the graph has at most one endpoint in I. The size of an independent
  19. set is the number of vertices it contains [1]_.
  20. A maximum independent set is a largest independent set for a given graph G
  21. and its size is denoted $\\alpha(G)$. The problem of finding such a set is called
  22. the maximum independent set problem and is an NP-hard optimization problem.
  23. As such, it is unlikely that there exists an efficient algorithm for finding
  24. a maximum independent set of a graph.
  25. The Independent Set algorithm is based on [2]_.
  26. Parameters
  27. ----------
  28. G : NetworkX graph
  29. Undirected graph
  30. Returns
  31. -------
  32. iset : Set
  33. The apx-maximum independent set
  34. Raises
  35. ------
  36. NetworkXNotImplemented
  37. If the graph is directed or is a multigraph.
  38. Notes
  39. -----
  40. Finds the $O(|V|/(log|V|)^2)$ apx of independent set in the worst case.
  41. References
  42. ----------
  43. .. [1] `Wikipedia: Independent set
  44. <https://en.wikipedia.org/wiki/Independent_set_(graph_theory)>`_
  45. .. [2] Boppana, R., & Halldórsson, M. M. (1992).
  46. Approximating maximum independent sets by excluding subgraphs.
  47. BIT Numerical Mathematics, 32(2), 180–196. Springer.
  48. """
  49. iset, _ = clique_removal(G)
  50. return iset
  51. @not_implemented_for("directed")
  52. @not_implemented_for("multigraph")
  53. def max_clique(G):
  54. r"""Find the Maximum Clique
  55. Finds the $O(|V|/(log|V|)^2)$ apx of maximum clique/independent set
  56. in the worst case.
  57. Parameters
  58. ----------
  59. G : NetworkX graph
  60. Undirected graph
  61. Returns
  62. -------
  63. clique : set
  64. The apx-maximum clique of the graph
  65. Raises
  66. ------
  67. NetworkXNotImplemented
  68. If the graph is directed or is a multigraph.
  69. Notes
  70. -----
  71. A clique in an undirected graph G = (V, E) is a subset of the vertex set
  72. `C \subseteq V` such that for every two vertices in C there exists an edge
  73. connecting the two. This is equivalent to saying that the subgraph
  74. induced by C is complete (in some cases, the term clique may also refer
  75. to the subgraph).
  76. A maximum clique is a clique of the largest possible size in a given graph.
  77. The clique number `\omega(G)` of a graph G is the number of
  78. vertices in a maximum clique in G. The intersection number of
  79. G is the smallest number of cliques that together cover all edges of G.
  80. https://en.wikipedia.org/wiki/Maximum_clique
  81. References
  82. ----------
  83. .. [1] Boppana, R., & Halldórsson, M. M. (1992).
  84. Approximating maximum independent sets by excluding subgraphs.
  85. BIT Numerical Mathematics, 32(2), 180–196. Springer.
  86. doi:10.1007/BF01994876
  87. """
  88. if G is None:
  89. raise ValueError("Expected NetworkX graph!")
  90. # finding the maximum clique in a graph is equivalent to finding
  91. # the independent set in the complementary graph
  92. cgraph = nx.complement(G)
  93. iset, _ = clique_removal(cgraph)
  94. return iset
  95. @not_implemented_for("directed")
  96. @not_implemented_for("multigraph")
  97. def clique_removal(G):
  98. r"""Repeatedly remove cliques from the graph.
  99. Results in a $O(|V|/(\log |V|)^2)$ approximation of maximum clique
  100. and independent set. Returns the largest independent set found, along
  101. with found maximal cliques.
  102. Parameters
  103. ----------
  104. G : NetworkX graph
  105. Undirected graph
  106. Returns
  107. -------
  108. max_ind_cliques : (set, list) tuple
  109. 2-tuple of Maximal Independent Set and list of maximal cliques (sets).
  110. Raises
  111. ------
  112. NetworkXNotImplemented
  113. If the graph is directed or is a multigraph.
  114. References
  115. ----------
  116. .. [1] Boppana, R., & Halldórsson, M. M. (1992).
  117. Approximating maximum independent sets by excluding subgraphs.
  118. BIT Numerical Mathematics, 32(2), 180–196. Springer.
  119. """
  120. graph = G.copy()
  121. c_i, i_i = ramsey.ramsey_R2(graph)
  122. cliques = [c_i]
  123. isets = [i_i]
  124. while graph:
  125. graph.remove_nodes_from(c_i)
  126. c_i, i_i = ramsey.ramsey_R2(graph)
  127. if c_i:
  128. cliques.append(c_i)
  129. if i_i:
  130. isets.append(i_i)
  131. # Determine the largest independent set as measured by cardinality.
  132. maxiset = max(isets, key=len)
  133. return maxiset, cliques
  134. @not_implemented_for("directed")
  135. @not_implemented_for("multigraph")
  136. def large_clique_size(G):
  137. """Find the size of a large clique in a graph.
  138. A *clique* is a subset of nodes in which each pair of nodes is
  139. adjacent. This function is a heuristic for finding the size of a
  140. large clique in the graph.
  141. Parameters
  142. ----------
  143. G : NetworkX graph
  144. Returns
  145. -------
  146. k: integer
  147. The size of a large clique in the graph.
  148. Raises
  149. ------
  150. NetworkXNotImplemented
  151. If the graph is directed or is a multigraph.
  152. Notes
  153. -----
  154. This implementation is from [1]_. Its worst case time complexity is
  155. :math:`O(n d^2)`, where *n* is the number of nodes in the graph and
  156. *d* is the maximum degree.
  157. This function is a heuristic, which means it may work well in
  158. practice, but there is no rigorous mathematical guarantee on the
  159. ratio between the returned number and the actual largest clique size
  160. in the graph.
  161. References
  162. ----------
  163. .. [1] Pattabiraman, Bharath, et al.
  164. "Fast Algorithms for the Maximum Clique Problem on Massive Graphs
  165. with Applications to Overlapping Community Detection."
  166. *Internet Mathematics* 11.4-5 (2015): 421--448.
  167. <https://doi.org/10.1080/15427951.2014.986778>
  168. See also
  169. --------
  170. :func:`networkx.algorithms.approximation.clique.max_clique`
  171. A function that returns an approximate maximum clique with a
  172. guarantee on the approximation ratio.
  173. :mod:`networkx.algorithms.clique`
  174. Functions for finding the exact maximum clique in a graph.
  175. """
  176. degrees = G.degree
  177. def _clique_heuristic(G, U, size, best_size):
  178. if not U:
  179. return max(best_size, size)
  180. u = max(U, key=degrees)
  181. U.remove(u)
  182. N_prime = {v for v in G[u] if degrees[v] >= best_size}
  183. return _clique_heuristic(G, U & N_prime, size + 1, best_size)
  184. best_size = 0
  185. nodes = (u for u in G if degrees[u] >= best_size)
  186. for u in nodes:
  187. neighbors = {v for v in G[u] if degrees[v] >= best_size}
  188. best_size = _clique_heuristic(G, neighbors, 1, best_size)
  189. return best_size