cmComputeComponentGraph.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #pragma once
  4. #include "cmConfigure.h" // IWYU pragma: keep
  5. #include <stack>
  6. #include <vector>
  7. #include "cmGraphAdjacencyList.h"
  8. /** \class cmComputeComponentGraph
  9. * \brief Analyze a graph to determine strongly connected components.
  10. *
  11. * Convert a directed graph into a directed acyclic graph whose nodes
  12. * correspond to strongly connected components of the original graph.
  13. *
  14. * We use Tarjan's algorithm to enumerate the components efficiently.
  15. * An advantage of this approach is that the components are identified
  16. * in a topologically sorted order.
  17. */
  18. class cmComputeComponentGraph
  19. {
  20. public:
  21. // Represent the graph with an adjacency list.
  22. using NodeList = cmGraphNodeList;
  23. using EdgeList = cmGraphEdgeList;
  24. using Graph = cmGraphAdjacencyList;
  25. cmComputeComponentGraph(Graph const& input);
  26. ~cmComputeComponentGraph();
  27. /** Run the computation. */
  28. void Compute();
  29. /** Get the adjacency list of the component graph. */
  30. Graph const& GetComponentGraph() const { return this->ComponentGraph; }
  31. EdgeList const& GetComponentGraphEdges(int c) const
  32. {
  33. return this->ComponentGraph[c];
  34. }
  35. /** Get map from component index to original node indices. */
  36. std::vector<NodeList> const& GetComponents() const
  37. {
  38. return this->Components;
  39. }
  40. NodeList const& GetComponent(int c) const { return this->Components[c]; }
  41. /** Get map from original node index to component index. */
  42. std::vector<int> const& GetComponentMap() const
  43. {
  44. return this->TarjanComponents;
  45. }
  46. static const int INVALID_COMPONENT;
  47. private:
  48. void TransferEdges();
  49. Graph const& InputGraph;
  50. Graph ComponentGraph;
  51. // Tarjan's algorithm.
  52. struct TarjanEntry
  53. {
  54. int Root;
  55. int VisitIndex;
  56. };
  57. std::vector<int> TarjanVisited;
  58. std::vector<int> TarjanComponents;
  59. std::vector<TarjanEntry> TarjanEntries;
  60. std::vector<NodeList> Components;
  61. std::stack<int> TarjanStack;
  62. int TarjanWalkId;
  63. int TarjanIndex;
  64. void Tarjan();
  65. void TarjanVisit(int i);
  66. // Connected components.
  67. };