25#include <boost/format.hpp>
26#include <boost/make_shared.hpp>
27#include <boost/optional.hpp>
44 template<
typename L,
typename Y>
45 int DecisionTree<L, Y>::Node::nrNodes = 0;
51 template <
typename L,
typename Y>
65 Leaf(
const Y& constant,
size_t nrAssignments = 1)
66 : constant_(constant), nrAssignments_(nrAssignments) {}
83 return (q.isLeaf() && q.sameLeaf(*
this));
87 bool equals(
const Node& q,
const CompareFunc& compare)
const override {
88 const Leaf* other =
dynamic_cast<const Leaf*
>(&q);
89 if (!other)
return false;
90 return compare(this->constant_, other->
constant_);
94 void print(
const std::string& s,
const LabelFormatter& labelFormatter,
95 const ValueFormatter& valueFormatter)
const override {
96 std::cout << s <<
" Leaf " << valueFormatter(constant_) << std::endl;
100 void dot(std::ostream& os,
const LabelFormatter& labelFormatter,
101 const ValueFormatter& valueFormatter,
102 bool showZero)
const override {
103 std::string value = valueFormatter(constant_);
104 if (showZero || value.compare(
"0"))
105 os <<
"\"" << this->id() <<
"\" [label=\"" << value
106 <<
"\", shape=box, rank=sink, height=0.35, fixedsize=true]\n";
116 NodePtr f(
new Leaf(op(constant_), nrAssignments_));
123 NodePtr f(
new Leaf(op(assignment, constant_), nrAssignments_));
132 NodePtr apply_f_op_g(
const Node& g,
const Binary& op)
const override {
133 return g.apply_g_op_fL(*
this, op);
137 NodePtr apply_g_op_fL(
const Leaf& fL,
const Binary& op)
const override {
139 NodePtr h(
new Leaf(op(fL.constant_, constant_), nrAssignments_));
144 NodePtr apply_g_op_fC(
const Choice& fC,
const Binary& op)
const override {
145 return fC.apply_fC_op_gL(*
this, op);
150 return NodePtr(
new Leaf(constant(), nrAssignments()));
153 bool isLeaf()
const override {
return true; }
159 friend class boost::serialization::access;
160 template <
class ARCHIVE>
161 void serialize(ARCHIVE& ar,
const unsigned int ) {
162 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
163 ar& BOOST_SERIALIZATION_NVP(constant_);
164 ar& BOOST_SERIALIZATION_NVP(nrAssignments_);
171 template<
typename L,
typename Y>
186 using ChoicePtr = boost::shared_ptr<const Choice>;
193#ifdef DT_DEBUG_MEMORY
194 std::std::cout << Node::nrNodes <<
" destructing (Choice) " << this->id()
201#ifndef GTSAM_DT_NO_PRUNING
203 assert(f->branches().size() > 0);
206 size_t nrAssignments = 0;
207 for(
auto branch: f->branches()) {
208 assert(branch->isLeaf());
210 boost::dynamic_pointer_cast<const Leaf>(branch)->nrAssignments();
213 new Leaf(boost::dynamic_pointer_cast<const Leaf>(f0)->constant(),
221 bool isLeaf()
const override {
return false; }
225 label_(label), allSame_(true) {
226 branches_.reserve(count);
236 size_t count = f.nrChoices();
237 branches_.reserve(count);
238 for (
size_t i = 0; i < count; i++)
239 push_back(f.
branches_[i]->apply_f_op_g(g, op));
243 size_t count = g.nrChoices();
244 branches_.reserve(count);
245 for (
size_t i = 0; i < count; i++)
246 push_back(g.
branches_[i]->apply_g_op_fC(f, op));
250 size_t count = f.nrChoices();
251 branches_.reserve(count);
252 for (
size_t i = 0; i < count; i++)
262 size_t nrChoices()
const {
263 return branches_.size();
266 const std::vector<NodePtr>& branches()
const {
273 if (allSame_ && !branches_.empty()) {
274 allSame_ = node->sameLeaf(*branches_.back());
276 branches_.push_back(node);
280 void print(
const std::string& s,
const LabelFormatter& labelFormatter,
281 const ValueFormatter& valueFormatter)
const override {
282 std::cout << s <<
" Choice(";
283 std::cout << labelFormatter(label_) <<
") " << std::endl;
284 for (
size_t i = 0; i < branches_.size(); i++)
285 branches_[i]->
print((boost::format(
"%s %d") % s % i).str(),
286 labelFormatter, valueFormatter);
290 void dot(std::ostream& os,
const LabelFormatter& labelFormatter,
291 const ValueFormatter& valueFormatter,
292 bool showZero)
const override {
293 os <<
"\"" << this->id() <<
"\" [shape=circle, label=\"" << label_
295 size_t B = branches_.size();
296 for (
size_t i = 0; i < B; i++) {
301 const Leaf* leaf =
dynamic_cast<const Leaf*
>(branch.get());
302 if (leaf && valueFormatter(leaf->constant()).compare(
"0"))
continue;
305 os <<
"\"" << this->id() <<
"\" -> \"" << branch->id() <<
"\"";
306 if (B == 2 && i == 0) os <<
" [style=dashed]";
308 branch->dot(os, labelFormatter, valueFormatter, showZero);
319 return (q.isLeaf() && q.sameLeaf(*
this));
323 bool equals(
const Node& q,
const CompareFunc& compare)
const override {
325 if (!other)
return false;
326 if (this->label_ != other->
label_)
return false;
327 if (branches_.size() != other->
branches_.size())
return false;
329 for (
size_t i = 0; i < branches_.size(); i++)
340 std::cout <<
"Trying to find value for " << label_ << std::endl;
341 throw std::invalid_argument(
342 "DecisionTree::operator(): value undefined for a label");
345 size_t index = x.at(label_);
346 NodePtr child = branches_[index];
351 Choice(
const L& label,
const Choice& f,
const Unary& op) :
352 label_(label), allSame_(true) {
353 branches_.reserve(f.branches_.size());
355 push_back(branch->apply(op));
371 : label_(label), allSame_(true) {
376 for (
size_t i = 0; i < f.
branches_.size(); i++) {
377 assignment_[label_] = i;
380 push_back(branch->apply(op, assignment_));
383 auto assignment_it = assignment_.find(label_);
384 assignment_.erase(assignment_it);
390 auto r = boost::make_shared<Choice>(label_, *
this, op);
397 auto r = boost::make_shared<Choice>(label_, *
this, op, assignment);
406 NodePtr apply_f_op_g(
const Node& g,
const Binary& op)
const override {
407 return g.apply_g_op_fC(*
this, op);
411 NodePtr apply_g_op_fL(
const Leaf& fL,
const Binary& op)
const override {
412 auto h = boost::make_shared<Choice>(label(), nrChoices());
413 for (
auto&& branch : branches_)
414 h->push_back(fL.apply_f_op_g(*branch, op));
419 NodePtr apply_g_op_fC(
const Choice& fC,
const Binary& op)
const override {
420 auto h = boost::make_shared<Choice>(fC, *
this, op);
425 template<
typename OP>
426 NodePtr apply_fC_op_gL(
const Leaf& gL, OP op)
const {
427 auto h = boost::make_shared<Choice>(label(), nrChoices());
428 for (
auto&& branch : branches_)
429 h->push_back(branch->apply_f_op_g(gL, op));
435 if (label_ == label)
return branches_[index];
438 auto r = boost::make_shared<Choice>(label_, branches_.size());
439 for (
auto&& branch : branches_)
440 r->push_back(branch->choose(label, index));
449 template <
class ARCHIVE>
450 void serialize(ARCHIVE& ar,
const unsigned int ) {
451 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
452 ar& BOOST_SERIALIZATION_NVP(label_);
453 ar& BOOST_SERIALIZATION_NVP(branches_);
454 ar& BOOST_SERIALIZATION_NVP(allSame_);
461 template<
typename L,
typename Y>
465 template<
typename L,
typename Y>
471 template<
typename L,
typename Y>
477 template <
typename L,
typename Y>
479 auto a = boost::make_shared<Choice>(label, 2);
483 root_ = Choice::Unique(a);
487 template <
typename L,
typename Y>
490 if (labelC.second != 2)
throw std::invalid_argument(
491 "DecisionTree: binary constructor called with non-binary label");
492 auto a = boost::make_shared<Choice>(labelC.first, 2);
496 root_ = Choice::Unique(a);
500 template<
typename L,
typename Y>
502 const std::vector<Y>& ys) {
504 root_ = create(labelCs.begin(), labelCs.end(), ys.begin(), ys.end());
508 template<
typename L,
typename Y>
510 const std::string& table) {
513 std::istringstream iss(table);
514 copy(std::istream_iterator<Y>(iss), std::istream_iterator<Y>(),
518 root_ = create(labelCs.begin(), labelCs.end(), ys.begin(), ys.end());
522 template<
typename L,
typename Y>
524 Iterator begin, Iterator end,
const L& label) {
525 root_ = compose(begin, end, label);
529 template<
typename L,
typename Y>
532 const std::vector<DecisionTree> functions{f0, f1};
533 root_ = compose(functions.begin(), functions.end(), label);
537 template <
typename L,
typename Y>
538 template <
typename X,
typename Func>
542 auto L_of_L = [](
const L& label) {
return label; };
543 root_ = convertFrom<L, X>(other.
root_, L_of_L, Y_of_X);
547 template <
typename L,
typename Y>
548 template <
typename M,
typename X,
typename Func>
550 const std::map<M, L>& map, Func Y_of_X) {
551 auto L_of_M = [&map](
const M& label) -> L {
return map.at(label); };
552 root_ = convertFrom<M, X>(other.
root_, L_of_M, Y_of_X);
561 template <
typename L,
typename Y>
562 template <
typename Iterator>
564 Iterator begin, Iterator end,
const L& label)
const {
566 boost::optional<L> highestLabel;
567 size_t nrChoices = 0;
568 for (Iterator it = begin; it != end; it++) {
569 if (it->root_->isLeaf())
571 boost::shared_ptr<const Choice> c =
572 boost::dynamic_pointer_cast<const Choice>(it->root_);
573 if (!highestLabel || c->label() > *highestLabel) {
574 highestLabel.reset(c->label());
575 nrChoices = c->nrChoices();
580 if (!nrChoices || !highestLabel || label > *highestLabel) {
581 auto choiceOnLabel = boost::make_shared<Choice>(label, end - begin);
582 for (Iterator it = begin; it != end; it++)
583 choiceOnLabel->push_back(it->root_);
584 return Choice::Unique(choiceOnLabel);
587 auto choiceOnHighestLabel =
588 boost::make_shared<Choice>(*highestLabel, nrChoices);
590 for (
size_t index = 0; index < nrChoices; index++) {
593 std::vector<DecisionTree> functions;
594 for (Iterator it = begin; it != end; it++) {
596 DecisionTree chosen = it->choose(*highestLabel, index);
597 functions.push_back(chosen);
600 NodePtr fi = compose(functions.begin(), functions.end(), label);
601 choiceOnHighestLabel->push_back(fi);
603 return Choice::Unique(choiceOnHighestLabel);
628 template<
typename L,
typename Y>
629 template<
typename It,
typename ValueIt>
631 It begin, It end, ValueIt beginY, ValueIt endY)
const {
633 size_t nrChoices = begin->second;
634 size_t size = endY - beginY;
637 It labelC = begin + 1;
641 if (size != nrChoices) {
642 std::cout <<
"Trying to create DD on " << begin->first << std::endl;
643 std::cout << boost::format(
644 "DecisionTree::create: expected %d values but got %d "
648 throw std::invalid_argument(
"DecisionTree::create invalid argument");
650 auto choice = boost::make_shared<Choice>(begin->first, endY - beginY);
651 for (ValueIt y = beginY; y != endY; y++)
653 return Choice::Unique(choice);
659 std::vector<DecisionTree> functions;
660 size_t split = size / nrChoices;
661 for (
size_t i = 0; i < nrChoices; i++, beginY +=
split) {
662 NodePtr f = create<It, ValueIt>(labelC, end, beginY, beginY +
split);
663 functions.emplace_back(f);
665 return compose(functions.begin(), functions.end(), begin->first);
669 template <
typename L,
typename Y>
670 template <
typename M,
typename X>
673 std::function<L(
const M&)> L_of_M,
674 std::function<Y(
const X&)> Y_of_X)
const {
681 if (
auto leaf = boost::dynamic_pointer_cast<const MXLeaf>(f)) {
682 return NodePtr(
new Leaf(Y_of_X(leaf->constant()), leaf->nrAssignments()));
687 auto choice = boost::dynamic_pointer_cast<const MXChoice>(f);
688 if (!choice)
throw std::invalid_argument(
689 "DecisionTree::convertFrom: Invalid NodePtr");
692 const M oldLabel = choice->label();
693 const L newLabel = L_of_M(oldLabel);
696 std::vector<LY> functions;
697 for (
auto&& branch : choice->branches()) {
698 functions.emplace_back(convertFrom<M, X>(branch, L_of_M, Y_of_X));
700 return LY::compose(functions.begin(), functions.end(), newLabel);
714 template <
typename L,
typename Y>
716 using F = std::function<void(
const Y&)>;
723 if (
auto leaf = boost::dynamic_pointer_cast<const Leaf>(node))
724 return f(leaf->constant());
727 auto choice = boost::dynamic_pointer_cast<const Choice>(node);
729 throw std::invalid_argument(
"DecisionTree::Visit: Invalid NodePtr");
730 for (
auto&& branch : choice->branches()) (*
this)(branch);
734 template <
typename L,
typename Y>
735 template <
typename Func>
751 template <
typename L,
typename Y>
760 if (
auto leaf = boost::dynamic_pointer_cast<const Leaf>(node))
764 auto choice = boost::dynamic_pointer_cast<const Choice>(node);
766 throw std::invalid_argument(
"DecisionTree::VisitLeaf: Invalid NodePtr");
767 for (
auto&& branch : choice->branches()) (*
this)(branch);
771 template <
typename L,
typename Y>
772 template <
typename Func>
785 template <
typename L,
typename Y>
787 using F = std::function<void(
const Assignment<L>&,
const Y&)>;
795 if (
auto leaf = boost::dynamic_pointer_cast<const Leaf>(node))
799 auto choice = boost::dynamic_pointer_cast<const Choice>(node);
801 throw std::invalid_argument(
"DecisionTree::VisitWith: Invalid NodePtr");
802 for (
size_t i = 0; i < choice->nrChoices(); i++) {
805 (*this)(choice->branches()[i]);
808 auto choice_it =
assignment.find(choice->label());
814 template <
typename L,
typename Y>
815 template <
typename Func>
822 template <
typename L,
typename Y>
825 visit([&total](
const Y& node) { total += 1; });
831 template <
typename L,
typename Y>
832 template <
typename Func,
typename X>
834 visit([&](
const Y& y) { x0 = f(y, x0); });
852 template <
typename L,
typename Y>
856 for (
auto&& kv : assignment) {
857 unique.insert(kv.first);
865 template <
typename L,
typename Y>
867 const CompareFunc& compare)
const {
868 return root_->equals(*other.
root_, compare);
871 template <
typename L,
typename Y>
873 const LabelFormatter& labelFormatter,
874 const ValueFormatter& valueFormatter)
const {
875 root_->print(s, labelFormatter, valueFormatter);
878 template<
typename L,
typename Y>
880 return root_->equals(*other.
root_);
883 template<
typename L,
typename Y>
885 return root_->operator ()(x);
888 template<
typename L,
typename Y>
892 throw std::runtime_error(
893 "DecisionTree::apply(unary op) undefined for empty tree.");
899 template <
typename L,
typename Y>
901 const UnaryAssignment& op)
const {
904 throw std::runtime_error(
905 "DecisionTree::apply(unary op) undefined for empty tree.");
912 template<
typename L,
typename Y>
914 const Binary& op)
const {
916 if (empty() || g.
empty()) {
917 throw std::runtime_error(
918 "DecisionTree::apply(binary op) undefined for empty trees.");
936 template<
typename L,
typename Y>
938 size_t cardinality,
const Binary& op)
const {
940 for (
size_t index = 1; index < cardinality; index++) {
942 result = result.apply(chosen, op);
948 template <
typename L,
typename Y>
950 const LabelFormatter& labelFormatter,
951 const ValueFormatter& valueFormatter,
952 bool showZero)
const {
953 os <<
"digraph G {\n";
954 root_->dot(os, labelFormatter, valueFormatter, showZero);
955 os <<
" [ordering=out]}" << std::endl;
958 template <
typename L,
typename Y>
960 const LabelFormatter& labelFormatter,
961 const ValueFormatter& valueFormatter,
962 bool showZero)
const {
963 std::ofstream os((name +
".dot").c_str());
964 dot(os, labelFormatter, valueFormatter, showZero);
966 system((
"dot -Tpdf " + name +
".dot -o " + name +
".pdf >& /dev/null")
969 throw std::runtime_error(
"DecisionTree::dot system call failed");
972 template <
typename L,
typename Y>
974 const ValueFormatter& valueFormatter,
975 bool showZero)
const {
976 std::stringstream ss;
977 dot(ss, labelFormatter, valueFormatter, showZero);
Decision Tree for use in DiscreteFactors.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
Split the graph into two parts: one corresponds to the given spanning tree, and the other corresponds...
Definition graph-inl.h:255
double dot(const V1 &a, const V2 &b)
Dot product.
Definition Vector.h:195
Template to create a binary predicate.
Definition Testable.h:111
An assignment from labels to value index (size_t).
Definition Assignment.h:37
Definition DecisionTree-inl.h:52
NodePtr choose(const L &label, size_t index) const override
choose a branch, create new memory !
Definition DecisionTree-inl.h:149
const Y & operator()(const Assignment< L > &x) const override
evaluate
Definition DecisionTree-inl.h:110
NodePtr apply(const UnaryAssignment &op, const Assignment< L > &assignment) const override
Apply unary operator with assignment.
Definition DecisionTree-inl.h:121
bool equals(const Node &q, const CompareFunc &compare) const override
equality up to tolerance
Definition DecisionTree-inl.h:87
Y constant_
constant stored in this leaf
Definition DecisionTree-inl.h:54
void print(const std::string &s, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter) const override
print
Definition DecisionTree-inl.h:94
NodePtr apply(const Unary &op) const override
apply unary operator
Definition DecisionTree-inl.h:115
bool sameLeaf(const Leaf &q) const override
Leaf-Leaf equality.
Definition DecisionTree-inl.h:77
Leaf(const Y &constant, size_t nrAssignments=1)
Constructor from constant.
Definition DecisionTree-inl.h:65
size_t nrAssignments_
The number of assignments contained within this leaf.
Definition DecisionTree-inl.h:59
void dot(std::ostream &os, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter, bool showZero) const override
Write graphviz format to stream os.
Definition DecisionTree-inl.h:100
Leaf()
Default constructor for serialization.
Definition DecisionTree-inl.h:62
bool sameLeaf(const Node &q) const override
polymorphic equality: is q a leaf and is it the same as this leaf?
Definition DecisionTree-inl.h:82
const Y & constant() const
Return the constant.
Definition DecisionTree-inl.h:69
size_t nrAssignments() const
Return the number of assignments contained within this leaf.
Definition DecisionTree-inl.h:74
Definition DecisionTree-inl.h:172
NodePtr apply(const Unary &op) const override
apply unary operator.
Definition DecisionTree-inl.h:389
Choice(const L &label, const Choice &f, const UnaryAssignment &op, const Assignment< L > &assignment)
Constructor which accepts a UnaryAssignment op and the corresponding assignment.
Definition DecisionTree-inl.h:369
const L & label() const
Return the label of this choice node.
Definition DecisionTree-inl.h:258
void print(const std::string &s, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter) const override
print (as a tree).
Definition DecisionTree-inl.h:280
NodePtr apply(const UnaryAssignment &op, const Assignment< L > &assignment) const override
Apply unary operator with assignment.
Definition DecisionTree-inl.h:395
L label_
the label of the variable on which we split
Definition DecisionTree-inl.h:174
bool sameLeaf(const Node &q) const override
polymorphic equality: if q is a leaf, could be...
Definition DecisionTree-inl.h:318
Choice(const Choice &f, const Choice &g, const Binary &op)
Construct from applying binary op to two Choice nodes.
Definition DecisionTree-inl.h:230
void push_back(const NodePtr &node)
add a branch: TODO merge into constructor
Definition DecisionTree-inl.h:271
std::vector< NodePtr > branches_
The children of this Choice node.
Definition DecisionTree-inl.h:177
Choice()
Default constructor for serialization.
Definition DecisionTree-inl.h:190
const Y & operator()(const Assignment< L > &x) const override
evaluate
Definition DecisionTree-inl.h:336
Choice(const L &label, size_t count)
Constructor, given choice label and mandatory expected branch count.
Definition DecisionTree-inl.h:224
NodePtr choose(const L &label, size_t index) const override
choose a branch, recursively
Definition DecisionTree-inl.h:434
void dot(std::ostream &os, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter, bool showZero) const override
output to graphviz (as a a graph)
Definition DecisionTree-inl.h:290
bool sameLeaf(const Leaf &q) const override
Choice-Leaf equality: always false.
Definition DecisionTree-inl.h:313
static NodePtr Unique(const ChoicePtr &f)
If all branches of a choice node f are the same, just return a branch.
Definition DecisionTree-inl.h:200
bool equals(const Node &q, const CompareFunc &compare) const override
equality
Definition DecisionTree-inl.h:323
Functor performing depth-first visit to each leaf with the leaf value as the argument.
Definition DecisionTree-inl.h:715
F f
folding function object.
Definition DecisionTree-inl.h:718
void operator()(const typename DecisionTree< L, Y >::NodePtr &node) const
Do a depth-first visit on the tree rooted at node.
Definition DecisionTree-inl.h:721
Visit(F f)
Construct from folding function.
Definition DecisionTree-inl.h:717
Functor performing depth-first visit to each leaf with the Leaf object passed as an argument.
Definition DecisionTree-inl.h:752
VisitLeaf(F f)
Construct from folding function.
Definition DecisionTree-inl.h:754
void operator()(const typename DecisionTree< L, Y >::NodePtr &node) const
Do a depth-first visit on the tree rooted at node.
Definition DecisionTree-inl.h:758
F f
folding function object.
Definition DecisionTree-inl.h:755
Functor performing depth-first visit to each leaf with the leaf's Assignment<L> and value passed as a...
Definition DecisionTree-inl.h:786
VisitWith(F f)
Construct from folding function.
Definition DecisionTree-inl.h:788
Assignment< L > assignment
Assignment, mutating through recursion.
Definition DecisionTree-inl.h:789
void operator()(const typename DecisionTree< L, Y >::NodePtr &node)
Do a depth-first visit on the tree rooted at node.
Definition DecisionTree-inl.h:793
F f
folding function object.
Definition DecisionTree-inl.h:790
a decision tree is a function from assignments to values.
Definition DecisionTree.h:61
DecisionTree apply(const Unary &op) const
apply Unary operation "op" to f
Definition DecisionTree-inl.h:889
NodePtr convertFrom(const typename DecisionTree< M, X >::NodePtr &f, std::function< L(const M &)> L_of_M, std::function< Y(const X &)> Y_of_X) const
Convert from a DecisionTree<M, X> to DecisionTree<L, Y>.
Definition DecisionTree-inl.h:671
NodePtr create(It begin, It end, ValueIt beginY, ValueIt endY) const
Internal recursive function to create from keys, cardinalities, and Y values.
Definition DecisionTree-inl.h:630
typename Node::Ptr NodePtr
---------------------— Node base class ------------------------—
Definition DecisionTree.h:143
std::set< L > labels() const
Retrieve all unique labels as a set.
Definition DecisionTree-inl.h:853
bool empty() const
Check if tree is empty.
Definition DecisionTree.h:257
void visit(Func f) const
Visit all leaves in depth-first fashion.
Definition DecisionTree-inl.h:736
void visitLeaf(Func f) const
Visit all leaves in depth-first fashion.
Definition DecisionTree-inl.h:773
std::function< Y(const Y &)> Unary
Handy typedefs for unary and binary function types.
Definition DecisionTree.h:74
X fold(Func f, X x0) const
Fold a binary function over the tree, returning accumulator.
Definition DecisionTree-inl.h:833
NodePtr root_
A DecisionTree just contains the root. TODO(dellaert): make protected.
Definition DecisionTree.h:146
void print(const std::string &s, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter) const
GTSAM-style print.
Definition DecisionTree-inl.h:872
DecisionTree combine(const L &label, size_t cardinality, const Binary &op) const
combine subtrees on key with binary operation "op"
Definition DecisionTree-inl.h:937
void visitWith(Func f) const
Visit all leaves in depth-first fashion.
Definition DecisionTree-inl.h:816
const Y & operator()(const Assignment< L > &x) const
evaluate
Definition DecisionTree-inl.h:884
void dot(std::ostream &os, const LabelFormatter &labelFormatter, const ValueFormatter &valueFormatter, bool showZero=true) const
output to graphviz format, stream version
Definition DecisionTree-inl.h:949
friend class boost::serialization::access
Serialization function.
Definition DecisionTree.h:399
bool operator==(const DecisionTree &q) const
equality
Definition DecisionTree-inl.h:879
std::pair< L, size_t > LabelC
A label annotated with cardinality.
Definition DecisionTree.h:79
size_t nrLeaves() const
Return the number of leaves in the tree.
Definition DecisionTree-inl.h:823
DecisionTree()
Default constructor (for serialization)
Definition DecisionTree-inl.h:462
---------------------— Node base class ------------------------—
Definition DecisionTree.h:86