diff --git a/enumerable/clique.hpp b/enumerable/clique.hpp index 3a8730a..556a113 100755 --- a/enumerable/clique.hpp +++ b/enumerable/clique.hpp @@ -24,14 +24,19 @@ class CliqueEnumeration using node_t = typename Graph::node_t; using NodeCallback = typename Enumerable, Clique>::NodeCallback; - explicit CliqueEnumeration(Graph* graph) - :graph_( + + explicit CliqueEnumeration(Graph* graph) : graph_() { #ifndef DEGENERACY - graph->Clone() + graph_ = graph->Clone(); #else - graph->Permute(DegeneracyOrder(*graph)) + auto degen = DegeneracyOrder(*graph); + inverse_perm = degen; + for (int i = 0; i < degen.size(); i++) { + inverse_perm[i] = degen[i]; + } + graph_ = graph->Permute(degen); #endif - ){} + } void SetUp() override { candidates_bitset_.resize(graph_->size()); @@ -112,7 +117,15 @@ class CliqueEnumeration Clique NodeToItem( const CliqueEnumerationNode& node) override { +#ifdef DEGENERACY + Clique inv_permuted(node.first.size()); + for (int i = 0; i < node.first.size(); i++) { + inv_permuted[i] = inverse_perm[node.first[i]]; + } + return inv_permuted; +#else return node.first; +#endif } private: @@ -179,6 +192,9 @@ class CliqueEnumeration static thread_local std::vector bad_bitset_; static thread_local std::vector bad_; std::unique_ptr graph_; +#ifdef DEGENERACY + std::vector inverse_perm; +#endif }; template diff --git a/enumerable/diam2kplex.hpp b/enumerable/diam2kplex.hpp index 4f78a55..bc060ef 100644 --- a/enumerable/diam2kplex.hpp +++ b/enumerable/diam2kplex.hpp @@ -489,18 +489,20 @@ class Diam2KplexEnumeration using NodeCallback = typename Enumerable, Kplex>::NodeCallback; + explicit Diam2KplexEnumeration(Graph* graph, size_t k, size_t q, bool enable_pivoting) - : graph_( -#ifndef DEGENERACY - graph->Clone() + : graph_(), k_(k), q_(q), enable_pivoting_(enable_pivoting) { +#ifdef DEGENERACY + auto degen = DegeneracyOrder(*graph); + inverse_perm = degen; + for (int i = 0; i < degen.size(); i++) { + inverse_perm[i] = degen[i]; + } + graph_ = graph->Permute(degen); #else - graph->Permute(DegeneracyOrder(*graph)) + graph_ = graph->Clone(); #endif - ), - k_(k), - q_(q), - enable_pivoting_(enable_pivoting) { } void SetUp() override {} @@ -510,7 +512,16 @@ class Diam2KplexEnumeration size_t MaxRoots() override { return graph_->size(); } Kplex NodeToItem(const Diam2KplexNode& node) override { +#ifdef DEGENERACY + auto kp = ((const Diam2KplexEnumeration*)this)->NodeToItem(node); + Kplex inv_permuted(kp.size()); + for (int i = 0; i < kp.size(); i++) { + inv_permuted[i] = inverse_perm[kp[i]]; + } + return inv_permuted; +#else return ((const Diam2KplexEnumeration*)this)->NodeToItem(node); +#endif } Kplex NodeToItem(const Diam2KplexNode& node) const { @@ -537,25 +548,25 @@ class Diam2KplexEnumeration subgraph_added[v] = true; node.AddToSubgraph(v); std::vector sg; - for (node_t n: graph_->fwd_neighs(v)) { + for (node_t n : graph_->fwd_neighs(v)) { sg.push_back(n); subgraph_added[n] = true; } auto filter_sg = [&](const std::vector& sg) { - std::vector filtered; - for (size_t i=0; iare_neighs(sg[i], sg[j]))count++; - } - if (count +2*k_>= q_) filtered.push_back(sg[i]); + std::vector filtered; + for (size_t i = 0; i < sg.size(); i++) { + size_t count = 0; + for (size_t j = 0; j < sg.size(); j++) { + if (graph_->are_neighs(sg[i], sg[j])) count++; } - return filtered; + if (count + 2 * k_ >= q_) filtered.push_back(sg[i]); + } + return filtered; }; size_t sz; do { - sz = sg.size(); - sg = filter_sg(sg); + sz = sg.size(); + sg = filter_sg(sg); } while (sg.size() != sz); for (node_t n : sg) { node.AddToSubgraph(n); @@ -580,7 +591,7 @@ class Diam2KplexEnumeration subgraph_candidates.clear(); } for (node_t n : node.Subgraph()) subgraph_added[n] = false; - for (node_t n: graph_->fwd_neighs(v)) subgraph_added[n] = false; + for (node_t n : graph_->fwd_neighs(v)) subgraph_added[n] = false; node.Init(graph_.get(), k_); cb(node); } @@ -597,6 +608,9 @@ class Diam2KplexEnumeration const size_t k_; const size_t q_; const bool enable_pivoting_; +#ifdef DEGENERACY + std::vector inverse_perm; +#endif }; extern template class Diam2KplexEnumeration>;