29 #ifndef DOXYGEN_SHOULD_SKIP_THIS 38 template <
typename STRUCTURAL_CONSTRAINT,
39 typename GRAPH_CHANGES_GENERATOR,
42 INLINE GraphChangesSelector4DiGraph< STRUCTURAL_CONSTRAINT,
43 GRAPH_CHANGES_GENERATOR,
45 GraphChangesSelector4DiGraph(Score< ALLOC >& score,
46 STRUCTURAL_CONSTRAINT& constraint,
47 GRAPH_CHANGES_GENERATOR& changes_generator) :
48 __score(score.clone()),
49 __constraint(&constraint), __changes_generator(&changes_generator) {
55 template <
typename STRUCTURAL_CONSTRAINT,
56 typename GRAPH_CHANGES_GENERATOR,
60 GRAPH_CHANGES_GENERATOR,
64 GRAPH_CHANGES_GENERATOR,
80 template <
typename STRUCTURAL_CONSTRAINT,
81 typename GRAPH_CHANGES_GENERATOR,
85 GRAPH_CHANGES_GENERATOR,
89 GRAPH_CHANGES_GENERATOR,
103 from.__score =
nullptr;
109 template <
typename STRUCTURAL_CONSTRAINT,
110 typename GRAPH_CHANGES_GENERATOR,
111 template <
typename >
115 STRUCTURAL_CONSTRAINT,
116 GRAPH_CHANGES_GENERATOR,
119 ALLOC< Score< ALLOC > > allocator(
__score->getAllocator());
121 allocator.deallocate(
__score, 1);
127 template <
typename STRUCTURAL_CONSTRAINT,
128 typename GRAPH_CHANGES_GENERATOR,
129 template <
typename >
132 GRAPH_CHANGES_GENERATOR,
135 GRAPH_CHANGES_GENERATOR,
138 GRAPH_CHANGES_GENERATOR,
143 ALLOC< Score< ALLOC > > allocator(
__score->getAllocator());
145 allocator.deallocate(
__score, 1);
149 if (from.__score !=
nullptr)
__score = from.__score->clone();
167 template <
typename STRUCTURAL_CONSTRAINT,
168 typename GRAPH_CHANGES_GENERATOR,
169 template <
typename >
172 GRAPH_CHANGES_GENERATOR,
175 GRAPH_CHANGES_GENERATOR,
178 GRAPH_CHANGES_GENERATOR,
182 from.__score =
nullptr;
202 template <
typename STRUCTURAL_CONSTRAINT,
203 typename GRAPH_CHANGES_GENERATOR,
204 template <
typename >
208 GRAPH_CHANGES_GENERATOR,
216 template <
typename STRUCTURAL_CONSTRAINT,
217 typename GRAPH_CHANGES_GENERATOR,
218 template <
typename >
222 GRAPH_CHANGES_GENERATOR,
230 template <
typename STRUCTURAL_CONSTRAINT,
231 typename GRAPH_CHANGES_GENERATOR,
232 template <
typename >
235 GRAPH_CHANGES_GENERATOR,
238 const DatabaseTable< ALLOC >& database =
__score->database();
239 const auto& nodeId2Columns =
__score->nodeId2Columns();
241 if (nodeId2Columns.empty()) {
244 if (!graph.existsNode(i)) { graph.addNodeWithId(i); }
247 for (
auto iter = nodeId2Columns.cbegin(); iter != nodeId2Columns.cend();
249 const NodeId id = iter.first();
250 if (!graph.existsNode(
id)) { graph.addNodeWithId(
id); }
257 if (nodeId2Columns.empty()) {
259 for (
auto node : graph) {
260 if (node >= nb_nodes) { graph.eraseNode(node); }
263 for (
auto node : graph) {
264 if (!nodeId2Columns.existsFirst(node)) { graph.eraseNode(node); }
278 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
289 const std::size_t nb_nodes = graph.size();
291 const std::vector< NodeId, ALLOC< NodeId > > empty_pars;
294 for (
const auto node : graph) {
295 auto& node_parents =
__parents.insert(node, empty_pars).second;
296 const NodeSet& dag_parents = graph.parents(node);
297 if (!dag_parents.empty()) {
298 node_parents.
resize(dag_parents.size());
299 std::size_t j = std::size_t(0);
300 for (
const auto par : dag_parents) {
301 node_parents[j] = par;
311 for (
const auto node : graph) {
321 __changes_generator->notifyGetCompleted();
331 std::pair< double, double >(std::numeric_limits< double >::min(),
332 std::numeric_limits< double >::min()));
336 const PriorityQueue< std::size_t, double, std::greater< double > >
338 for (
const auto node : graph) {
343 for (std::size_t i = std::size_t(0); i <
__changes.size(); ++i) {
347 const GraphChange& change =
__changes[i];
349 switch (change.type()) {
351 auto& parents =
__parents[change.node2()];
352 parents.push_back(change.node1());
353 const double delta =
__score->score(change.node2(), parents)
362 auto& parents =
__parents[change.node2()];
363 for (
auto& par : parents) {
364 if (par == change.node1()) {
365 par = *(parents.rbegin());
370 const double delta =
__score->score(change.node2(), parents)
372 parents.push_back(change.node1());
380 auto& parents2 =
__parents[change.node2()];
381 for (
auto& par : parents2) {
382 if (par == change.node1()) {
383 par = *(parents2.rbegin());
389 const double delta2 =
__score->score(change.node2(), parents2)
391 parents2.push_back(change.node1());
394 auto& parents1 =
__parents[change.node1()];
395 parents1.push_back(change.node2());
396 const double delta1 =
__score->score(change.node1(), parents1)
403 const double delta = delta1 + delta2;
411 "Method setGraph of GraphChangesSelector4DiGraph " 412 <<
"does not handle yet graph change of type " 421 for (
const auto node : graph) {
424 ? std::numeric_limits< double >::min()
433 template <
typename STRUCTURAL_CONSTRAINT,
434 typename GRAPH_CHANGES_GENERATOR,
435 template <
typename >
439 GRAPH_CHANGES_GENERATOR,
442 const GraphChange& change =
__changes[change_index];
445 PriorityQueue< std::size_t, double, std::greater< double > >& queue1 =
447 queue1.erase(change_index);
450 const double new_priority = queue1.empty()
451 ? std::numeric_limits< double >::min()
452 : queue1.topPriority();
457 PriorityQueue< std::size_t, double, std::greater< double > >& queue2 =
459 queue2.erase(change_index);
462 const double new_priority = queue2.empty()
463 ? std::numeric_limits< double >::min()
464 : queue2.topPriority();
473 template <
typename STRUCTURAL_CONSTRAINT,
474 typename GRAPH_CHANGES_GENERATOR,
475 template <
typename >
478 GRAPH_CHANGES_GENERATOR,
484 auto& queue = queue_pair.second;
498 template <
typename STRUCTURAL_CONSTRAINT,
499 typename GRAPH_CHANGES_GENERATOR,
500 template <
typename >
503 GRAPH_CHANGES_GENERATOR,
508 for (
auto& queue_pair : __change_queue_per_node) {
509 auto& queue = queue_pair.second;
517 return __change_queue_per_node[node].empty();
522 template <
typename STRUCTURAL_CONSTRAINT,
523 typename GRAPH_CHANGES_GENERATOR,
524 template <
typename >
526 INLINE
const GraphChange&
528 GRAPH_CHANGES_GENERATOR,
533 GUM_ERROR(NotFound,
"there exists no graph change applicable");
538 template <
typename STRUCTURAL_CONSTRAINT,
539 typename GRAPH_CHANGES_GENERATOR,
540 template <
typename >
542 INLINE
const GraphChange&
544 GRAPH_CHANGES_GENERATOR,
547 return __changes[__change_queue_per_node[node].top()];
549 GUM_ERROR(NotFound,
"there exists no graph change applicable");
554 template <
typename STRUCTURAL_CONSTRAINT,
555 typename GRAPH_CHANGES_GENERATOR,
556 template <
typename >
559 GRAPH_CHANGES_GENERATOR,
564 GUM_ERROR(NotFound,
"there exists no graph change applicable");
569 template <
typename STRUCTURAL_CONSTRAINT,
570 typename GRAPH_CHANGES_GENERATOR,
571 template <
typename >
575 GRAPH_CHANGES_GENERATOR,
578 return __change_queue_per_node[node].topPriority();
580 GUM_ERROR(NotFound,
"there exists no graph change applicable");
585 template <
typename STRUCTURAL_CONSTRAINT,
586 typename GRAPH_CHANGES_GENERATOR,
587 template <
typename >
590 STRUCTURAL_CONSTRAINT,
591 GRAPH_CHANGES_GENERATOR,
597 const GraphChange& change =
__changes[*iter];
599 __change_queue_per_node[change.node1()].insert(
600 *iter, std::numeric_limits< double >::min());
602 __change_queue_per_node[change.node2()].insert(
603 *iter, std::numeric_limits< double >::min());
605 changes_to_recompute.
insert(*iter);
613 template <
typename STRUCTURAL_CONSTRAINT,
614 typename GRAPH_CHANGES_GENERATOR,
615 template <
typename >
618 GRAPH_CHANGES_GENERATOR,
621 const NodeId target_node) {
622 const HashTable< std::size_t, Size >& changes =
623 __change_queue_per_node[target_node].allValues();
624 for (
auto iter = changes.cbeginSafe(); iter != changes.cendSafe(); ++iter) {
625 if (!changes_to_recompute.
exists(iter.key())) {
627 changes_to_recompute.
insert(iter.key());
637 template <
typename STRUCTURAL_CONSTRAINT,
638 typename GRAPH_CHANGES_GENERATOR,
639 template <
typename >
642 STRUCTURAL_CONSTRAINT,
643 GRAPH_CHANGES_GENERATOR,
647 for (
const auto change_index : changes_to_recompute) {
648 const GraphChange& change =
__changes[change_index];
650 switch (change.type()) {
653 auto& parents =
__parents[change.node2()];
654 parents.push_back(change.node1());
655 const double delta =
__score->score(change.node2(), parents)
663 __change_queue_per_node[change.node2()].setPriority(change_index,
666 modified_nodes.insert(change.node2());
671 auto& parents =
__parents[change.node2()];
672 for (
auto& par : parents) {
673 if (par == change.node1()) {
674 par = *(parents.rbegin());
679 const double delta =
__score->score(change.node2(), parents)
681 parents.push_back(change.node1());
687 __change_queue_per_node[change.node2()].setPriority(change_index,
690 modified_nodes.insert(change.node2());
695 auto& parents2 =
__parents[change.node2()];
696 for (
auto& par : parents2) {
697 if (par == change.node1()) {
698 par = *(parents2.rbegin());
704 const double delta2 =
__score->score(change.node2(), parents2)
706 parents2.push_back(change.node1());
709 auto& parents1 =
__parents[change.node1()];
710 parents1.push_back(change.node2());
711 const double delta1 =
__score->score(change.node1(), parents1)
720 const double delta = delta1 + delta2;
721 __change_queue_per_node[change.node1()].setPriority(change_index,
723 __change_queue_per_node[change.node2()].setPriority(change_index,
727 modified_nodes.insert(change.node1());
728 modified_nodes.insert(change.node2());
733 "Method __updateScores of GraphChangesSelector4DiGraph " 734 <<
"does not handle yet graph change of type " 741 for (
const auto node : modified_nodes) {
743 __change_queue_per_node[node].
empty()
744 ? std::numeric_limits< double >::min()
745 : __change_queue_per_node[node].topPriority());
751 template <
typename STRUCTURAL_CONSTRAINT,
752 typename GRAPH_CHANGES_GENERATOR,
753 template <
typename >
756 GRAPH_CHANGES_GENERATOR,
759 for (
const auto& change : *__changes_generator) {
768 std::pair< double, double >(std::numeric_limits< double >::min(),
769 std::numeric_limits< double >::min()));
774 __changes_generator->notifyGetCompleted();
779 template <
typename STRUCTURAL_CONSTRAINT,
780 typename GRAPH_CHANGES_GENERATOR,
781 template <
typename >
784 GRAPH_CHANGES_GENERATOR,
788 const std::size_t change_index =
__changes.pos(change);
792 switch (change.type()) {
797 __parents[change.node2()].push_back(change.node1());
800 __constraint->modifyGraph(static_cast< const ArcAddition& >(change));
801 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
802 &(__changes_generator->constraint()))
804 __changes_generator->constraint().modifyGraph(
805 static_cast< const ArcAddition& >(change));
810 __changes_generator->modifyGraph(
811 static_cast< const ArcAddition& >(change));
825 auto& parents =
__parents[change.node2()];
826 for (
auto& par : parents) {
827 if (par == change.node1()) {
828 par = *(parents.rbegin());
835 __constraint->modifyGraph(static_cast< const ArcDeletion& >(change));
836 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
837 &(__changes_generator->constraint()))
839 __changes_generator->constraint().modifyGraph(
840 static_cast< const ArcDeletion& >(change));
845 __changes_generator->modifyGraph(
846 static_cast< const ArcDeletion& >(change));
862 __parents[change.node1()].push_back(change.node2());
863 auto& parents =
__parents[change.node2()];
864 for (
auto& par : parents) {
865 if (par == change.node1()) {
866 par = *(parents.rbegin());
873 __constraint->modifyGraph(static_cast< const ArcReversal& >(change));
874 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
875 &(__changes_generator->constraint()))
877 __changes_generator->constraint().modifyGraph(
878 static_cast< const ArcReversal& >(change));
883 __changes_generator->modifyGraph(
884 static_cast< const ArcReversal& >(change));
897 "Method applyChange of GraphChangesSelector4DiGraph " 898 <<
"does not handle yet graph change of type " 907 template <
typename STRUCTURAL_CONSTRAINT,
908 typename GRAPH_CHANGES_GENERATOR,
909 template <
typename >
912 STRUCTURAL_CONSTRAINT,
913 GRAPH_CHANGES_GENERATOR,
916 const std::size_t change_index =
__changes.pos(change);
919 switch (change.type()) {
924 __parents[change.node2()].push_back(change.node1());
927 __constraint->modifyGraph(static_cast< const ArcAddition& >(change));
928 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
929 &(__changes_generator->constraint()))
931 __changes_generator->constraint().modifyGraph(
932 static_cast< const ArcAddition& >(change));
937 __changes_generator->modifyGraph(
938 static_cast< const ArcAddition& >(change));
953 auto& parents =
__parents[change.node2()];
954 for (
auto& par : parents) {
955 if (par == change.node1()) {
956 par = *(parents.rbegin());
963 __constraint->modifyGraph(static_cast< const ArcDeletion& >(change));
964 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
965 &(__changes_generator->constraint()))
967 __changes_generator->constraint().modifyGraph(
968 static_cast< const ArcDeletion& >(change));
973 __changes_generator->modifyGraph(
974 static_cast< const ArcDeletion& >(change));
991 __parents[change.node1()].push_back(change.node2());
992 auto& parents =
__parents[change.node2()];
993 for (
auto& par : parents) {
994 if (par == change.node1()) {
995 par = *(parents.rbegin());
1002 __constraint->modifyGraph(static_cast< const ArcReversal& >(change));
1003 if (reinterpret_cast< STRUCTURAL_CONSTRAINT* >(
1004 &(__changes_generator->constraint()))
1006 __changes_generator->constraint().modifyGraph(
1007 static_cast< const ArcReversal& >(change));
1012 __changes_generator->modifyGraph(
1013 static_cast< const ArcReversal& >(change));
1027 "Method applyChangeWithoutScoreUpdate of " 1028 <<
"GraphChangesSelector4DiGraph " 1029 <<
"does not handle yet graph change of type " 1036 template <
typename STRUCTURAL_CONSTRAINT,
1037 typename GRAPH_CHANGES_GENERATOR,
1038 template <
typename >
1041 GRAPH_CHANGES_GENERATOR,
1049 new_legal_changes.
insert(*iter);
1059 __queues_to_update.clear();
1062 for (
const auto change_index : new_legal_changes) {
1063 const GraphChange& change =
__changes[change_index];
1065 __change_queue_per_node[change.node1()].insert(
1066 change_index, std::numeric_limits< double >::min());
1068 __change_queue_per_node[change.node2()].insert(
1069 change_index, std::numeric_limits< double >::min());
1071 changes_to_recompute.
insert(change_index);
1082 template <
typename STRUCTURAL_CONSTRAINT,
1083 typename GRAPH_CHANGES_GENERATOR,
1084 template <
typename >
1086 std::vector< std::pair< NodeId, double > >
1088 GRAPH_CHANGES_GENERATOR,
1096 std::sort(result.begin(),
1098 [](
const std::pair< NodeId, double >& a,
1099 const std::pair< NodeId, double >& b) ->
bool {
1100 return a.second > b.second;
1108 template <
typename STRUCTURAL_CONSTRAINT,
1109 typename GRAPH_CHANGES_GENERATOR,
1110 template <
typename >
1112 std::vector< std::pair< NodeId, double > >
1114 GRAPH_CHANGES_GENERATOR,
1127 template <
typename STRUCTURAL_CONSTRAINT,
1128 typename GRAPH_CHANGES_GENERATOR,
1129 template <
typename >
1132 GRAPH_CHANGES_GENERATOR,
1135 GRAPH_CHANGES_GENERATOR,
NodeProperty< double > __node_current_scores
the current score of each node
bool empty()
indicates whether the selector still contains graph changes
GeneratorType & graphChangeGenerator() const noexcept
returns the generator used by the selector
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
void __updateScores(const Set< std::size_t > &changes_to_recompute)
perform the necessary updates of the scores
STRUCTURAL_CONSTRAINT * __constraint
the set of constraints used to determine valid changes
const GraphChange & bestChange()
returns the best graph change to examine
const Val & top() const
returns the element at the top of the priority queue
void applyChange(const GraphChange &change)
indicate to the selector that a change has been applied
Set< std::size_t > __illegal_changes
the set of changes known to be currently illegal (due to the constraints)
void erase(const Key &k)
Erases an element from the set.
Score< ALLOC > * __score
the scoring function
~GraphChangesSelector4DiGraph()
destructor
const Priority & priorityByPos(Size index) const
Returns the priority of the value passed in argument.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
PriorityQueue< NodeId, double, std::greater< double > > __node_queue
a global priority queue indicating for each node its best score
std::vector< std::pair< double, double > > __change_scores
the scores for the head and tail of all the changes
const iterator_safe & endSafe() const noexcept
The usual safe end iterator to parse the set.
void setPriority(const Val &elt, const Priority &new_priority)
Modifies the priority of each instance of a given element.
void applyChangeWithoutScoreUpdate(const GraphChange &change)
indicate to the selector that one of serveral changes has been applied
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
bool __isChangeValid(const std::size_t index) const
indicates whether a given change is valid or not
void resize(Size new_capacity)
Changes the size of the underlying hash table containing the set.
NodeProperty< std::vector< NodeId, ALLOC< NodeId > > > __parents
the set of parents of each node (speeds-up score computations)
Size insert(const Val &val, const Priority &priority)
Inserts a new (a copy) element in the priority queue.
Set< NodeId > __queues_to_update
the set of queues to update when applying several changes
double bestScore()
return the score of the best graph change
bool __queues_valid
indicates whether we need to recompute whether the queue is empty or not
GraphChangesSelector4DiGraph(Score< ALLOC > &score, STRUCTURAL_CONSTRAINT &constraint, GRAPH_CHANGES_GENERATOR &changes_generator)
default constructor
void updateScoresAfterAppliedChanges()
recompute all the scores after the application of several changes
std::vector< std::pair< NodeId, double > > nodesUnsortedWithScore() const
returns the set of queues top priorities
iterator_safe beginSafe() const
The usual safe begin iterator to parse the set.
Sequence< GraphChange > __changes
a sequence containing all the possible changes
std::vector< std::pair< NodeId, double > > nodesSortedByBestScore() const
returns the set of queues sorted by decreasing top priority
void clear()
Removes all the elements from the queue.
void __invalidateChange(const std::size_t change_index)
put a change into the illegal set
void __findLegalChangesNeedingUpdate(Set< std::size_t > &changes_to_recompute, const NodeId target_node)
finds the changes that are affected by a given node modification
void __illegal2LegalChanges(Set< std::size_t > &changes_to_recompute)
remove the now legal changes from the illegal set
void setGraph(DiGraph &graph)
sets the graph from which scores are computed
GRAPH_CHANGES_GENERATOR GeneratorType
the type of the generator
void clear()
Removes all the elements, if any, from the set.
GRAPH_CHANGES_GENERATOR * __changes_generator
the generator that returns the set of possible changes
void __getNewChanges()
get from the graph change generator a new set of changes
Size size() const noexcept
Returns the number of elements in the set.
bool isChangeValid(const GraphChange &change) const
indicates whether a given change is valid or not
const Priority & topPriority() const
Returns the priority of the top element.
Size NodeId
Type for node ids.
void insert(const Key &k)
Inserts a new element into the set.
NodeProperty< PriorityQueue< std::size_t, double, std::greater< double > > > __change_queue_per_node
for each node, a priority queue sorting GraphChanges by decreasing score
Size size() const noexcept
Returns the number of elements in the priority queue.
#define GUM_ERROR(type, msg)