49#ifndef DOXYGEN_SHOULD_SKIP_THIS
58 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
61 STRUCTURAL_CONSTRAINT& constraint,
62 GRAPH_CHANGES_GENERATOR& changes_generator) :
63 _score_(score.clone()), _constraint_(&constraint), _changes_generator_(&changes_generator) {
65 GUM_CONSTRUCTOR(GraphChangesSelector4DiGraph);
69 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
70 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
71 GraphChangesSelector4DiGraph(
72 const GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >&
74 _score_(from._score_ != nullptr ? from._score_->clone() : nullptr),
75 _constraint_(from._constraint_), _changes_generator_(from._changes_generator_),
76 _changes_(from._changes_), _change_scores_(from._change_scores_),
77 _change_queue_per_node_(from._change_queue_per_node_), _node_queue_(from._node_queue_),
78 _illegal_changes_(from._illegal_changes_),
79 _node_current_scores_(from._node_current_scores_), _parents_(from._parents_),
80 _queues_valid_(from._queues_valid_), _queues_to_update_(from._queues_to_update_) {
82 GUM_CONS_CPY(GraphChangesSelector4DiGraph);
86 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
87 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
88 GraphChangesSelector4DiGraph(
89 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >&& from) :
90 _score_(from._score_), _constraint_(
std::move(from._constraint_)),
91 _changes_generator_(
std::move(from._changes_generator_)),
92 _changes_(
std::move(from._changes_)), _change_scores_(
std::move(from._change_scores_)),
93 _change_queue_per_node_(
std::move(from._change_queue_per_node_)),
94 _node_queue_(
std::move(from._node_queue_)),
95 _illegal_changes_(
std::move(from._illegal_changes_)),
96 _node_current_scores_(
std::move(from._node_current_scores_)),
97 _parents_(
std::move(from._parents_)), _queues_valid_(
std::move(from._queues_valid_)),
98 _queues_to_update_(
std::move(from._queues_to_update_)) {
99 from._score_ =
nullptr;
101 GUM_CONS_MOV(GraphChangesSelector4DiGraph);
105 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
107 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
108 GRAPH_CHANGES_GENERATOR >::~GraphChangesSelector4DiGraph() {
109 if (_score_ !=
nullptr)
delete _score_;
110 GUM_DESTRUCTOR(GraphChangesSelector4DiGraph);
114 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
115 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >&
116 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::operator=(
117 const GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >&
121 if (_score_ !=
nullptr) {
126 if (from._score_ !=
nullptr) _score_ = from._score_->clone();
127 _constraint_ = from._constraint_;
128 _changes_generator_ = from._changes_generator_;
129 _changes_ = from._changes_;
130 _change_scores_ = from._change_scores_;
131 _change_queue_per_node_ = from._change_queue_per_node_;
132 _node_queue_ = from._node_queue_;
133 _illegal_changes_ = from._illegal_changes_;
134 _node_current_scores_ = from._node_current_scores_;
135 _parents_ = from._parents_;
136 _queues_valid_ = from._queues_valid_;
137 _queues_to_update_ = from._queues_to_update_;
144 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
145 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >&
146 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::operator=(
147 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >&& from) {
149 _score_ = from._score_;
150 from._score_ =
nullptr;
152 _constraint_ = std::move(from._constraint_);
153 _changes_generator_ = std::move(from._changes_generator_);
154 _changes_ = std::move(from._changes_);
155 _change_scores_ = std::move(from._change_scores_);
156 _change_queue_per_node_ = std::move(from._change_queue_per_node_);
157 _node_queue_ = std::move(from._node_queue_);
158 _illegal_changes_ = std::move(from._illegal_changes_);
159 _node_current_scores_ = std::move(from._node_current_scores_);
160 _parents_ = std::move(from._parents_);
161 _queues_valid_ = std::move(from._queues_valid_);
162 _queues_to_update_ = std::move(from._queues_to_update_);
169 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
170 INLINE
bool GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
171 isChangeValid(
const GraphChange& change)
const {
172 return _constraint_->checkModification(change);
176 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
177 INLINE
bool GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
178 _isChangeValid_(
const std::size_t index)
const {
179 return isChangeValid(_changes_[index]);
183 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
184 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::setGraph(
187 const DatabaseTable& database = _score_->database();
188 const auto& nodeId2Columns = _score_->nodeId2Columns();
190 if (nodeId2Columns.empty()) {
191 const NodeId nb_nodes = NodeId(database.nbVariables());
192 for (NodeId i = NodeId(0); i < nb_nodes; ++i) {
193 if (!graph.existsNode(i)) { graph.addNodeWithId(i); }
196 for (
auto iter = nodeId2Columns.cbegin(); iter != nodeId2Columns.cend(); ++iter) {
197 const NodeId
id = iter.first();
198 if (!graph.existsNode(
id)) { graph.addNodeWithId(
id); }
205 if (nodeId2Columns.empty()) {
206 const NodeId nb_nodes = NodeId(database.nbVariables());
207 for (
auto node: graph) {
208 if (node >= nb_nodes) { graph.eraseNode(node); }
211 for (
auto node: graph) {
212 if (!nodeId2Columns.existsFirst(node)) { graph.eraseNode(node); }
225 _constraint_->setGraph(graph);
226 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
228 _changes_generator_->constraint().setGraph(graph);
231 _changes_generator_->setGraph(graph);
236 const std::size_t nb_nodes = graph.size();
238 const std::vector< NodeId > empty_pars;
240 _parents_.resize(nb_nodes);
241 for (
const auto node: graph) {
242 auto& node_parents = _parents_.insert(node, empty_pars).second;
243 const NodeSet& dag_parents = graph.parents(node);
244 if (!dag_parents.empty()) {
245 node_parents.resize(dag_parents.size());
246 std::size_t j = std::size_t(0);
247 for (
const auto par: dag_parents) {
248 node_parents[j] = par;
256 _node_current_scores_.clear();
257 _node_current_scores_.resize(nb_nodes);
258 for (
const auto node: graph) {
259 _node_current_scores_.insert(node, _score_->score(node, _parents_[node]));
264 _changes_.resize(nb_nodes);
265 for (
const auto& change: *_changes_generator_) {
268 _changes_generator_->notifyGetCompleted();
272 _illegal_changes_.clear();
275 _change_scores_.clear();
276 _change_scores_.resize(_changes_.size(),
277 std::pair< double, double >(std::numeric_limits< double >::min(),
278 std::numeric_limits< double >::min()));
279 _change_queue_per_node_.clear();
280 _change_queue_per_node_.resize(nb_nodes);
282 const PriorityQueue< std::size_t, double, std::greater< double > > empty_prio;
283 for (
const auto node: graph) {
284 _change_queue_per_node_.insert(node, empty_prio);
288 for (std::size_t i = std::size_t(0); i < _changes_.size(); ++i) {
289 if (!_isChangeValid_(i)) {
290 _illegal_changes_.insert(i);
292 const GraphChange& change = _changes_[i];
294 switch (change.type()) {
295 case GraphChangeType::ARC_ADDITION : {
296 auto& parents = _parents_[change.node2()];
297 parents.push_back(change.node1());
299 = _score_->score(change.node2(), parents) - _node_current_scores_[change.node2()];
302 _change_scores_[i].second = delta;
303 _change_queue_per_node_[change.node2()].insert(i, delta);
306 case GraphChangeType::ARC_DELETION : {
307 auto& parents = _parents_[change.node2()];
308 for (
auto& par: parents) {
309 if (par == change.node1()) {
310 par = *(parents.rbegin());
316 = _score_->score(change.node2(), parents) - _node_current_scores_[change.node2()];
317 parents.push_back(change.node1());
319 _change_scores_[i].second = delta;
320 _change_queue_per_node_[change.node2()].insert(i, delta);
323 case GraphChangeType::ARC_REVERSAL : {
325 auto& parents2 = _parents_[change.node2()];
326 for (
auto& par: parents2) {
327 if (par == change.node1()) {
328 par = *(parents2.rbegin());
334 const double delta2 = _score_->score(change.node2(), parents2)
335 - _node_current_scores_[change.node2()];
336 parents2.push_back(change.node1());
339 auto& parents1 = _parents_[change.node1()];
340 parents1.push_back(change.node2());
341 const double delta1 = _score_->score(change.node1(), parents1)
342 - _node_current_scores_[change.node1()];
345 _change_scores_[i].first = delta1;
346 _change_scores_[i].second = delta2;
348 const double delta = delta1 + delta2;
349 _change_queue_per_node_[change.node1()].insert(i, delta);
350 _change_queue_per_node_[change.node2()].insert(i, delta);
356 "Method setGraph of GraphChangesSelector4DiGraph "
357 <<
"does not handle yet graph change of type " << change.type());
364 _node_queue_.clear();
365 for (
const auto node: graph) {
366 _node_queue_.insert(node,
367 _change_queue_per_node_[node].empty()
368 ? std::numeric_limits< double >::min()
369 : _change_queue_per_node_[node].topPriority());
371 _queues_valid_ =
true;
372 _queues_to_update_.clear();
376 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
377 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
378 _invalidateChange_(
const std::size_t change_index) {
379 const GraphChange& change = _changes_[change_index];
380 if (change.type() == GraphChangeType::ARC_REVERSAL) {
382 PriorityQueue< std::size_t, double, std::greater< double > >& queue1
383 = _change_queue_per_node_[change.node1()];
384 queue1.erase(change_index);
387 const double new_priority
388 = queue1.empty() ? std::numeric_limits< double >::min() : queue1.topPriority();
389 _node_queue_.setPriority(change.node1(), new_priority);
393 PriorityQueue< std::size_t, double, std::greater< double > >& queue2
394 = _change_queue_per_node_[change.node2()];
395 queue2.erase(change_index);
398 const double new_priority
399 = queue2.empty() ? std::numeric_limits< double >::min() : queue2.topPriority();
400 _node_queue_.setPriority(change.node2(), new_priority);
403 _illegal_changes_.insert(change_index);
407 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
408 bool GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::empty() {
411 if (!_queues_valid_) {
412 for (
auto& queue_pair: _change_queue_per_node_) {
413 auto& queue = queue_pair.second;
414 while (!queue.empty() && !_isChangeValid_(queue.top())) {
415 _invalidateChange_(queue.top());
418 _queues_valid_ =
true;
421 return _node_queue_.topPriority() == std::numeric_limits< double >::min();
426 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
427 bool GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::empty(
431 if (!_queues_valid_) {
432 for (
auto& queue_pair: _change_queue_per_node_) {
433 auto& queue = queue_pair.second;
434 while (!queue.empty() && !_isChangeValid_(queue.top())) {
435 _invalidateChange_(queue.top());
438 _queues_valid_ =
true;
441 return _change_queue_per_node_[node].empty();
445 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
446 INLINE
const GraphChange&
447 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
448 GRAPH_CHANGES_GENERATOR >::bestChange() {
449 if (!empty())
return _changes_[_change_queue_per_node_[_node_queue_.top()].top()];
454 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
455 INLINE
const GraphChange&
456 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::bestChange(
458 if (!empty(node))
return _changes_[_change_queue_per_node_[node].top()];
463 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
464 INLINE
double GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
465 GRAPH_CHANGES_GENERATOR >::bestScore() {
466 if (!empty())
return _change_queue_per_node_[_node_queue_.top()].topPriority();
471 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
473 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::bestScore(
475 if (!empty(node))
return _change_queue_per_node_[node].topPriority();
480 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
481 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
482 _illegal2LegalChanges_(Set< std::size_t >& changes_to_recompute) {
483 for (
auto iter = _illegal_changes_.beginSafe(); iter != _illegal_changes_.endSafe(); ++iter) {
484 if (_isChangeValid_(*iter)) {
485 const GraphChange& change = _changes_[*iter];
486 if (change.type() == GraphChangeType::ARC_REVERSAL) {
487 _change_queue_per_node_[change.node1()].insert(*iter,
488 std::numeric_limits< double >::min());
490 _change_queue_per_node_[change.node2()].insert(*iter,
491 std::numeric_limits< double >::min());
493 changes_to_recompute.insert(*iter);
494 _illegal_changes_.erase(iter);
500 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
501 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
502 _findLegalChangesNeedingUpdate_(Set< std::size_t >& changes_to_recompute,
503 const NodeId target_node) {
504 const HashTable< std::size_t, Size >& changes
505 = _change_queue_per_node_[target_node].allValues();
506 for (
auto iter = changes.cbeginSafe(); iter != changes.cendSafe(); ++iter) {
507 if (!changes_to_recompute.exists(iter.key())) {
508 if (_isChangeValid_(iter.key())) {
509 changes_to_recompute.insert(iter.key());
511 _invalidateChange_(iter.key());
518 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
519 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
520 _updateScores_(
const Set< std::size_t >& changes_to_recompute) {
521 Set< NodeId > modified_nodes(changes_to_recompute.size());
523 for (
const auto change_index: changes_to_recompute) {
524 const GraphChange& change = _changes_[change_index];
526 switch (change.type()) {
527 case GraphChangeType::ARC_ADDITION : {
529 auto& parents = _parents_[change.node2()];
530 parents.push_back(change.node1());
532 = _score_->score(change.node2(), parents) - _node_current_scores_[change.node2()];
536 _change_scores_[change_index].second = delta;
539 _change_queue_per_node_[change.node2()].setPriority(change_index, delta);
541 modified_nodes.insert(change.node2());
544 case GraphChangeType::ARC_DELETION : {
546 auto& parents = _parents_[change.node2()];
547 for (
auto& par: parents) {
548 if (par == change.node1()) {
549 par = *(parents.rbegin());
555 = _score_->score(change.node2(), parents) - _node_current_scores_[change.node2()];
556 parents.push_back(change.node1());
559 _change_scores_[change_index].second = delta;
562 _change_queue_per_node_[change.node2()].setPriority(change_index, delta);
564 modified_nodes.insert(change.node2());
567 case GraphChangeType::ARC_REVERSAL : {
569 auto& parents2 = _parents_[change.node2()];
570 for (
auto& par: parents2) {
571 if (par == change.node1()) {
572 par = *(parents2.rbegin());
579 = _score_->score(change.node2(), parents2) - _node_current_scores_[change.node2()];
580 parents2.push_back(change.node1());
583 auto& parents1 = _parents_[change.node1()];
584 parents1.push_back(change.node2());
586 = _score_->score(change.node1(), parents1) - _node_current_scores_[change.node1()];
590 _change_scores_[change_index].first = delta1;
591 _change_scores_[change_index].second = delta2;
594 const double delta = delta1 + delta2;
595 _change_queue_per_node_[change.node1()].setPriority(change_index, delta);
596 _change_queue_per_node_[change.node2()].setPriority(change_index, delta);
599 modified_nodes.insert(change.node1());
600 modified_nodes.insert(change.node2());
605 "Method _updateScores_ of GraphChangesSelector4DiGraph "
606 <<
"does not handle yet graph change of type " << change.type());
612 for (
const auto node: modified_nodes) {
613 _node_queue_.setPriority(node,
614 _change_queue_per_node_[node].empty()
615 ? std::numeric_limits< double >::min()
616 : _change_queue_per_node_[node].topPriority());
621 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
622 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
623 GRAPH_CHANGES_GENERATOR >::_getNewChanges_() {
625 for (
const auto& change: *_changes_generator_) {
627 if (!_changes_.exists(change)) {
631 _illegal_changes_.insert(_changes_.size());
633 _change_scores_.push_back(
634 std::pair< double, double >(std::numeric_limits< double >::min(),
635 std::numeric_limits< double >::min()));
640 _changes_generator_->notifyGetCompleted();
644 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
646 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::applyChange(
647 const GraphChange& change) {
649 const std::size_t change_index = _changes_.pos(change);
652 Set< std::size_t > changes_to_recompute;
653 switch (change.type()) {
654 case GraphChangeType::ARC_ADDITION : {
656 _node_current_scores_[change.node2()] += _change_scores_[change_index].second;
657 _parents_[change.node2()].push_back(change.node1());
660 _constraint_->modifyGraph(
static_cast< const ArcAddition&
>(change));
661 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
663 _changes_generator_->constraint().modifyGraph(
664 static_cast< const ArcAddition&
>(change));
669 _changes_generator_->modifyGraph(
static_cast< const ArcAddition&
>(change));
673 _illegal2LegalChanges_(changes_to_recompute);
674 _invalidateChange_(change_index);
675 _findLegalChangesNeedingUpdate_(changes_to_recompute, change.node2());
676 _updateScores_(changes_to_recompute);
679 case GraphChangeType::ARC_DELETION : {
681 _node_current_scores_[change.node2()] += _change_scores_[change_index].second;
682 auto& parents = _parents_[change.node2()];
683 for (
auto& par: parents) {
684 if (par == change.node1()) {
685 par = *(parents.rbegin());
692 _constraint_->modifyGraph(
static_cast< const ArcDeletion&
>(change));
693 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
695 _changes_generator_->constraint().modifyGraph(
696 static_cast< const ArcDeletion&
>(change));
701 _changes_generator_->modifyGraph(
static_cast< const ArcDeletion&
>(change));
705 _illegal2LegalChanges_(changes_to_recompute);
706 _invalidateChange_(change_index);
707 _findLegalChangesNeedingUpdate_(changes_to_recompute, change.node2());
708 _updateScores_(changes_to_recompute);
711 case GraphChangeType::ARC_REVERSAL : {
713 _node_current_scores_[change.node1()] += _change_scores_[change_index].first;
714 _node_current_scores_[change.node2()] += _change_scores_[change_index].second;
715 _parents_[change.node1()].push_back(change.node2());
716 auto& parents = _parents_[change.node2()];
717 for (
auto& par: parents) {
718 if (par == change.node1()) {
719 par = *(parents.rbegin());
726 _constraint_->modifyGraph(
static_cast< const ArcReversal&
>(change));
727 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
729 _changes_generator_->constraint().modifyGraph(
730 static_cast< const ArcReversal&
>(change));
735 _changes_generator_->modifyGraph(
static_cast< const ArcReversal&
>(change));
739 _illegal2LegalChanges_(changes_to_recompute);
740 _invalidateChange_(change_index);
741 _findLegalChangesNeedingUpdate_(changes_to_recompute, change.node1());
742 _findLegalChangesNeedingUpdate_(changes_to_recompute, change.node2());
743 _updateScores_(changes_to_recompute);
748 "Method applyChange of GraphChangesSelector4DiGraph "
749 <<
"does not handle yet graph change of type " << change.type());
752 _queues_valid_ =
false;
756 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
757 void GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT, GRAPH_CHANGES_GENERATOR >::
758 applyChangeWithoutScoreUpdate(
const GraphChange& change) {
760 const std::size_t change_index = _changes_.pos(change);
763 switch (change.type()) {
764 case GraphChangeType::ARC_ADDITION : {
766 _node_current_scores_[change.node2()] += _change_scores_[change_index].second;
767 _parents_[change.node2()].push_back(change.node1());
770 _constraint_->modifyGraph(
static_cast< const ArcAddition&
>(change));
771 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
773 _changes_generator_->constraint().modifyGraph(
774 static_cast< const ArcAddition&
>(change));
779 _changes_generator_->modifyGraph(
static_cast< const ArcAddition&
>(change));
783 _invalidateChange_(change_index);
787 _queues_to_update_.insert(change.node2());
790 case GraphChangeType::ARC_DELETION : {
792 _node_current_scores_[change.node2()] += _change_scores_[change_index].second;
793 auto& parents = _parents_[change.node2()];
794 for (
auto& par: parents) {
795 if (par == change.node1()) {
796 par = *(parents.rbegin());
803 _constraint_->modifyGraph(
static_cast< const ArcDeletion&
>(change));
804 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
806 _changes_generator_->constraint().modifyGraph(
807 static_cast< const ArcDeletion&
>(change));
812 _changes_generator_->modifyGraph(
static_cast< const ArcDeletion&
>(change));
816 _invalidateChange_(change_index);
820 _queues_to_update_.insert(change.node2());
823 case GraphChangeType::ARC_REVERSAL : {
825 _node_current_scores_[change.node1()] += _change_scores_[change_index].first;
826 _node_current_scores_[change.node2()] += _change_scores_[change_index].second;
827 _parents_[change.node1()].push_back(change.node2());
828 auto& parents = _parents_[change.node2()];
829 for (
auto& par: parents) {
830 if (par == change.node1()) {
831 par = *(parents.rbegin());
838 _constraint_->modifyGraph(
static_cast< const ArcReversal&
>(change));
839 if (
reinterpret_cast< STRUCTURAL_CONSTRAINT*
>(&(_changes_generator_->constraint()))
841 _changes_generator_->constraint().modifyGraph(
842 static_cast< const ArcReversal&
>(change));
847 _changes_generator_->modifyGraph(
static_cast< const ArcReversal&
>(change));
851 _invalidateChange_(change_index);
855 _queues_to_update_.insert(change.node1());
856 _queues_to_update_.insert(change.node2());
861 "Method applyChangeWithoutScoreUpdate of "
862 <<
"GraphChangesSelector4DiGraph "
863 <<
"does not handle yet graph change of type " << change.type());
868 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
870 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
871 GRAPH_CHANGES_GENERATOR >::updateScoresAfterAppliedChanges() {
873 Set< std::size_t > new_legal_changes;
874 for (
auto iter = _illegal_changes_.beginSafe(); iter != _illegal_changes_.endSafe(); ++iter) {
875 if (_isChangeValid_(*iter)) {
876 new_legal_changes.insert(*iter);
877 _illegal_changes_.erase(iter);
882 Set< std::size_t > changes_to_recompute;
883 for (
const auto& node: _queues_to_update_) {
884 _findLegalChangesNeedingUpdate_(changes_to_recompute, node);
886 _queues_to_update_.clear();
889 for (
const auto change_index: new_legal_changes) {
890 const GraphChange& change = _changes_[change_index];
891 if (change.type() == GraphChangeType::ARC_REVERSAL) {
892 _change_queue_per_node_[change.node1()].insert(change_index,
893 std::numeric_limits< double >::min());
895 _change_queue_per_node_[change.node2()].insert(change_index,
896 std::numeric_limits< double >::min());
898 changes_to_recompute.insert(change_index);
902 _updateScores_(changes_to_recompute);
904 _queues_valid_ =
false;
908 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
909 std::vector< std::pair< NodeId, double > >
910 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
911 GRAPH_CHANGES_GENERATOR >::nodesSortedByBestScore()
const {
912 std::vector< std::pair< NodeId, double > > result(_node_queue_.size());
913 for (std::size_t i = std::size_t(0); i < _node_queue_.size(); ++i) {
914 result[i].first = _node_queue_[i];
915 result[i].second = _node_queue_.priorityByPos(i);
918 std::sort(result.begin(),
920 [](
const std::pair< NodeId, double >& a,
921 const std::pair< NodeId, double >& b) ->
bool { return a.second > b.second; });
927 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
928 std::vector< std::pair< NodeId, double > >
929 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
930 GRAPH_CHANGES_GENERATOR >::nodesUnsortedWithScore()
const {
931 std::vector< std::pair< NodeId, double > > result(_node_queue_.size());
932 for (std::size_t i = std::size_t(0); i < _node_queue_.size(); ++i) {
933 result[i].first = _node_queue_[i];
934 result[i].second = _node_queue_.priorityByPos(i);
941 template <
typename STRUCTURAL_CONSTRAINT,
typename GRAPH_CHANGES_GENERATOR >
942 INLINE
typename GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
943 GRAPH_CHANGES_GENERATOR >::GeneratorType&
944 GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
945 GRAPH_CHANGES_GENERATOR >::graphChangeGenerator()
947 return *_changes_generator_;
Exception : the element we looked for cannot be found.
Exception : there is something wrong with an implementation.
GraphChangesSelector4DiGraph(Score &score, STRUCTURAL_CONSTRAINT &constraint, GRAPH_CHANGES_GENERATOR &changes_generator)
default constructor
The base class for all the scores used for learning (BIC, BDeu, etc).
#define GUM_ERROR(type, msg)
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
include the inlined functions if necessary
gum is the global namespace for all aGrUM entities