cmake/Source/cmComputeComponentGraph.h

83 lines
2.2 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
2023-05-23 16:38:00 +02:00
#include <cstddef>
#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; }
2023-05-23 16:38:00 +02:00
EdgeList const& GetComponentGraphEdges(size_t 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;
}
2023-05-23 16:38:00 +02:00
NodeList const& GetComponent(size_t c) const { return this->Components[c]; }
/** Get map from original node index to component index. */
2023-05-23 16:38:00 +02:00
std::vector<size_t> const& GetComponentMap() const
2016-07-09 11:21:54 +02:00
{
return this->TarjanComponents;
}
2023-05-23 16:38:00 +02:00
static const size_t INVALID_COMPONENT;
private:
void TransferEdges();
Graph const& InputGraph;
Graph ComponentGraph;
// Tarjan's algorithm.
struct TarjanEntry
{
2023-05-23 16:38:00 +02:00
size_t Root;
size_t VisitIndex;
};
2023-05-23 16:38:00 +02:00
std::vector<size_t> TarjanVisited;
std::vector<size_t> TarjanComponents;
std::vector<TarjanEntry> TarjanEntries;
2015-11-17 17:22:37 +01:00
std::vector<NodeList> Components;
2023-05-23 16:38:00 +02:00
std::stack<size_t> TarjanStack;
size_t TarjanWalkId;
size_t TarjanIndex;
void Tarjan();
2023-05-23 16:38:00 +02:00
void TarjanVisit(size_t i);
// Connected components.
};