LCOV - code coverage report
Current view: top level - app/include/utils - alg.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 26 27 96.3 %
Date: 2023-08-17 16:45:52 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <algorithm>
       4             : #include <cassert>
       5             : #include <iostream>
       6             : #include <list>
       7             : #include <set>
       8             : #include <stdexcept>
       9             : 
      10             : namespace utils::alg {
      11             : 
      12             : template<class T>
      13             : void topological_sort(std::vector<T> &v) {
      14             :     return topological_sort(v, std::less<T>());
      15             : }
      16             : 
      17             : template<class T, class Compare>
      18           2 : void topological_sort(std::vector<T> &v, Compare comp) {
      19           2 :     const size_t N = v.size();
      20             : 
      21           2 :     std::vector<ssize_t> inDegree(N, 0);
      22             : 
      23          14 :     for(size_t i = 0; i < N; ++i) {
      24          84 :         for(size_t j = 0; j < N; ++j) {
      25          72 :             if(comp(v[i], v[j])) {
      26             :                 // Edge from i to j
      27          13 :                 ++inDegree[j];
      28             :             }
      29             :         }
      30             :     }
      31             : 
      32           2 :     std::vector<T> L;
      33           2 :     L.reserve(N);
      34             : 
      35           2 :     std::set<size_t> S;
      36             : 
      37          14 :     for(size_t i = 0; i < N; ++i) {
      38          12 :         if(inDegree[i] == 0) {
      39          12 :             S.insert(i);
      40             :         }
      41             :     }
      42             : 
      43          14 :     while(!S.empty()) {
      44          12 :         size_t n = *S.begin();
      45          12 :         S.erase(S.begin());
      46          12 :         L.emplace_back(v[n]);
      47             : 
      48          84 :         for(size_t m = 0; m < N; ++m) {
      49          72 :             if(inDegree[m] > 0) {
      50          26 :                 if(comp(v[n], v[m])) {
      51          13 :                     --inDegree[m];
      52          13 :                     if(inDegree[m] == 0) {
      53          72 :                         S.insert(m);
      54             :                     }
      55             :                 }
      56             :             }
      57             :         }
      58             :     }
      59             : 
      60           2 :     if(L.size() != N)
      61           0 :         throw std::invalid_argument("Graph has a cycle");
      62             : 
      63           2 :     v = L;
      64           2 : }
      65             : 
      66             : }  // namespace utils::alg

Generated by: LCOV version 1.14