47#include <lal/linear_arrangement.hpp>
48#include <lal/detail/graphs/traversal.hpp>
49#include <lal/detail/graphs/size_subtrees.hpp>
50#include <lal/detail/properties/tree_centroid.hpp>
51#include <lal/detail/sorting/counting_sort.hpp>
52#include <lal/detail/data_array.hpp>
53#include <lal/detail/macros/basic_convert.hpp>
54#include <lal/detail/linarr/Dopt_utils.hpp>
56typedef std::pair<uint64_t,lal::node> size_node;
62namespace unconstrained {
71using namespace Dopt_utils;
84template <
char anchored>
86(
const uint64_t n,
const ordering& ord, uint64_t& s_0, uint64_t& s_1)
94 const uint64_t k = ord.size() - 1;
96 uint64_t n_0 = ord[0].first;
104 if (max_p == 0) {
return 0; }
107 for (uint64_t i = 0; i <= 2*max_p; ++i) { sum += ord[i].first; }
109 uint64_t n_star = n - sum;
110 uint64_t tricky_formula = (n_0 + 2)/2 + (n_star + 2)/2;
113 uint64_t n_p = ord[2*max_p].first;
114 while (max_p > 0 and n_p <= tricky_formula) {
115 sum -= ord[2*max_p].first + ord[2*max_p - 1].first;
119 tricky_formula = (n_0 + 2)/2 + (n_star + 2)/2;
123 n_p = (max_p > 0 ? ord[2*max_p].first : n_p);
126 s_0 = max_p*(n_star + 1 + n_0);
128 for (uint64_t i = 1; i < max_p; ++i) {
129 s_0 += i*(ord[2*i + 1].first + ord[2*i + 2].first);
137 if (max_p == 0) {
return 0; }
140 for (uint64_t i = 0; i <= 2*max_p - 1; ++i) { sum += ord[i].first; }
141 uint64_t n_star = n - sum;
142 uint64_t tricky_formula = (n_0 + 2)/2 + (n_star + 2)/2;
143 uint64_t n_p = ord[2*max_p - 1].first;
144 while (max_p > 0 and n_p <= tricky_formula) {
145 sum -= ord[2*max_p - 1].first;
146 sum -= ord[2*max_p - 2].first;
149 tricky_formula = (n_0 + 2)/2 + (n_star + 2)/2;
153 n_p = (max_p > 0 ? ord[2*max_p - 1].first : n_p);
157 s_1 = max_p*(n_star + 1 + n_0) - 1;
158 for (uint64_t i = 1; i < max_p; ++i) {
159 s_1 += i*(ord[2*i].first + ord[2*i + 1].first);
181template <
char alpha,
bool make_arrangement>
193 const uint64_t size_tree = t.get_num_nodes_component(root_or_anchor);
196 assert(size_tree > 0);
200 if (size_tree == 1) {
202 if constexpr (make_arrangement) {
203 mla.assign(root_or_anchor, start);
209 const node v_star = (
225 const neighbourhood& v_star_neighs = t.get_neighbours(v_star);
226 for (std::size_t i = 0; i < v_star_neighs.size(); ++i) {
228 const node ui = v_star_neighs[i];
230 const uint64_t s_ui = s[ui];
233 M = std::max(M, s_ui);
240 [](
const size_node& p) {
return p.first; }
244 const node v_0 = ord[0].second;
245 const uint64_t n_0 = ord[0].
first;
248 t.remove_edge(v_star, v_0,
false,
false);
255 calculate_mla<NO_ANCHOR, make_arrangement>
256 (t, v_star, start, end - n_0, mla, c2);
258 calculate_mla<LEFT_ANCHOR, make_arrangement>
259 (t, v_0, end - n_0 + 1, end, mla, c1);
263 calculate_mla<RIGHT_ANCHOR, make_arrangement>
264 (t, v_0, start, start + n_0 - 1, mla, c1);
266 constexpr auto new_alpha =
269 calculate_mla<new_alpha, make_arrangement>
270 (t, v_star, start + n_0, end, mla, c2);
275 else { cost = c1 + c2 + size_tree - n_0; }
278 t.add_edge(v_star, v_0,
false,
false);
284 constexpr auto anchored =
289 const uint64_t p_alpha =
290 calculate_p_alpha<anchored>(size_tree, ord, s_0, s_1);
296 std::vector<edge> edges(2*p_alpha - anchored);
299 for (uint64_t i = 1; i <= 2*p_alpha - anchored; ++i) {
300 const node r = ord[i].second;
301 edges[i - 1].
first = v_star;
302 edges[i - 1].second = r;
304 t.remove_edges(edges,
false,
false);
308 for(uint64_t i = 1; i <= 2*p_alpha - anchored; ++i) {
311 const node r = ord[i].second;
312 const uint64_t n_i = ord[i].
first;
314 calculate_mla<RIGHT_ANCHOR, make_arrangement>
315 (t, r, start, start + n_i - 1, mla_B, c_aux);
321 calculate_mla<LEFT_ANCHOR, make_arrangement>
322 (t, r, end - n_i + 1, end, mla_B, c_aux);
331 calculate_mla<NO_ANCHOR, make_arrangement>
332 (t, v_star, start, end, mla_B, c_aux);
337 t.add_edges(edges,
false,
false);
352 if constexpr (make_arrangement) {
354 mla = std::move(mla_B);
373template <
bool make_arrangement>
376 std::pair<uint64_t, linear_arrangement>,
391 Shiloach::calculate_mla<Shiloach::NO_ANCHOR, make_arrangement>
394 if constexpr (make_arrangement) {
395 return {Dmin, std::move(arrangement)};
Free tree graph class.
Definition: free_tree.hpp:60
uint64_t get_num_nodes() const noexcept
Returns the number of ndoes.
Definition: graph.hpp:198
Linear arrangement of vertices.
Definition: linear_arrangement.hpp:103
void calculate_mla(graphs::free_tree &t, node root_or_anchor, position start, position end, linear_arrangement &mla, uint64_t &cost) noexcept
Calculate a minimum linear arrangment using Shiloach's algorithm.
Definition: Dmin_Unconstrained_YS.hpp:182
uint64_t calculate_p_alpha(const uint64_t n, const ordering &ord, uint64_t &s_0, uint64_t &s_1) noexcept
Calculate .
Definition: Dmin_Unconstrained_YS.hpp:86
std::conditional_t< make_arrangement, std::pair< uint64_t, linear_arrangement >, uint64_t > YossiShiloach(const graphs::free_tree &t) noexcept
Calculates a minimum linear arrangment using Shiloach's algorithm.
Definition: Dmin_Unconstrained_YS.hpp:379
constexpr char NO_ANCHOR
The tree is not anchored.
Definition: Dopt_utils.hpp:92
constexpr char ANCHOR
The tree is anchored.
Definition: Dopt_utils.hpp:94
constexpr char RIGHT_ANCHOR
The tree is right-anchored.
Definition: Dopt_utils.hpp:90
constexpr char LEFT_ANCHOR
The tree is left-anchored.
Definition: Dopt_utils.hpp:88
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
void get_size_subtrees(const tree_t &t, const node u, const node v, uint64_t *const sizes) noexcept
Calculate the size of every subtree of the tree t.
Definition: size_subtrees.hpp:74
constexpr uint64_t alpha(const int64_t n, const int64_t d1, const int64_t d2) noexcept
Amount of crossings pairs of edges of given lengths.
Definition: predict_C.hpp:71
std::pair< node, node > retrieve_centroid(const tree_t &t, const node x) noexcept
Calculate the centroid of the connected component that has node x.
Definition: tree_centroid.hpp:396
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
std::vector< node > neighbourhood
List of nodes.
Definition: basic_types.hpp:62
Wrapper of a C array for autmatic deallocation of memory.
Definition: data_array.hpp:59
T & first() noexcept
Non-constant reference to the first element in the array.
Definition: data_array.hpp:234
std::size_t size() const noexcept
Size of the array.
Definition: data_array.hpp:204
T * end() noexcept
Non-constant raw pointer to last+1 element.
Definition: data_array.hpp:293
T * begin() noexcept
Non-constant raw pointer to first element.
Definition: data_array.hpp:291
Non-increasing sort.
Definition: sorting_types.hpp:51