Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
LIS.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
79#ifndef LIS_H
80#define LIS_H
81
82#include <algorithm>
83#include <cstddef>
84#include <limits>
85#include <utility>
86
87#include <ahFunction.H>
88#include <tpl_array.H>
89
90namespace Aleph {
95template <typename T>
97{
98 size_t length = 0;
100};
101
102namespace lis_detail {
103template <typename T, class Compare>
104[[nodiscard]] inline size_t lower_bound_pos(const Array<T> &tails, const T &value, Compare cmp)
105{
106 size_t lo = 0, hi = tails.size();
107 while (lo < hi)
108 {
109 const size_t mid = lo + (hi - lo) / 2;
110 if (cmp(tails[mid], value))
111 lo = mid + 1;
112 else
113 hi = mid;
114 }
115 return lo;
116}
117
118template <typename T, class Compare>
119[[nodiscard]] inline size_t upper_bound_pos(const Array<T> &tails, const T &value, Compare cmp)
120{
121 size_t lo = 0, hi = tails.size();
122 while (lo < hi)
123 {
124 const size_t mid = lo + (hi - lo) / 2;
125 if (cmp(value, tails[mid]))
126 hi = mid;
127 else
128 lo = mid + 1;
129 }
130 return lo;
131}
132} // namespace lis_detail
133
148template <typename T, class Compare = Aleph::less<T>>
150 Compare cmp = Compare())
151{
152 const size_t n = seq.size();
153 if (n == 0)
154 return LIS_Result<T>{0, Array<T>()};
155
156 // tails[i] = smallest tail element for IS of length i+1
158 tails.reserve(n);
159
160 // parent[i] = index of predecessor of seq[i] in best IS ending at seq[i]
162 // pos[i] = index in seq of the element at tails[i]
164 tail_idx.reserve(n);
165
166 for (size_t i = 0; i < n; ++i)
167 {
168 const size_t lo = lis_detail::lower_bound_pos(tails, seq[i], cmp);
169
170 if (lo == tails.size())
171 {
172 tails.append(seq[i]);
173 tail_idx.append(i);
174 }
175 else
176 {
177 tails[lo] = seq[i];
178 tail_idx[lo] = i;
179 }
180
181 parent(i) = lo > 0 ? tail_idx[lo - 1] : std::numeric_limits<size_t>::max();
182 }
183
184 // reconstruct
185 const size_t lis_len = tails.size();
187 size_t idx = tail_idx[lis_len - 1];
188 for (size_t k = lis_len; k > 0; --k)
189 {
190 result(k - 1) = seq[idx];
191 idx = parent(idx);
192 }
193
194 return LIS_Result<T>{lis_len, std::move(result)};
195}
196
211template <typename T, class Compare = Aleph::less<T>>
212[[nodiscard]] size_t lis_length(const Array<T> &seq, Compare cmp = Compare())
213{
214 const size_t n = seq.size();
215 if (n == 0)
216 return 0;
217
219 tails.reserve(n);
220
221 for (size_t i = 0; i < n; ++i)
222 {
223 const size_t lo = lis_detail::lower_bound_pos(tails, seq[i], cmp);
224
225 if (lo == tails.size())
226 tails.append(seq[i]);
227 else
228 tails[lo] = seq[i];
229 }
230
231 return tails.size();
232}
233
248template <typename T, class Compare = Aleph::less<T>>
250 Compare cmp = Compare())
251{
252 const size_t n = seq.size();
253 if (n == 0)
254 return LIS_Result<T>{0, Array<T>()};
255
257 tails.reserve(n);
258
261 tail_idx.reserve(n);
262
263 for (size_t i = 0; i < n; ++i)
264 {
265 const size_t pos = lis_detail::upper_bound_pos(tails, seq[i], cmp);
266
267 if (pos == tails.size())
268 {
269 tails.append(seq[i]);
270 tail_idx.append(i);
271 }
272 else
273 {
274 tails[pos] = seq[i];
275 tail_idx[pos] = i;
276 }
277
278 parent(i) = pos > 0 ? tail_idx[pos - 1] : std::numeric_limits<size_t>::max();
279 }
280
281 const size_t len = tails.size();
282 Array<T> result = Array<T>::create(len);
283 size_t idx = tail_idx[len - 1];
284 for (size_t k = len; k > 0; --k)
285 {
286 result(k - 1) = seq[idx];
287 idx = parent(idx);
288 }
289
290 return LIS_Result<T>{len, std::move(result)};
291}
292} // namespace Aleph
293
294#endif // LIS_H
Standard functor implementations and comparison objects.
size_t size_t int32_t value
Definition ca-c-api.h:116
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
static Array create(size_t n)
Create an array with n logical elements.
Definition tpl_array.H:196
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Definition tpl_array.H:365
void reserve(size_t cap)
Reserves cap cells into the array.
Definition tpl_array.H:320
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4129
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
size_t lower_bound_pos(const Array< T > &tails, const T &value, Compare cmp)
Definition LIS.H:104
size_t upper_bound_pos(const Array< T > &tails, const T &value, Compare cmp)
Definition LIS.H:119
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
LIS_Result< T > longest_nondecreasing_subsequence(const Array< T > &seq, Compare cmp=Compare())
Compute the Longest Non-Decreasing Subsequence.
Definition LIS.H:249
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
LIS_Result< T > longest_increasing_subsequence(const Array< T > &seq, Compare cmp=Compare())
Compute the Longest Increasing Subsequence (strictly increasing).
Definition LIS.H:149
size_t lis_length(const Array< T > &seq, Compare cmp=Compare())
Compute only the length of the LIS (no reconstruction).
Definition LIS.H:212
Result of a Longest Increasing Subsequence computation.
Definition LIS.H:97
Array< T > subsequence
One optimal subsequence found.
Definition LIS.H:99
size_t length
Length of the resulting subsequence.
Definition LIS.H:98
static int * k
Dynamic array container with automatic resizing.