Feature Selection Toolbox FST4
UTIA · Czech Academy of Sciences
Loading...
Searching...
No Matches
search_branch_and_bound_basic.hpp
Go to the documentation of this file.
1#ifndef FSTSEARCHBRANCHANDBOUNDBASIC_H
2#define FSTSEARCHBRANCHANDBOUNDBASIC_H
3 /*
27=========================================================================
28Copyright and license:
29 * FST4 software (with the exception of any bundled or externally linked
30 third-party components) is Copyright (C) 2000-present Institute of
31 Information Theory and Automation of the Czech Academy of Sciences (UTIA).
32 * FST4 is free software: you can redistribute it and/or modify it under
33 the terms of the GNU Affero General Public License as published by the
34 Free Software Foundation, version 3. The full text of the license is in
35 the file LICENSE in the distribution root and at
36 https://www.gnu.org/licenses/agpl-3.0.html.
37 * FST4 is distributed in the hope that it will be useful, but WITHOUT ANY
38 WARRANTY; without even the implied warranty of MERCHANTABILITY or
39 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
40 License for more details.
41 * Closed-source use without the AGPL's copyleft obligations requires a
42 commercial license from UTIA; in case of interest write to
43 utia@utia.cas.cz. LICENSING.md in the distribution root explains both
44 options, the contributor license agreement that every contribution
45 requires, and the contacts (technical questions and pull requests:
46 somol@utia.cas.cz, with "FST" in the subject line).
47========================================================================== */
48
49#include <memory>
50#include <cassert>
51#include <iostream>
53#include "error.hpp"
54#include "global.hpp"
55#include "fst_rand.hpp" // FST-owned PRNG: identical random sequences on every platform
56#include "result_tracker.hpp"
57
58/*============== Template parameter type naming conventions ==============
59--------- Numeric types: -------------------------------------------------
60DATATYPE - data sample values - usually real numbers (but may be integers
61 in text processing etc.)
62REALTYPE - must be real numbers - for representing intermediate results of
63 calculations like mean, covariance etc.
64IDXTYPE - index values for enumeration of data samples - (nonnegative) integers,
65 extent depends on numbers of samples in data
66DIMTYPE - index values for enumeration of features (dimensions), or classes (not
67 class sizes) - (nonnegative) integers, usually lower extent than IDXTYPE,
68 but be aware of expressions like _classes*_features*_features !
69 in linearized representations of feature matrices for all classes
70BINTYPE - feature selection marker type - represents ca. <10 different feature
71 states (selected, deselected, sel./desel. temporarily 1st nested loop, 2nd...)
72RETURNTYPE - criterion value: real value, but may be extended in future to support
73 multiple values
74--------- Class types: ---------------------------------------------------
75SUBSET - class of class type Subset
76CLASSIFIER - class implementing interface defined in abstract class Classifier
77EVALUATOR - class implementing interface defined in abstract class Sequential_Step
78DISTANCE - class implementing interface defined in abstract class Distance
79DATAACCESSOR - class implementing interface defined in abstract class Data_Accessor
80INTERVALCONTAINER - class of class type Data_Intervaller
81CONTAINER - STL container of class type Data_Interval
82========================================================================== */
83
84namespace FST {
85
100
101template<class RETURNTYPE, typename DIMTYPE, class SUBSET, class CRITERION>
102class Search_Branch_And_Bound_Basic : public Search_Branch_And_Bound<RETURNTYPE,DIMTYPE,SUBSET,CRITERION>{
103public:
106 typedef typename parent::PSubset PSubset;
107 typedef typename parent::PNode PNode;
108 typedef typename parent::Node Node;
109 typedef typename parent::NodeType NodeType;
111 explicit Search_Branch_And_Bound_Basic(PEvaluatorEngine engine=PEvaluatorEngine()):Search_Branch_And_Bound<RETURNTYPE,DIMTYPE,SUBSET,CRITERION>(engine) {notify("Search_Branch_And_Bound_Basic constructor.");}
112 virtual ~Search_Branch_And_Bound_Basic() {notify("Search_Branch_And_Bound_Basic destructor.");}
113
114 // for search() implementation see parent class
115
117 virtual std::ostream& print(std::ostream& os) const override {
118 if(parent::get_engine()->is_threaded()) os << "Basic Branch & Bound (BBB) [Search_Branch_And_Bound_Basic(threads="<<parent::get_engine()->get_max_threads()<<")]";
119 else os << "Basic Branch & Bound (BBB) [Search_Branch_And_Bound_Basic()]";
120 return os;
121 };
122
123protected:
124 // the following may be overriden in descendant Branch and Bound specialization classes
125 virtual void initialize(const DIMTYPE d, const DIMTYPE n, const PCriterion crit) override {}
126 virtual void pre_evaluate_availables() override;
127 virtual void post_process_tree_level() override;
128 virtual bool cut_possible() override;
129};
130
131template<class RETURNTYPE, typename DIMTYPE, class SUBSET, class CRITERION>
133{
134 const PSubset &currentset=parent::get_currentset(); assert(currentset);
135 // pre-evaluate available features before next tree level construction
136 PNode avail;
137 for(bool got=this->getFirstAvailable(avail);got;got=this->getNextAvailable(avail))
138 {
139 avail->value=(RETURNTYPE)fst_rand(); // in basic B&B ordering is not defined, randomization here aims at preventing worst-case scenarios
140 avail->type=parent::UNKNOWN;
141 }
142}
143
144template<class RETURNTYPE, typename DIMTYPE, class SUBSET, class CRITERION>
146{
147 assert(parent::get_criterion());
148 assert(parent::get_engine());
149 const PSubset &currentset=parent::get_currentset(); assert(currentset);
150 // supply the true criterion value of the level's chosen nodes (BBB pre-orders by
151 // random values, so every chosen node needs computing) - batched through the
152 // engine. Results map back to their nodes by submission order: the per-result
153 // callback fires in add-order under both engine implementations (the submitted
154 // vector is fully built before the first add_candidate because the sequential
155 // engine fires callbacks synchronously inside add_candidate); list node pointers
156 // stay stable (no insert/erase during the batch). A threaded run returns the same
157 // tree as a sequential one - candidate generation (and the fst_rand pre-ordering)
158 // stays on the master thread
159 PNode nod;
160 std::vector<PNode> submitted;
161 for(bool got=this->getFirstNode(nod);got;got=this->getNextNode(nod))
162 if(nod->type!=parent::COMPUTED) submitted.push_back(nod);
163 if(submitted.empty()) return;
164
165 DIMTYPE done=0;
166 typename parent::EVALUATORENGINE::ResultCallback on_result=[&submitted,&done](const RETURNTYPE value, const PSubset&, const DIMTYPE feat) {
167 PNode node=submitted[done++];
168 assert(node->feature==feat); (void)feat;
169 node->value=value;
170 node->type=parent::COMPUTED;
171 };
172 parent::get_engine()->initialize(parent::get_criterion(),(DIMTYPE)submitted.size(),on_result);
173 for(PNode snod : submitted)
174 {
175 assert(currentset->selected_raw(snod->feature));
176 currentset->deselect_raw(snod->feature);
177 if(!parent::get_engine()->add_candidate(currentset,snod->feature)) throw FST::fst_error("Criterion evaluation failure.");
178 currentset->select_raw(snod->feature);
179 }
180 // a failed batch must not leave nodes UNKNOWN on the tree path - fail the search instead
181 if(!parent::get_engine()->collect()) throw FST::fst_error("Criterion evaluation failure.");
182}
183
184template<class RETURNTYPE, typename DIMTYPE, class SUBSET, class CRITERION>
186{ // NOTE: the lazy compute below deliberately stays on the master thread -
187 // it is a single evaluation on the traversal's critical path (nothing to batch)
189 Node &currentnode=parent::get_current_node();
190 if(currentnode.type!=parent::COMPUTED) {
191 const PSubset &currentset=parent::get_currentset(); assert(currentset);
192 assert(parent::get_criterion());
193 assert(currentnode.feature<parent::get_n());
194 assert(currentset->selected_raw(currentnode.feature));
195 currentset->deselect_raw(currentnode.feature);
196 if(!parent::get_criterion()->evaluate(currentnode.value,currentset)) throw FST::fst_error("Criterion evaluation failure.");
197 currentset->select_raw(currentnode.feature);
198 currentnode.type=parent::COMPUTED;
199 }
200 if(currentnode.value<=parent::get_bound_value()) {
201 return true;
202 }
203 }
204 return false;
205}
206
207} // namespace
208#endif // FSTSEARCHBRANCHANDBOUNDBASIC_H ///:~
Implements Branch and Bound Basic method, i.e., with randomized node ordering.
Definition search_branch_and_bound_basic.hpp:102
parent::PSubset PSubset
shared pointer to a feature subset
Definition search_branch_and_bound_basic.hpp:106
parent::Node Node
search-tree node record (feature, value, type, valid), see Search_Branch_And_Bound
Definition search_branch_and_bound_basic.hpp:108
parent::PNode PNode
pointer to a search-tree Node, see Search_Branch_And_Bound
Definition search_branch_and_bound_basic.hpp:107
virtual void pre_evaluate_availables() override
BBB does not order the tree by any estimate of feature importance: every available feature gets a ran...
Definition search_branch_and_bound_basic.hpp:132
parent::NodeType NodeType
UNKNOWN/RANDOM/PREDICTED/COMPUTED node-value provenance, see Search_Branch_And_Bound.
Definition search_branch_and_bound_basic.hpp:109
Search_Branch_And_Bound_Basic(PEvaluatorEngine engine=PEvaluatorEngine())
engine forwarded to Search_Branch_And_Bound; defaults to sequential in-line evaluation if not supplie...
Definition search_branch_and_bound_basic.hpp:111
Search_Branch_And_Bound< RETURNTYPE, DIMTYPE, SUBSET, CRITERION > parent
base class alias
Definition search_branch_and_bound_basic.hpp:104
virtual void initialize(const DIMTYPE d, const DIMTYPE n, const PCriterion crit) override
BBB keeps no structures of its own beyond the base class's tree, so there is nothing to set up.
Definition search_branch_and_bound_basic.hpp:125
virtual std::ostream & print(std::ostream &os) const override
writes the method's name and, with a threaded engine, the number of worker threads
Definition search_branch_and_bound_basic.hpp:117
parent::PCriterion PCriterion
shared pointer to the criterion the search optimizes
Definition search_branch_and_bound_basic.hpp:105
virtual bool cut_possible() override
computes the current node's criterion value if it is not known yet and reports whether the node's val...
Definition search_branch_and_bound_basic.hpp:185
parent::PEvaluatorEngine PEvaluatorEngine
shared pointer to the injected evaluation-strategy engine
Definition search_branch_and_bound_basic.hpp:110
virtual void post_process_tree_level() override
the ordering values above are random, not criterion values, so every node chosen for the new level st...
Definition search_branch_and_bound_basic.hpp:145
PSubset & get_currentset()
mutable accessor for _currentset, for use by descendant B&B variants' hooks
Definition search_branch_and_bound.hpp:198
Node * PNode
pointer to a Node, as used by the getFirst.../getNext... accessors below
Definition search_branch_and_bound.hpp:142
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
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
PEvaluatorEngine const & get_engine() const
accessor for the injected evaluation strategy (sequential-inline or thread-pooled),...
Definition search_branch_and_bound.hpp:181
bool getFirstAvailable(PNode &avail)
begins iteration over _available in feature-index order, skipping withdrawn (invalid) entries,...
Definition search_branch_and_bound.hpp:193
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
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
bool is_bound_valid() const
true once a valid bound has been established, see _boundvalid
Definition search_branch_and_bound.hpp:184
std::shared_ptr< SUBSET > PSubset
shared pointer to a feature subset
Definition search_branch_and_bound.hpp:113
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
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
FST4 specific error passing class.
Definition error.hpp:61
FST4 specific error passing class.
FST4-owned pseudo-random number generator (UCRT-compatible LCG), replacing platform-specific std::ran...
Global definitions.
The Feature Selection Toolbox 4 library: every library component – data access, criteria and classifi...
Definition data_accessor.hpp:80
int fst_rand()
Returns the next pseudo-random draw in 0..FST_RAND_MAX; use instead of std::rand().
Definition fst_rand.hpp:93
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.
Implements Branch and Bound template method as basis for more advanced B&B implementations.
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
Copyright © 2000–present ÚTIA, Institute of Information Theory and Automation of the Czech Academy of Sciences · Contacts · This site sets no cookies and uses no analytics.