49#include <lal/graphs/graph.hpp>
50#include <lal/detail/arrangement_wrapper.hpp>
51#include <lal/detail/avl.hpp>
52#include <lal/detail/sorting/counting_sort.hpp>
53#include <lal/detail/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)
68namespace stack_based {
91template <
class graph_t,
class arrangement_t>
95 const arrangement_t& arr,
96 std::vector<neighbourhood>& adjP,
97 std::vector<std::vector<indexed_edge>>& adjN,
98 uint64_t *
const size_adjN_u
102 const uint64_t n = g.get_num_nodes();
105 std::vector<edge> edges = g.get_edges();
112 edges.begin(), edges.end(),
115 [&](
const edge& e) -> std::size_t {
117 const node uu = e.first;
118 const node vv = e.second;
128 for (
node u = 0; u < n; ++u) {
132 assert((size_adjN_u[u]%2) == 0);
139 adjN[u].resize(size_adjN_u[u]);
143 for (
const auto& [uu, vv] : edges) {
149 adjP[v].push_back(u);
153 adjN[u][size_adjN_u[u]] =
indexed_edge(0, edge_sorted_by_vertex_index(u,v));
157 for (
node u = 0; u < n; ++u) {
158 assert(size_adjN_u[u] == 0);
179template <
bool dec
ide_upper_bound,
class graph_t,
class arrangement_t>
183 const arrangement_t& arr,
184 uint64_t *
const size_adjN_u,
189 const uint64_t n = g.get_num_nodes();
193 std::vector<neighbourhood> adjP(n);
195 std::vector<std::vector<indexed_edge>> adjN(n);
200 std::map<edge, uint64_t> edge_to_idx;
204 const node u = arr[pu];
205 for (
auto& v : adjN[u]) {
208 edge_to_idx.insert( make_pair(v.second, idx) );
219 const node u = arr[pu];
220 for (
node v : adjP[u]) {
221 const edge uv = edge_sorted_by_vertex_index(u,v);
230 if constexpr (decide_upper_bound) {
231 if (C > upper_bound) {
return DECIDED_C_GT; }
259template <
class graph_t,
class arrangement_t>
261(
const graph_t& g,
const arrangement_t& arr)
264 const uint64_t n = g.get_num_nodes();
267 assert(arr.size() == 0 or arr.size() == n);
270 if (n < 4) {
return 0; }
277 (g, arr, size_adjN_u.
begin(), 0);
290template <
class graph_t>
292(
const graph_t& g,
const std::vector<linear_arrangement>& arrs)
295 const uint64_t n = g.get_num_nodes();
297 std::vector<uint64_t> cs(arrs.size(), 0);
298 if (n < 4) {
return cs; }
305 for (std::size_t i = 0; i < arrs.size(); ++i) {
308 assert(arrs[i].size() == n);
335template <
class graph_t,
class arrangement_t>
339 const arrangement_t& arr,
340 const uint64_t upper_bound
344 const uint64_t n = g.get_num_nodes();
347 assert(arr.size() == 0 or arr.size() == n);
350 if (n < 4) {
return 0; }
357 (g, arr, size_adjN_u.
begin(), upper_bound);
372template <
class graph_t>
376 const std::vector<linear_arrangement>& arrs,
377 const uint64_t upper_bound
381 const uint64_t n = g.get_num_nodes();
383 std::vector<uint64_t> cs(arrs.size(), 0);
384 if (n < 4) {
return cs; }
391 for (std::size_t i = 0; i < arrs.size(); ++i) {
394 assert(arrs[i].size() == n);
415template <
class graph_t>
419 const std::vector<linear_arrangement>& arrs,
420 const std::vector<uint64_t>& upper_bounds
426 assert(arrs.size() == upper_bounds.size());
429 const uint64_t n = g.get_num_nodes();
431 std::vector<uint64_t> cs(arrs.size(), 0);
432 if (n < 4) {
return cs; }
439 for (std::size_t i = 0; i < arrs.size(); ++i) {
442 assert(arrs[i].size() == n);
Simple class that implements an AVL tree.
Definition avl.hpp:73
frequencies remove(const T &v) noexcept
Remove an element from the tree.
Definition avl.hpp:236
void join_sorted_all_greater(U &&v) noexcept
Add to the tree the elements in the vector v.
Definition avl.hpp:253
std::pair< uint64_t, edge > indexed_edge
Useful typedef.
Definition stack_based.hpp:71
uint64_t compute_C_stack_based(const graph_t &g, const arrangement_t &arr, uint64_t *const size_adjN_u, uint64_t upper_bound) noexcept
Stack based computation of for undirected graphs.
Definition stack_based.hpp:181
void fill_adjP_adjN(const graph_t &g, const arrangement_t &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 stack_based.hpp:93
uint64_t is_n_C_stack_based_lesseq_than(const graph_t &g, const arrangement_t &arr, const uint64_t upper_bound) noexcept
Stack based computation of with early termination.
Definition stack_based.hpp:337
uint64_t n_C_stack_based(const graph_t &g, const arrangement_t &arr) noexcept
Stack based computation of .
Definition stack_based.hpp:261
@ non_decreasing
Non-decreasing sort type.
void counting_sort(const value_iterator_t begin, const value_iterator_t end, const std::size_t largest_key_plus_1, const Callable &key, countingsort::memory< value_t > &mem) noexcept
Counting sort algorithm with reusable memory.
Definition counting_sort.hpp:152
arrangement_wrapper< arrangement_type::nonidentity > nonidentity_arr(const linear_arrangement &arr) noexcept
Shorthand for a nonidentity arrangement.
Definition arrangement_wrapper.hpp:133
constexpr T abs_diff(const T &t1, const T &t2) noexcept
Absolute difference of two values.
Definition basic_convert.hpp:77
Main namespace of the library.
Definition basic_types.hpp:48
std::pair< node, node > edge
See Edge page for further details.
Definition basic_types.hpp:56
uint64_t node
Node type. See Node / Vertex page for further details.
Definition basic_types.hpp:51
std::size_t num_nodes_larger
Number of nodes with a key larger than v in the tree.
Definition avl.hpp:82
Wrapper of a C array for automatic deallocation of memory.
Definition array.hpp:59
T * begin() noexcept
Non-constant raw pointer to first element.
Definition array.hpp:300
Typesafe node type.
Definition basic_types.hpp:70
Typesafe position type.
Definition basic_types.hpp:244