49#include <lal/graphs/graph.hpp>
50#include <lal/detail/identity_arrangement.hpp>
51#include <lal/detail/avl.hpp>
52#include <lal/detail/sorting/counting_sort.hpp>
53#include <lal/detail/data_array.hpp>
54#include <lal/detail/macros/basic_convert.hpp>
56#define edge_sorted_by_vertex_index(u,v) (u < v ? edge(u,v) : edge(v,u) )
57#define DECIDED_C_GT (upper_bound + 1)
69namespace stack_based {
92template <
class graph_t, linarr_type arr_type>
95 std::vector<neighbourhood>& adjP,
96 std::vector<std::vector<indexed_edge>>& adjN,
97 uint64_t *
const size_adjN_u
101 const uint64_t n = g.get_num_nodes();
104 std::vector<edge> edges = g.get_edges();
111 edges.begin(), edges.end(),
114 [&](
const edge& e) -> std::size_t {
116 const node uu = e.first;
117 const node vv = e.second;
127 for (
node u = 0; u < n; ++u) {
131 assert((size_adjN_u[u]%2) == 0);
138 adjN[u].resize(size_adjN_u[u]);
142 for (
const auto& [uu, vv] : edges) {
148 adjP[v].push_back(u);
152 adjN[u][size_adjN_u[u]] =
indexed_edge(0, edge_sorted_by_vertex_index(u,v));
156 for (
node u = 0; u < n; ++u) {
157 assert(size_adjN_u[u] == 0);
178template <
bool dec
ide_upper_bound,
class graph_t, linarr_type arr_type>
181 uint64_t *
const size_adjN_u,
186 const uint64_t n = g.get_num_nodes();
190 std::vector<neighbourhood> adjP(n);
192 std::vector<std::vector<indexed_edge>> adjN(n);
197 std::map<edge, uint64_t> edge_to_idx;
201 const node u = arr[pu];
202 for (
auto& v : adjN[u]) {
205 edge_to_idx.insert( make_pair(v.second, idx) );
216 const node u = arr[pu];
217 for (
node v : adjP[u]) {
218 const edge uv = edge_sorted_by_vertex_index(u,v);
227 if constexpr (decide_upper_bound) {
228 if (C > upper_bound) {
return DECIDED_C_GT; }
256template <
class graph_t,
class arrangement_t>
260 const uint64_t n = g.get_num_nodes();
263 assert(arr.m_arr.size() == 0 or arr.m_arr.size() == n);
266 if (n < 4) {
return 0; }
272 return stack_based::compute_C_stack_based<false>
273 (g, arr, size_adjN_u.
begin(), 0);
286template <
class graph_t>
288(
const graph_t& g,
const std::vector<linear_arrangement>& arrs)
291 const uint64_t n = g.get_num_nodes();
293 std::vector<uint64_t> cs(arrs.size(), 0);
294 if (n < 4) {
return cs; }
301 for (std::size_t i = 0; i < arrs.size(); ++i) {
304 assert(arrs[i].size() == n);
308 cs[i] = stack_based::compute_C_stack_based<false>
331template <
class graph_t,
class arrangement_t>
334 const arrangement_t& arr,
339 const uint64_t n = g.get_num_nodes();
342 assert(arr.m_arr.size() == 0 or arr.m_arr.size() == n);
345 if (n < 4) {
return 0; }
351 return stack_based::compute_C_stack_based<true>
352 (g, arr, size_adjN_u.
begin(), upper_bound);
367template <
class graph_t>
370 const std::vector<linear_arrangement>& arrs,
375 const uint64_t n = g.get_num_nodes();
377 std::vector<uint64_t> cs(arrs.size(), 0);
378 if (n < 4) {
return cs; }
385 for (std::size_t i = 0; i < arrs.size(); ++i) {
388 assert(arrs[i].size() == n);
392 cs[i] = stack_based::compute_C_stack_based<true>
409template <
class graph_t>
412 const std::vector<linear_arrangement>& arrs,
413 const std::vector<uint64_t>& upper_bounds
419 assert(arrs.size() == upper_bounds.size());
422 const uint64_t n = g.get_num_nodes();
424 std::vector<uint64_t> cs(arrs.size(), 0);
425 if (n < 4) {
return cs; }
432 for (std::size_t i = 0; i < arrs.size(); ++i) {
435 assert(arrs[i].size() == n);
439 cs[i] = stack_based::compute_C_stack_based<true>
Simple class that implements an AVL tree.
Definition: avl.hpp:74
frequencies remove(const T &v) noexcept
Remove an element from the tree.
Definition: avl.hpp:235
void join_sorted_all_greater(U &&v) noexcept
Add to the tree the elements in the vector v.
Definition: avl.hpp:252
void fill_adjP_adjN(const graph_t &g, const linarr_wrapper< arr_type > &arr, std::vector< neighbourhood > &adjP, std::vector< std::vector< indexed_edge > > &adjN, uint64_t *const size_adjN_u) noexcept
Auxiliary function to sort edges as a function of the arrangement.
Definition: C_stack_based.hpp:93
std::pair< uint64_t, lal::edge > indexed_edge
Useful typedef.
Definition: C_stack_based.hpp:72
uint64_t compute_C_stack_based(const graph_t &g, const linarr_wrapper< arr_type > &arr, uint64_t *const size_adjN_u, uint64_t upper_bound) noexcept
Stack based computation of for undirected graphs.
Definition: C_stack_based.hpp:179
uint64_t n_C_stack_based(const graph_t &g, const arrangement_t &arr) noexcept
Stack based computation of .
Definition: C_stack_based.hpp:257
uint64_t is_n_C_stack_based_lesseq_than(const graph_t &g, const arrangement_t &arr, uint64_t upper_bound) noexcept
Stack based computation of with early termination.
Definition: C_stack_based.hpp:332
void counting_sort(const value_iterator_t begin, const value_iterator_t end, const std::size_t largest_key_plus_1, const std::function< std::size_t(const value_t &)> &key, countingsort::memory< value_t > &mem) noexcept
Counting sort algorithm with reusable memory.
Definition: counting_sort.hpp:155
constexpr T abs_diff(const T &t1, const T &t2) noexcept
Absolute difference of two values.
Definition: basic_convert.hpp:67
linarr_wrapper< linarr_type::nonident > nonident_arr(const linear_arrangement &arr) noexcept
Shorthand for a nonidentity arrangement.
Definition: identity_arrangement.hpp:121
Main namespace of the library.
Definition: basic_types.hpp:50
std::pair< node, node > edge
See Edge page for further details.
Definition: basic_types.hpp:58
uint64_t node
Node type. See Node / Vertex page for further details.
Definition: basic_types.hpp:53
std::size_t num_nodes_larger
Number of nodes with a key larger than v in the tree.
Definition: avl.hpp:83
Wrapper of a C array for autmatic deallocation of memory.
Definition: data_array.hpp:59
T * begin() noexcept
Non-constant raw pointer to first element.
Definition: data_array.hpp:291
A wrapper to easily use identity arrangements.
Definition: identity_arrangement.hpp:72
Non-decreasing sort type.
Definition: sorting_types.hpp:49
Typesafe node type.
Definition: basic_types.hpp:67
Typesafe position type.
Definition: basic_types.hpp:168