58#include <lal/linear_arrangement.hpp>
59#include <lal/graphs/rooted_tree.hpp>
60#include <lal/detail/data_array.hpp>
61#include <lal/iterators/E_iterator.hpp>
62#include <lal/detail/graphs/size_subtrees.hpp>
63#include <lal/detail/sorting/counting_sort.hpp>
64#include <lal/detail/properties/tree_centroid.hpp>
65#include <lal/detail/macros/basic_convert.hpp>
66#include <lal/detail/linarr/Dopt_utils.hpp>
74using namespace Dopt_utils;
111template <
bool make_arrangement>
114 const std::vector<std::vector<node_size>>& L,
127 const auto& children = L[r];
132 side roots_side = (r_place == PLACE_RIGHT_OF ? RIGHT_SIDE : LEFT_SIDE);
135 uint64_t acc_size_left = 0;
137 uint64_t acc_size_right = 0;
140 uint64_t n_intervals_left = 0;
142 uint64_t n_intervals_right = 0;
152 std::optional<uint64_t> previous_size;
158 for (
const auto& [vi, ni] : children) {
163 assert(*previous_size >= ni);
165 previous_size = {ni};
170 arrange<make_arrangement>(
172 (roots_side == LEFT_SIDE ? PLACE_LEFT_OF : PLACE_RIGHT_OF),
173 (make_arrangement ? (roots_side == LEFT_SIDE ? ini : fin - ni + 1) : 0),
174 (make_arrangement ? (roots_side == LEFT_SIDE ? ini + ni - 1 : fin) : 0),
179 d += ni*(roots_side == LEFT_SIDE ? n_intervals_left : n_intervals_right);
184 n_intervals_left += roots_side;
185 n_intervals_right += other_side(roots_side);
188 acc_size_left += roots_side*ni;
189 acc_size_right += other_side(roots_side)*ni;
192 if constexpr (make_arrangement) {
193 ini += roots_side*ni;
194 fin -= other_side(roots_side)*ni;
198 roots_side = other_side(roots_side);
202 if constexpr (make_arrangement) {
206 if constexpr (make_arrangement) {
212 (r_place == PLACE_NONE_OF ? 0 :
213 r_place == PLACE_LEFT_OF ? acc_size_right : acc_size_left);
233 uint64_t n,
const std::vector<std::vector<node_size>>& L,
238 return arrange<true>(L, r, PLACE_NONE_OF, 0, n-1, arr);
255(uint64_t n,
const std::vector<std::vector<node_size>>& L,
node r)
259 return arrange<false>(L, r, PLACE_NONE_OF, 0, n-1, arr);
289template <
bool make_arrangement>
291 const std::vector<std::vector<node_size>>& L,
293 int64_t base, int64_t dir,
298 const auto& Cv = L[v];
299 uint64_t cost_branch = 0;
303 uint64_t under_anchor = 0;
306 for (std::size_t i = 1; i < Cv.size(); i += 2) {
309 under_anchor += Cv[i].size;
312 if constexpr (make_arrangement) {
313 base += dir*(
to_int64(under_anchor) + 1);
316 cost_branch += under_anchor;
319 uint64_t i = Cv.size();
320 for (
auto it = Cv.rbegin(); it != Cv.rend(); ++it, --i) {
322 assert(i <= Cv.size());
325 const auto [vi, ni] = *it;
328 embed_branch<make_arrangement>(
335 (i&0x1) == 0 ? -dir : dir
340 cost_branch += ( (i&0x1) == 0 ? before : after );
342 before += ((i&0x1) == 0 ? ni : 0);
343 after += ((i&0x1) == 0 ? 0 : ni);
348 if constexpr (make_arrangement) {
369template <
bool make_arrangement>
371 const std::vector<std::vector<node_size>>& L,
377 const uint64_t n = L.size();
381 uint64_t left_sum = 0;
382 uint64_t right_sum = 0;
384 uint64_t i = L[r].size();
387 for (
auto it = L[r].rbegin(); it != L[r].rend(); ++it, --i) {
388 const auto [vi, ni] = *it;
390 assert(i <= L[r].size());
394 embed_branch<make_arrangement>(
406 D += ( (i&0x1) == 0 ? right_sum : left_sum );
408 right_sum += ((i&0x1) == 0 ? ni : 0);
409 left_sum += ((i&0x1) == 0 ? 0 : ni);
415 if constexpr (make_arrangement) {
416 arr.assign(r, left_sum + 1 - 1);
418 for (
node v = 0; v < n; ++v) {
Linear arrangement of vertices.
Definition: linear_arrangement.hpp:103
uint64_t embed_branch(const std::vector< std::vector< node_size > > &L, node v, int64_t base, int64_t dir, data_array< int64_t > &rel_pos) noexcept
Embed a tree's branch.
Definition: Dmin_utils.hpp:290
uint64_t arrange(const std::vector< std::vector< node_size > > &L, const node r, const place r_place, position ini, position fin, linear_arrangement &arr) noexcept
Make a minimum projective arrangement using the sorted, rooted adjacency list L.
Definition: Dmin_utils.hpp:113
uint64_t arrange_projective(uint64_t n, const std::vector< std::vector< node_size > > &L, node r, linear_arrangement &arr) noexcept
Wrapper method for the recursive method arrange.
Definition: Dmin_utils.hpp:232
uint64_t embed(const std::vector< std::vector< node_size > > &L, const node r, linear_arrangement &arr) noexcept
Embed a tree's branch.
Definition: Dmin_utils.hpp:370
unsigned char side
Useful typedef to denote relative position.
Definition: Dopt_utils.hpp:74
unsigned char place
Useful typedef to denote relative position.
Definition: Dopt_utils.hpp:72
constexpr int64_t to_int64(const T &t) noexcept
Conversion to int64_t.
Definition: basic_convert.hpp:52
constexpr uint64_t to_uint64(const T &t) noexcept
Conversion to uint64_t.
Definition: basic_convert.hpp:57
Main namespace of the library.
Definition: basic_types.hpp:50
uint64_t position
Node's position type.
Definition: basic_types.hpp:55
uint64_t node
Node type. See Node / Vertex page for further details.
Definition: basic_types.hpp:53
Wrapper of a C array for autmatic deallocation of memory.
Definition: data_array.hpp:59
Typesafe node type.
Definition: basic_types.hpp:67