perfect_graph.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import itertools
  2. import networkx as nx
  3. from networkx.utils.decorators import not_implemented_for
  4. __all__ = ["is_perfect_graph"]
  5. @nx._dispatchable
  6. @not_implemented_for("directed")
  7. @not_implemented_for("multigraph")
  8. def is_perfect_graph(G):
  9. r"""Return True if G is a perfect graph, else False.
  10. A graph G is perfect if, for every induced subgraph H of G, the chromatic
  11. number of H equals the size of the largest clique in H.
  12. According to the **Strong Perfect Graph Theorem (SPGT)**:
  13. A graph is perfect if and only if neither the graph G nor its complement
  14. :math:`\overline{G}` contains an **induced odd hole** — an induced cycle of
  15. odd length at least five without chords.
  16. Parameters
  17. ----------
  18. G : NetworkX Graph
  19. The graph to check. Must be a finite, simple, undirected graph.
  20. Returns
  21. -------
  22. bool
  23. True if G is a perfect graph, else False.
  24. Notes
  25. -----
  26. This function uses a direct approach: cycle enumeration to detect
  27. chordless odd cycles in G and :math:`\overline{G}`. This implementation
  28. runs in exponential time in the worst case, since the number of chordless
  29. cycles can grow exponentially.
  30. The perfect-graph recognition problem is theoretically solvable in
  31. polynomial time. Chudnovsky *et al.* (2006) proved it can be solved in
  32. :math:`O(n^9)` time via a complex structural decomposition [1]_, [2]_.
  33. This implementation opts for a direct, transparent check rather than
  34. implementing that high-degree polynomial-time decomposition algorithm.
  35. See Also
  36. --------
  37. is_chordal, is_bipartite :
  38. Related checks for specific categories of perfect graphs, such as chordal
  39. graphs, and bipartite graphs.
  40. chordless_cycles :
  41. Used to detect "holes" in the graph
  42. References
  43. ----------
  44. .. [1] M. Chudnovsky, N. Robertson, P. Seymour, and R. Thomas,
  45. *The Strong Perfect Graph Theorem*,
  46. Annals of Mathematics, vol. 164, no. 1, pp. 51–229, 2006.
  47. https://doi.org/10.4007/annals.2006.164.51
  48. .. [2] M. Chudnovsky, G. Cornuéjols, X. Liu, P. Seymour, and K. Vušković,
  49. *Recognizing Berge Graphs*,
  50. Combinatorica 25(2): 143–186, 2005.
  51. DOI: 10.1007/s00493-005-0003-8
  52. Preprint available at:
  53. https://web.math.princeton.edu/~pds/papers/algexp/Bergealg.pdf
  54. """
  55. return not any(
  56. (len(c) >= 5) and (len(c) % 2 == 1)
  57. for c in itertools.chain(
  58. nx.chordless_cycles(G), nx.chordless_cycles(nx.complement(G))
  59. )
  60. )