60 #ifndef UTIL_GRAPH_TOPOLOGICALSORTER_H__ 61 #define UTIL_GRAPH_TOPOLOGICALSORTER_H__ 64 #include <type_traits> 67 #include "absl/base/attributes.h" 68 #include "absl/container/flat_hash_map.h" 81 int num_nodes,
const std::vector<std::pair<int, int>>& arcs,
82 std::vector<int>* topological_order);
86 int num_nodes,
const std::vector<std::pair<int, int>>& arcs,
87 std::vector<int>* topological_order);
96 int num_nodes,
const std::vector<std::pair<int, int>>& arcs);
100 template <
typename T>
102 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs,
103 std::vector<T>* topological_order);
104 template <
typename T>
106 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs,
107 std::vector<T>* topological_order);
112 int num_nodes,
const std::vector<std::pair<int, int>>& arcs);
114 int num_nodes,
const std::vector<std::pair<int, int>>& arcs);
115 template <
typename T>
117 const std::vector<std::pair<T, T>>& arcs);
118 template <
typename T>
120 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs);
124 template <
typename T,
typename Sorter>
126 Sorter* sorter,
const std::vector<std::pair<T, T>>& arcs,
127 std::vector<T>* topological_order_or_cycle);
141 template <
bool stable_sort = false>
150 : traversal_started_(false),
152 num_edges_added_since_last_duplicate_removal_(0) {}
158 : adjacency_lists_(num_nodes),
159 traversal_started_(false),
161 num_edges_added_since_last_duplicate_removal_(0) {}
172 void AddEdge(
int from,
int to);
177 bool GetNext(
int* next_node_index,
bool* cyclic,
178 std::vector<int>* output_cycle_nodes = NULL);
182 return nodes_with_zero_indegree_.size();
195 int skip_lists_smaller_than);
202 std::vector<AdjacencyList> adjacency_lists_;
204 bool traversal_started_;
208 typename std::conditional<
211 std::priority_queue<int, std::vector<int>, std::greater<int>>,
212 std::queue<int>>::type nodes_with_zero_indegree_;
213 std::vector<int> indegree_;
218 int num_edges_added_since_last_duplicate_removal_;
224 extern template class DenseIntTopologicalSorterTpl<false>;
225 extern template class DenseIntTopologicalSorterTpl<true>;
231 typedef ::util::internal::DenseIntTopologicalSorterTpl<
240 typedef ::util::internal::DenseIntTopologicalSorterTpl<
265 template <
typename T,
bool stable_sort =
false,
266 typename Hash =
typename absl::flat_hash_map<T, int>::hasher,
268 typename absl::flat_hash_map<T, int, Hash>::key_equal>
282 void AddNode(
const T& node) { int_sorter_.AddNode(LookupOrInsertNode(node)); }
291 const int from_int = LookupOrInsertNode(from);
292 const int to_int = LookupOrInsertNode(to);
293 int_sorter_.AddEdge(from_int, to_int);
314 std::vector<T>* output_cycle_nodes = NULL) {
317 if (!int_sorter_.GetNext(&node_index, cyclic_ptr,
318 output_cycle_nodes ? &cycle_int_nodes_ : NULL)) {
319 if (*cyclic_ptr && output_cycle_nodes != NULL) {
320 output_cycle_nodes->clear();
321 for (
const int int_node : cycle_int_nodes_) {
322 output_cycle_nodes->push_back(nodes_[int_node]);
327 *node = nodes_[node_index];
335 return int_sorter_.GetCurrentFringeSize();
344 nodes_.resize(node_to_index_.size());
347 for (
auto& node_and_index : node_to_index_) {
348 nodes_[node_and_index.second] = std::move(node_and_index.first);
351 int_sorter_.StartTraversal();
362 absl::flat_hash_map<T, int, Hash, KeyEqual> node_to_index_;
365 std::vector<T> nodes_;
372 std::vector<int> cycle_int_nodes_;
376 int LookupOrInsertNode(
const T& node) {
386 template <
typename T,
typename Sorter>
388 Sorter* sorter,
const std::vector<std::pair<T, T>>& arcs,
389 std::vector<T>* topological_order, std::vector<T>* cycle) {
390 topological_order->clear();
391 for (
const auto& arc : arcs) {
392 sorter->AddEdge(arc.first, arc.second);
395 sorter->StartTraversal();
397 while (sorter->GetNext(&
next, &cyclic, cycle)) {
398 topological_order->push_back(
next);
403 template <
bool stable_sort = false>
405 int num_nodes,
const std::vector<std::pair<int, int>>& arcs,
406 std::vector<int>* topological_order) {
408 return RunTopologicalSorter<int, decltype(sorter)>(
409 &sorter, arcs, topological_order,
nullptr);
412 template <
typename T,
bool stable_sort = false>
414 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs,
415 std::vector<T>* topological_order) {
417 for (
const T& node :
nodes) {
420 return RunTopologicalSorter<T, decltype(sorter)>(&sorter, arcs,
421 topological_order,
nullptr);
425 template <
typename T,
typename Sorter>
427 Sorter* sorter,
const std::vector<std::pair<T, T>>& arcs) {
428 std::vector<T> topo_order;
434 template <
bool stable_sort = false>
436 int num_nodes,
const std::vector<std::pair<int, int>>& arcs) {
441 template <
typename T,
bool stable_sort = false>
443 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs) {
445 for (
const T& node :
nodes) {
454 int num_nodes,
const std::vector<std::pair<int, int>>& arcs,
455 std::vector<int>* topological_order) {
456 return internal::DenseIntTopologicalSortImpl<false>(num_nodes, arcs,
461 int num_nodes,
const std::vector<std::pair<int, int>>& arcs,
462 std::vector<int>* topological_order) {
463 return internal::DenseIntTopologicalSortImpl<true>(num_nodes, arcs,
467 template <
typename T>
469 const std::vector<std::pair<T, T>>& arcs,
470 std::vector<T>* topological_order) {
471 return internal::TopologicalSortImpl<T, false>(
nodes, arcs,
475 template <
typename T>
477 const std::vector<std::pair<T, T>>& arcs,
478 std::vector<T>* topological_order) {
479 return internal::TopologicalSortImpl<T, true>(
nodes, arcs, topological_order);
483 int num_nodes,
const std::vector<std::pair<int, int>>& arcs) {
484 return internal::DenseIntTopologicalSortOrDieImpl<false>(num_nodes, arcs);
488 int num_nodes,
const std::vector<std::pair<int, int>>& arcs) {
489 return internal::DenseIntTopologicalSortOrDieImpl<true>(num_nodes, arcs);
492 template <
typename T>
494 const std::vector<std::pair<T, T>>& arcs) {
495 return internal::TopologicalSortOrDieImpl<T, false>(
nodes, arcs);
498 template <
typename T>
500 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs) {
501 return internal::TopologicalSortOrDieImpl<T, true>(
nodes, arcs);
512 template <
typename T,
bool stable_sort =
false,
513 typename Hash =
typename absl::flat_hash_map<T, int>::hasher,
515 typename absl::flat_hash_map<T, int, Hash>::key_equal>
522 int num_nodes,
const std::vector<std::pair<int, int>>& arcs) {
526 int num_nodes,
const std::vector<std::pair<int, int>>& arcs) {
529 template <
typename T>
531 const std::vector<T>&
nodes,
const std::vector<std::pair<T, T>>& arcs) {
532 return ::util::StableTopologicalSortOrDie<T>(
nodes, arcs);
538 #endif // UTIL_GRAPH_TOPOLOGICALSORTER_H__ uint64_t Hash(uint64_t num, uint64_t c)
std::vector< T > StableTopologicalSortOrDie(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs)
std::vector< int > DenseIntTopologicalSortOrDieImpl(int num_nodes, const std::vector< std::pair< int, int >> &arcs)
ABSL_MUST_USE_RESULT bool TopologicalSortImpl(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs, std::vector< T > *topological_order)
ABSL_MUST_USE_RESULT bool DenseIntTopologicalSortImpl(int num_nodes, const std::vector< std::pair< int, int >> &arcs, std::vector< int > *topological_order)
::util::DenseIntTopologicalSorter DenseIntTopologicalSorter
bool GetNext(int *next_node_index, bool *cyclic, std::vector< int > *output_cycle_nodes=NULL)
bool TraversalStarted() const
std::vector< T > RunTopologicalSorterOrDie(Sorter *sorter, const std::vector< std::pair< T, T >> &arcs)
::util::DenseIntStableTopologicalSorter DenseIntStableTopologicalSorter
void STLClearHashIfBig(T *obj, size_t limit)
int GetCurrentFringeSize()
ABSL_MUST_USE_RESULT bool RunTopologicalSorter(Sorter *sorter, const std::vector< std::pair< T, T >> &arcs, std::vector< T > *topological_order_or_cycle)
std::vector< T > TopologicalSortOrDie(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs)
std::vector< int > AdjacencyList
void ExtractCycle(std::vector< int > *cycle_nodes) const
std::vector< int > DenseIntTopologicalSortOrDie(int num_nodes, const std::vector< std::pair< int, int >> &arcs)
auto LogContainer(const ContainerT &container, const PolicyT &policy) -> decltype(gtl::LogRange(container.begin(), container.end(), policy))
std::vector< int > FindCycleInDenseIntGraph(int num_nodes, const std::vector< std::pair< int, int >> &arcs)
DenseIntTopologicalSorterTpl(int num_nodes)
void AddEdge(int from, int to)
void AddNode(const T &node)
ABSL_MUST_USE_RESULT bool DenseIntTopologicalSort(int num_nodes, const std::vector< std::pair< int, int >> &arcs, std::vector< int > *topological_order)
bool GetNext(T *node, bool *cyclic_ptr, std::vector< T > *output_cycle_nodes=NULL)
DenseIntTopologicalSorterTpl()
std::vector< int > DenseIntTopologicalSortOrDie(int num_nodes, const std::vector< std::pair< int, int >> &arcs)
static int RemoveDuplicates(std::vector< AdjacencyList > *lists, int skip_lists_smaller_than)
int GetCurrentFringeSize()
ABSL_MUST_USE_RESULT bool TopologicalSort(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs, std::vector< T > *topological_order)
std::vector< T > TopologicalSortOrDieImpl(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs)
::util::internal::DenseIntTopologicalSorterTpl< true > DenseIntStableTopologicalSorter
Collection::value_type::second_type & LookupOrInsert(Collection *const collection, const typename Collection::value_type::first_type &key, const typename Collection::value_type::second_type &value)
std::vector< T > StableTopologicalSortOrDie(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs)
::util::internal::DenseIntTopologicalSorterTpl< false > DenseIntTopologicalSorter
std::vector< int > DenseIntStableTopologicalSortOrDie(int num_nodes, const std::vector< std::pair< int, int >> &arcs)
std::vector< int > DenseIntStableTopologicalSortOrDie(int num_nodes, const std::vector< std::pair< int, int >> &arcs)
void AddNode(int node_index)
bool TraversalStarted() const
ABSL_MUST_USE_RESULT bool DenseIntStableTopologicalSort(int num_nodes, const std::vector< std::pair< int, int >> &arcs, std::vector< int > *topological_order)
void AddEdge(const T &from, const T &to)
ABSL_MUST_USE_RESULT bool StableTopologicalSort(const std::vector< T > &nodes, const std::vector< std::pair< T, T >> &arcs, std::vector< T > *topological_order)