54# include <type_traits>
71 namespace subset_sum_detail
73 template <std::
integral T>
78 if constexpr (std::is_signed_v<T>)
82 using UT = std::make_unsigned_t<T>;
84 if constexpr (
sizeof(
UT) >
sizeof(
size_t))
87 std::numeric_limits<size_t>::max()))
90 return static_cast<size_t>(
uvalue);
93 template <std::
integral T>
98 for (
size_t i = 0; i < values.
size(); ++i)
105 template <
typename T>
110 <<
"subset_sum_mitm: each half must have fewer than 64 elements";
114 <<
"subset_sum_mitm: subset count does not fit size_t";
122 for (
size_t j = 0; j < len; ++j)
123 if (mask & (
static_cast<uint64_t>(1) << j))
124 s +=
static_cast<long long>(arr[start + j]);
125 result.
append(std::make_pair(s, mask));
145 template <std::
integral T>
149 const size_t n = values.
size();
165 for (
size_t i = 0; i <= n; ++i)
168 for (
size_t s = 0; s <= tgt; ++s)
170 dp.
append(std::move(row));
175 for (
size_t i = 1; i <= n; ++i)
177 const size_t vi =
weights[i - 1];
178 for (
size_t s = 0; s <= tgt; ++s)
180 dp[i][s] = dp[i - 1][s];
181 if (
not dp[i][s]
and vi <= s
and dp[i - 1][s - vi])
192 for (
size_t i = n; i > 0
and s > 0; --i)
193 if (dp[i][s]
and not dp[i - 1][s])
202 for (
size_t k =
sel.size();
k > 0; --
k)
221 template <std::
integral T>
225 const size_t n = values.
size();
227 target,
"subset_sum_exists",
"target");
229 values,
"subset_sum_exists");
237 for (
size_t s = 0; s <= tgt; ++s)
241 for (
size_t i = 0; i < n; ++i)
244 for (
size_t s = tgt; s >= vi
and s !=
static_cast<size_t>(-1); --s)
265 template <std::
integral T>
269 const size_t n = values.
size();
272 values,
"subset_sum_count");
275 for (
size_t s = 0; s <= tgt; ++s)
279 for (
size_t i = 0; i < n; ++i)
282 for (
size_t s = tgt; s >= vi
and s !=
static_cast<size_t>(-1); --s)
283 if (
const size_t count = dp[s - vi];
count > 0)
285 if (dp(s) > std::numeric_limits<size_t>::max() -
count)
286 dp(s) = std::numeric_limits<size_t>::max();
311 template <std::
integral T>
315 const size_t n = values.
size();
320 const size_t half1 = n / 2;
329 return a.first < b.first;
332 const auto target_ll =
static_cast<long long>(target);
333 for (
size_t i = 0; i <
sums1.size(); ++i)
338 size_t lo = 0, hi =
sums2.size();
341 const size_t mid = lo + (hi - lo) / 2;
355 for (
size_t j = 0; j <
half1; ++j)
359 for (
size_t j = 0; j <
half2; ++j)
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
Array< size_t > extract_values_checked(const Array< T > &values, const char *fn_name)
Array< std::pair< long long, uint64_t > > enumerate_sums(const Array< T > &arr, size_t start, size_t len)
size_t to_size_checked(const T value, const char *fn_name, const char *field_name)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
bool subset_sum_exists(const Array< T > &values, T target)
Subset sum existence check (space-optimized).
size_t subset_sum_count(const Array< T > &values, T target)
Count the number of subsets summing to target.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
Subset_Sum_Result< T > subset_sum_mitm(const Array< T > &values, T target)
Subset sum via meet-in-the-middle (MITM).
Subset_Sum_Result< T > subset_sum(const Array< T > &values, T target)
Subset sum via classical DP with reconstruction.
void introsort(T *a, const long l, const long r, const Compare &cmp=Compare())
Sort an array using introsort (introspective sort).
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Result of a subset sum computation.
Array< size_t > selected_indices
Indices of selected elements.
bool exists
Whether a valid subset was found.
Dynamic array container with automatic resizing.
Comprehensive sorting algorithms and search utilities for Aleph-w.