cmake/Source/cmComputeComponentGraph.h

80 lines
2.1 KiB
C
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2021-09-14 00:13:48 +02:00
#pragma once
2017-07-20 19:35:53 +02:00
#include "cmConfigure.h" // IWYU pragma: keep
#include <stack>
2016-10-30 18:24:19 +01:00
#include <vector>
2020-02-01 23:06:01 +01:00
#include "cmGraphAdjacencyList.h"
/** \class cmComputeComponentGraph
* \brief Analyze a graph to determine strongly connected components.
*
* Convert a directed graph into a directed acyclic graph whose nodes
* correspond to strongly connected components of the original graph.
*
* We use Tarjan's algorithm to enumerate the components efficiently.
* An advantage of this approach is that the components are identified
* in a topologically sorted order.
*/
class cmComputeComponentGraph
{
public:
// Represent the graph with an adjacency list.
2020-02-01 23:06:01 +01:00
using NodeList = cmGraphNodeList;
using EdgeList = cmGraphEdgeList;
using Graph = cmGraphAdjacencyList;
cmComputeComponentGraph(Graph const& input);
~cmComputeComponentGraph();
2021-09-14 00:13:48 +02:00
/** Run the computation. */
void Compute();
/** Get the adjacency list of the component graph. */
2016-07-09 11:21:54 +02:00
Graph const& GetComponentGraph() const { return this->ComponentGraph; }
2010-11-13 01:00:53 +02:00
EdgeList const& GetComponentGraphEdges(int c) const
2016-07-09 11:21:54 +02:00
{
return this->ComponentGraph[c];
}
/** Get map from component index to original node indices. */
std::vector<NodeList> const& GetComponents() const
2016-07-09 11:21:54 +02:00
{
return this->Components;
}
NodeList const& GetComponent(int c) const { return this->Components[c]; }
/** Get map from original node index to component index. */
std::vector<int> const& GetComponentMap() const
2016-07-09 11:21:54 +02:00
{
return this->TarjanComponents;
}
private:
void TransferEdges();
Graph const& InputGraph;
Graph ComponentGraph;
// Tarjan's algorithm.
struct TarjanEntry
{
int Root;
int VisitIndex;
};
std::vector<int> TarjanVisited;
std::vector<int> TarjanComponents;
std::vector<TarjanEntry> TarjanEntries;
2015-11-17 17:22:37 +01:00
std::vector<NodeList> Components;
std::stack<int> TarjanStack;
2015-11-17 17:22:37 +01:00
int TarjanWalkId;
int TarjanIndex;
void Tarjan();
void TarjanVisit(int i);
// Connected components.
};