1#ifndef FSTSEARCHBRANCHANDBOUND_H
2#define FSTSEARCHBRANCHANDBOUND_H
108template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
111 typedef Search<RETURNTYPE,DIMTYPE,SUBSET,CRITERION>
parent;
123 notify(
"Search_Branch_And_Bound constructor.");
128 virtual bool search(
const DIMTYPE target_d, RETURNTYPE &result,
const PSubset sub,
const PCriterion crit, std::ostream& os=std::cout)
override;
130 virtual std::ostream&
print(std::ostream& os)
const override {os <<
"Search_Branch_And_Bound() abstract class";
return os;};
134 typedef enum {UNKNOWN, RANDOM, PREDICTED, COMPUTED}
NodeType;
233 virtual void leaf_result(
const DIMTYPE feature,
const RETURNTYPE value) {}
256template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
269template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
274 assert(sub->get_n()==
_boundset->get_n());
285template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
307 while(it!=
_tree[
k].end() && it->value<avail->
value) {++it; ++pos;}
309 _tree[
k].insert(it,*avail);
313 assert(
_tree[
k].size()==levelsize);
321template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
340template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
365template<
class RETURNTYPE,
typename DIMTYPE,
class SUBSET,
class CRITERION>
369 notify(
"Search_Branch_And_Bound::search().");
373 assert(target_d>0 && target_d<
n);
382 sos <<
"---------------------------------------" << std::endl;
383 sos <<
"Starting " << *
this << std::endl;
384 sos <<
"with Criterion: " << *crit << std::endl;
385 sos <<
"Target subset size set to: " << target_d << std::endl;
386 sos << std::endl << std::flush;
393 this->
report(os,
msgbuf() <<
"WARNING: the supplied criterion does not declare monotonicity w.r.t. subset cardinality" << std::endl
394 <<
"(Criterion::is_monotonic()==false). Branch & Bound optimality guarantees do NOT apply -" << std::endl
395 <<
"the result may be suboptimal. Override is_monotonic() to true only if removing a feature" << std::endl
396 <<
"provably never increases the criterion value; otherwise prefer a non-optimal search." << std::endl << std::endl << std::flush);
400 sub->select_all_raw();
401 if(!crit->evaluate(result,sub))
throw FST::fst_error(
"Criterion evaluation failure.");
412 _tree[0].push_back(root);
420 DIMTYPE lastcut_k=
n-
d;
435 while(
k>0 &&
k<
n-
d) {
443 assert(!
_tree[
k].empty());
448 feature=
_tree[
k].back().feature; assert(feature<
n);
453 while(
k>0 &&
_tree[
k].empty()) {
456 assert(!
_tree[
k].empty());
457 feature=
_tree[
k].back().feature; assert(feature<
n);
466 feature=
_tree[
k].back().feature; assert(feature<
n);
480 assert(!
_tree[
k].empty());
481 feature=
_tree[
k].back().feature; assert(feature<
n);
486 }
while(
k>0 &&
_tree[
k].empty());
490 assert(!
_tree[
k].empty());
491 feature=
_tree[
k].back().feature; assert(feature<
n);
499 assert(sub->get_n()==
_boundset->get_n());
504 sos <<
"......................................." << std::endl;
505 sos <<
"Branch and Bound search finished. " << *
swatch << std::endl;
506 sos <<
"Search result: "<< std::endl << *sub << std::endl <<
"Criterion value: " << result << std::endl << std::endl << std::flush;
Abstract candidate-evaluation strategy: the seam through which one search algorithm body evaluates ca...
Implements sequential in-line evaluation of a criterion on a set of subset candidates.
Implements sequential in-line evaluation of a criterion on a set of subset candidates.
Definition candidate_evaluator_sequential.hpp:62
Abstract candidate-evaluation strategy (sequential-inline vs. thread-pooled).
Definition candidate_evaluator.hpp:86
std::function< void(const RETURNTYPE, const PSubset &, const DIMTYPE)> ResultCallback
fired once per evaluated batch candidate: (criterion value, candidate, feature tag as passed to add_c...
Definition candidate_evaluator.hpp:94
Implements Branch and Bound template method as basis for more advanced B&B implementations.
Definition search_branch_and_bound.hpp:109
PSubset & get_currentset()
mutable accessor for _currentset, for use by descendant B&B variants' hooks
Definition search_branch_and_bound.hpp:198
PSubset _currentset
the subset defined by the branch currently being followed: all n features minus the ones removed on t...
Definition search_branch_and_bound.hpp:165
Node & get_parent_node()
the node one level up (_tree[k-1].back()) whose feature removal defines the branch currently being fo...
Definition search_branch_and_bound.hpp:199
virtual void pre_evaluate_availables()=0
Called by make_tree_level() before the k-th level is built. It must assign Node::value (and Node::typ...
virtual std::ostream & print(std::ostream &os) const override
writes a human-readable identification of the search and its configuration; base default writes nothi...
Definition search_branch_and_bound.hpp:130
virtual void process_leafs()
engine-routed leaf evaluation; descendants hook per-leaf work via leaf_result() instead of overriding...
Definition search_branch_and_bound.hpp:341
virtual void initialize(const DIMTYPE d, const DIMTYPE n, const PCriterion crit)=0
Called once per search() run, after setup_default_structures() and the root evaluation but before the...
DIMTYPE get_d() const
target subset cardinality, see d
Definition search_branch_and_bound.hpp:188
Node * PNode
pointer to a Node, as used by the getFirst.../getNext... accessors below
Definition search_branch_and_bound.hpp:142
virtual bool cut_possible()=0
Tests the current node (get_current_node(), i.e. _tree[k].back()) for the possibility to cut the whol...
bool getFirstNode(PNode &nod)
begins forward iteration (ascending by value, from _tree[k].begin()) over the current level's not-yet...
Definition search_branch_and_bound.hpp:190
PCriterion const & get_criterion() const
accessor for _criterion, for use by descendant B&B variants' hooks
Definition search_branch_and_bound.hpp:180
Search_Branch_And_Bound(PEvaluatorEngine engine=PEvaluatorEngine())
Constructs the search, optionally injecting a candidate-evaluation engine.
Definition search_branch_and_bound.hpp:121
DIMTYPE n
no. of all features
Definition search_branch_and_bound.hpp:176
VectorNode _available
the pool of still-undecided features, one entry per original feature and indexed by feature id: Node:...
Definition search_branch_and_bound.hpp:160
virtual void leaf_result(const DIMTYPE feature, const RETURNTYPE value)
Definition search_branch_and_bound.hpp:233
void available_add(const DIMTYPE feature)
re-admits feature to the undecided candidate pool (valid=true, type reset to UNKNOWN); used on backtr...
Definition search_branch_and_bound.hpp:162
DIMTYPE k
current tree level
Definition search_branch_and_bound.hpp:175
Node & get_current_node()
the node at the current level k presently being visited (_tree[k].back()), i.e. about to be tested fo...
Definition search_branch_and_bound.hpp:200
Search< RETURNTYPE, DIMTYPE, SUBSET, CRITERION > parent
base class: the abstract Search interface (search(), progress reporting, result tracker)
Definition search_branch_and_bound.hpp:111
PEvaluatorEngine const & get_engine() const
accessor for the injected evaluation strategy (sequential-inline or thread-pooled),...
Definition search_branch_and_bound.hpp:181
Candidate_Evaluator< RETURNTYPE, DIMTYPE, SUBSET, CRITERION > EVALUATORENGINE
the injected candidate-evaluation strategy type (sequential-inline or thread-pooled); process_leafs()...
Definition search_branch_and_bound.hpp:114
int get_k() const
the tree depth/level currently being processed (root is 0; the deepest stored level is n-d-1,...
Definition search_branch_and_bound.hpp:186
bool getAvailable(DIMTYPE idx, PNode &avail)
direct lookup of _available[idx] by feature index, regardless of its valid flag; returns false if idx...
Definition search_branch_and_bound.hpp:195
ListNode::iterator ListNodeIter
iterator into a single tree level's ListNode, as used by _nodeiter/getFirstNode()/getNextNode()
Definition search_branch_and_bound.hpp:145
PSubset _boundset
the best subset of target cardinality d found so far; meaningful only once _boundvalid is true
Definition search_branch_and_bound.hpp:171
bool getFirstAvailable(PNode &avail)
begins iteration over _available in feature-index order, skipping withdrawn (invalid) entries,...
Definition search_branch_and_bound.hpp:193
std::list< Node > ListNode
one tree level's not-yet-decided candidate nodes, kept sorted ascending by value; the main search loo...
Definition search_branch_and_bound.hpp:143
void currentset_remove(const DIMTYPE feature)
deselects feature from _currentset, committing its removal as the branch descends past it
Definition search_branch_and_bound.hpp:167
virtual void post_process_tree_level()=0
Called by make_tree_level() once the k-th level has been filled and its features withdrawn from _avai...
ListNodeIter _nodeiter
used in get*Node()
Definition search_branch_and_bound.hpp:157
bool getNextNode(PNode &nod)
advances the getFirstNode() iteration; returns false once the level's end is reached
Definition search_branch_and_bound.hpp:191
DIMTYPE d
no. of features to be selected
Definition search_branch_and_bound.hpp:177
PEvaluatorEngine _engine
injected evaluation strategy (sequential-inline or thread-pooled)
Definition search_branch_and_bound.hpp:153
std::shared_ptr< EVALUATORENGINE > PEvaluatorEngine
shared pointer to an EVALUATORENGINE, as accepted by the constructor and returned by get_engine()
Definition search_branch_and_bound.hpp:115
DIMTYPE get_available_size()
number of features still undecided (valid==true) in _available
Definition search_branch_and_bound.hpp:161
void currentset_add(const DIMTYPE feature)
re-selects feature in _currentset, undoing a prior currentset_remove() (used when backtracking up the...
Definition search_branch_and_bound.hpp:166
PCriterion _criterion
the criterion supplied to search(), assigned once initialize() has run (see search())
Definition search_branch_and_bound.hpp:151
void available_remove(const DIMTYPE feature)
withdraws feature from the undecided candidate pool (valid=false), e.g. once it has been sorted into ...
Definition search_branch_and_bound.hpp:163
bool is_bound_valid() const
true once a valid bound has been established, see _boundvalid
Definition search_branch_and_bound.hpp:184
virtual bool search(const DIMTYPE target_d, RETURNTYPE &result, const PSubset sub, const PCriterion crit, std::ostream &os=std::cout) override
returns the found subset of exactly target_d features + its criterion value; target_d must be nonzero...
Definition search_branch_and_bound.hpp:366
std::shared_ptr< SUBSET > PSubset
shared pointer to a feature subset
Definition search_branch_and_bound.hpp:113
void make_tree_level()
Builds the k-th tree level (_tree[k]), keeping exactly n-d-k+1 candidates in reserve for the levels s...
Definition search_branch_and_bound.hpp:286
bool getNextAvailable(PNode &avail)
advances the getFirstAvailable() iteration, again skipping invalid entries; returns false once exhaus...
Definition search_branch_and_bound.hpp:194
std::shared_ptr< CRITERION > PCriterion
shared pointer to the criterion under optimization
Definition search_branch_and_bound.hpp:112
NodeType
Marks how a Node's value was obtained: UNKNOWN = not yet assigned; RANDOM = reserved but currently un...
Definition search_branch_and_bound.hpp:134
VectorListNode _tree
the search tree; _tree[k] holds the not-yet-decided candidate nodes at depth k (see make_tree_level()...
Definition search_branch_and_bound.hpp:155
void setup_default_structures(const DIMTYPE d, const DIMTYPE n)
Allocates and resets everything one search() run needs: the n-d stored tree levels (all emptied),...
Definition search_branch_and_bound.hpp:257
void process_rightmost_path()
Evaluates and registers the "rightmost" leaf reachable from the current branch by removing every feat...
Definition search_branch_and_bound.hpp:322
std::shared_ptr< StopWatch > swatch
stopwatch for the running search, (re)created at the start of search() and reported alongside progres...
Definition search_branch_and_bound.hpp:229
std::vector< ListNode >::iterator TreeLevelIter
iterator over tree levels (used only to clear _tree in setup_default_structures())
Definition search_branch_and_bound.hpp:146
std::ostream * shared_os
to enable sharing the same stream across the methods below
Definition search_branch_and_bound.hpp:202
DIMTYPE get_n() const
total number of features, see n
Definition search_branch_and_bound.hpp:187
RETURNTYPE get_bound_value() const
the current best (bound) criterion value; meaningful only once is_bound_valid()
Definition search_branch_and_bound.hpp:183
RETURNTYPE _boundvalue
the criterion value of _boundset; meaningful only once _boundvalid is true
Definition search_branch_and_bound.hpp:172
void update_bound(const RETURNTYPE val, const PSubset &sub)
Registers one fully-evaluated candidate subset of target cardinality d against the running bound....
Definition search_branch_and_bound.hpp:270
PSubset _tempset
temporary copy of _currentset subset to be modified and evaluated
Definition search_branch_and_bound.hpp:169
DIMTYPE _availiter
iteration cursor used by getFirstAvailable()/getNextAvailable() over _available
Definition search_branch_and_bound.hpp:158
std::vector< Node > VectorNode
type of _available: one Node per original feature, indexed by feature id
Definition search_branch_and_bound.hpp:147
std::vector< ListNode > VectorListNode
the search tree: one ListNode per level, indexed by tree depth k (see _tree)
Definition search_branch_and_bound.hpp:144
bool _boundvalid
true once at least one candidate of target cardinality d has been evaluated, so _boundset/_boundvalue...
Definition search_branch_and_bound.hpp:173
bool output_normal() const
true unless output detail is SILENT
Definition search.hpp:159
void report(std::ostream &os, const msgbuf &m) const
delivers one pre-formatted progress message: to the observer if attached, otherwise as syncout text t...
Definition search.hpp:170
bool result_tracker_active() const
true if a result tracker was assigned via enable_result_tracking() and not since disabled
Definition search.hpp:155
OutputDetail get_output_detail() const
the currently configured output detail level
Definition search.hpp:158
PResultTracker _tracker
the assigned result tracker, or null (see enable_result_tracking()/result_tracker_active())
Definition search.hpp:179
void report_solution(std::ostream &os, const RETURNTYPE value, const SUBSET &sub, const msgbuf &m) const
like report(), for sites announcing a new (sub-)solution; fires on_solution instead
Definition search.hpp:175
bool output_detailed() const
true only at the DETAILED output level
Definition search.hpp:160
Simple stopwatch to measure run time of search algorithms.
Definition stopwatch.hpp:92
FST4 specific error passing class.
Definition error.hpp:61
Message accumulator for Search::report() - collects one progress message exactly as an std::ostringst...
Definition search.hpp:87
FST4 specific error passing class.
The Feature Selection Toolbox 4 library: every library component – data access, criteria and classifi...
Definition data_accessor.hpp:80
void notify(const std::string msg)
Prints msg followed by a newline via syncout::print(); a no-op unless the preprocessor macro DEBUG is...
Definition global.hpp:112
Defines interface for classes that enable collecting multiple results.
Defines interface for search method implementations.
Simple tool to measure run time.
Structure representing search tree node.
Definition search_branch_and_bound.hpp:136
RETURNTYPE value
the node's criterion value: exact once type==COMPUTED, an ordering estimate while type==PREDICTED,...
Definition search_branch_and_bound.hpp:138
DIMTYPE feature
the feature index this node represents removing from its ancestor set (meaningless in the single root...
Definition search_branch_and_bound.hpp:137
NodeType type
how value was obtained, see NodeType
Definition search_branch_and_bound.hpp:139
bool valid
for use in _available only: true while the feature is still an undecided candidate (see available_add...
Definition search_branch_and_bound.hpp:140