57 explicit SubsetSumState(
const size_t n = 0)
58 : index(0),
sum(0), chosen(n, 0)
72 using State = SubsetSumState;
74 explicit SubsetSumDomain(
const Array<int> &values,
const int target)
76 suffix_remaining_(values.
size() + 1, 0),
79 for (
size_t i = values_.size(); i > 0; --i)
80 suffix_remaining_[i - 1] = suffix_remaining_[i] + values_[i - 1];
83 bool is_goal(
const State &state)
const
85 return state.sum == target_;
90 return state.index == values_.size();
93 bool should_prune(
const State &state,
const size_t)
const
95 return state.sum > target_
or state.sum + suffix_remaining_[state.index] < target_;
98 void apply(State &state,
const Move &move)
const
101 state.sum += values_[state.index];
103 state.chosen[state.index] = move.take ? 1 : 0;
107 void undo(State &state,
const Move &move)
const
111 state.sum -= values_[state.index];
113 state.chosen[state.index] = 0;
116 template <
typename Visitor>
117 bool for_each_successor(
const State &state,
Visitor visit)
const
119 if (state.index >= values_.size())
125 return visit(Move{
false});
139std::string
signature(
const SubsetSumState &state)
142 for (
const auto pick : state.chosen)
151 for (
size_t i = 0; i < values.
size(); ++i)
156 std::cout << values[i];
167 constexpr int target = 2;
169 SubsetSumDomain domain(values, target);
179 std::cout <<
"Subset sum target: " << target <<
'\n';
180 std::cout <<
"Solutions found: " << result.stats.solutions_found <<
'\n';
181 std::cout <<
"Pruned states: " << result.stats.pruned_by_domain <<
'\n';
183 for (
auto it =
collector.solutions().get_it(); it.has_curr(); it.next_ne())
185 const auto &solution = it.get_curr();
186 std::cout <<
"Choice mask: " <<
signature(solution.state) <<
" -> ";
Umbrella header for the implicit state-space search framework.
Simple dynamic array with automatic resizing and functional operations.
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Recursive depth-first backtracking over an implicit state space.
Collector that stores accepted solutions in an Aleph list.
User-facing facade exported by the umbrella search header.
size_t size(Node *root) noexcept
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.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Exploration controls shared across engines.
bool stop_at_first_solution
Stop when the first goal is found.