aGrUM  0.14.2
graphChangesGeneratorOnSubDiGraph_tpl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}@lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it wil be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 
28 namespace gum {
29 
30  namespace learning {
31 
33  template < typename STRUCT_CONSTRAINT >
35  GraphChangesGeneratorOnSubDiGraph(STRUCT_CONSTRAINT& constraint) :
36  _constraint(&constraint) {
37  GUM_CONSTRUCTOR(GraphChangesGeneratorOnSubDiGraph);
38  }
39 
41  template < typename STRUCT_CONSTRAINT >
50  }
51 
53  template < typename STRUCT_CONSTRAINT >
58  _target_nodes(std::move(from._target_nodes)),
59  _tail_nodes(std::move(from._tail_nodes)),
60  _legal_changes(std::move(from._legal_changes)),
63  }
64 
66  template < typename STRUCT_CONSTRAINT >
68  STRUCT_CONSTRAINT >::~GraphChangesGeneratorOnSubDiGraph() {
69  GUM_DESTRUCTOR(GraphChangesGeneratorOnSubDiGraph);
70  }
71 
73  template < typename STRUCT_CONSTRAINT >
74  GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT >&
76  const GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT >& from) {
77  if (this != &from) {
78  _constraint = from._constraint;
79  _target_nodes = from._target_nodes;
80  _tail_nodes = from._tail_nodes;
81  _legal_changes = from._legal_changes;
82  __max_threads_number = from.__max_threads_number;
83  }
84  return *this;
85  }
86 
88  template < typename STRUCT_CONSTRAINT >
89  GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT >&
91  GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT >&& from) {
92  if (this != &from) {
93  _constraint = std::move(from._constraint);
94  _target_nodes = std::move(from._target_nodes);
95  _tail_nodes = std::move(from._tail_nodes);
96  _legal_changes = std::move(from._legal_changes);
97  __max_threads_number = from.__max_threads_number;
98  }
99  return *this;
100  }
101 
103  template < typename STRUCT_CONSTRAINT >
105  _legal_changes.clear();
106 
107  // for all the pairs of nodes, consider adding, reverse and removing arcs
108  std::vector< Set< GraphChange > > legal_changes;
109 # pragma omp parallel num_threads(__max_threads_number)
110  {
111  int num_threads = getNumberOfRunningThreads();
112 
113 # pragma omp single
114  {
115  // resize the change vectors so that each thread can write to its
116  // own vector
117  legal_changes.resize(num_threads);
118  }
119 
120  const Size this_thread = getThreadNumber();
121 
122  Idx i = 0;
123  for (const auto node1 : _tail_nodes) {
124  if (i == this_thread) {
125  for (const auto node2 : _target_nodes) {
126  if (node1 != node2) {
127  // try arc additions
128  ArcAddition arc_add(node1, node2);
129  if (!_constraint->isAlwaysInvalid(arc_add)) {
130  legal_changes[this_thread].insert(std::move(arc_add));
131  }
132 
133  // try arc deletion
134  ArcDeletion arc_del(node1, node2);
135  if (!_constraint->isAlwaysInvalid(arc_del)) {
136  legal_changes[this_thread].insert(std::move(arc_del));
137  }
138 
139  // try arc reversal
140  ArcReversal arc_rev(node1, node2);
141  if (!_constraint->isAlwaysInvalid(arc_rev)) {
142  legal_changes[this_thread].insert(std::move(arc_rev));
143  }
144  }
145  }
146  }
147  ++i;
148  i %= num_threads;
149  }
150  }
151 
152  // now store the changes into the protected vectors of the
153  // GraphChangesGeneratorOnSubDiGraph
154  for (const auto& changes : legal_changes) {
155  for (const auto& change : changes) {
156  _legal_changes.insert(std::move(change));
157  }
158  }
159  }
160 
162  template < typename STRUCT_CONSTRAINT >
164  const DiGraph& graph) {
165  // generate the set of all changes
166  _createChanges();
167  }
168 
170  template < typename STRUCT_CONSTRAINT >
172  const NodeSet& nodes) {
173  _target_nodes = nodes;
174  }
175 
177  template < typename STRUCT_CONSTRAINT >
179  NodeId node) {
180  _target_nodes.insert(node);
181  }
182 
184  template < typename STRUCT_CONSTRAINT >
185  INLINE void
187  NodeId node) {
188  _target_nodes.erase(node);
189  }
190 
192  template < typename STRUCT_CONSTRAINT >
194  const NodeSet& nodes) {
195  _tail_nodes = nodes;
196  }
197 
199  template < typename STRUCT_CONSTRAINT >
201  Size nb_nodes) {
202  _tail_nodes.clear();
203  for (Idx i = 0; i < nb_nodes; ++i) {
204  _tail_nodes.insert(i);
205  }
206  }
207 
209  template < typename STRUCT_CONSTRAINT >
211  NodeId node) {
212  _tail_nodes = node;
213  }
214 
216  template < typename STRUCT_CONSTRAINT >
218  NodeId node) {
219  _tail_nodes.erase(node);
220  }
221 
223  template < typename STRUCT_CONSTRAINT >
225  STRUCT_CONSTRAINT >::clearChanges() noexcept {
226  _legal_changes.clear();
227  }
228 
230  template < typename STRUCT_CONSTRAINT >
231  INLINE
234  return _legal_changes.cbegin();
235  }
236 
238  template < typename STRUCT_CONSTRAINT >
239  INLINE const typename GraphChangesGeneratorOnSubDiGraph<
240  STRUCT_CONSTRAINT >::iterator&
242  return _legal_changes.cend();
243  }
244 
246  template < typename STRUCT_CONSTRAINT >
247  INLINE void
249  const ArcAddition& change) {}
250 
252  template < typename STRUCT_CONSTRAINT >
253  INLINE void
255  const ArcDeletion& change) {}
256 
258  template < typename STRUCT_CONSTRAINT >
259  INLINE void
261  const ArcReversal& change) {}
262 
264  template < typename STRUCT_CONSTRAINT >
265  INLINE void
267  const GraphChange& change) {}
268 
270  template < typename STRUCT_CONSTRAINT >
272  STRUCT_CONSTRAINT >::notifyGetCompleted() {
273  if (_legal_changes.size()) _legal_changes.clear();
274  }
275 
277  template < typename STRUCT_CONSTRAINT >
278  INLINE void
280  Size nb) noexcept {
281 # if defined(_OPENMP) && !defined(GUM_DEBUG_MODE)
282  if (nb == 0) nb = getMaxNumberOfThreads();
284 # else
286 # endif /* _OPENMP && GUM_DEBUG_MODE */
287  }
288 
290  template < typename STRUCT_CONSTRAINT >
291  INLINE STRUCT_CONSTRAINT&
293  noexcept {
294  return *_constraint;
295  }
296 
297  } /* namespace learning */
298 
299 } /* namespace gum */
300 
301 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT > & operator=(const GraphChangesGeneratorOnSubDiGraph< STRUCT_CONSTRAINT > &from)
copy operator
NodeSet _tail_nodes
the tail nodes (other extremities than the targets)
STRUCT_CONSTRAINT & constraint() const noexcept
returns the constraint that is used by the generator
unsigned int getNumberOfRunningThreads()
Get the current number of running threads.
unsigned int getThreadNumber()
Get the calling thread id.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
Set< GraphChange > _legal_changes
the current set of operators
void eraseTarget(NodeId node)
removes a target
GraphChangesGeneratorOnSubDiGraph(STRUCT_CONSTRAINT &constraint)
default constructor
void eraseTail(NodeId node)
removes a tail node
STL namespace.
unsigned int getMaxNumberOfThreads()
Returns the maximum number of threads at any time.
const iterator & end() const
returns an (unsafe) iterator on the end of the list of operators
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
void setTails(const NodeSet &nodes)
assign a set of "tail" nodes
void modifyGraph(const ArcAddition &change)
notify the operator set of a change applied to the graph
void clearChanges() noexcept
empty the set of possible change operators that can be applied
Size __max_threads_number
the max number of threads authorized
void setGraph(const DiGraph &graph)
sets a new graph from which the operator will compute possible changes
void _createChanges()
create the set of legal and illegal changes from a given graph
iterator begin() const
returns an (unsafe) iterator on the beginning of the list of operators
STRUCT_CONSTRAINT * _constraint
a reference on the structural constraint used to restrict the changes
void setMaxNbThreads(Size nb) noexcept
sets the maximum number of threads used to compute the set of changes
void setTargets(const NodeSet &nodes)
assign a set of target nodes
void addTarget(NodeId node)
adds a new target node
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
void addTail(NodeId node)
adds a new "tail" node
Size NodeId
Type for node ids.
Definition: graphElements.h:97
typename Set< GraphChange >::const_iterator iterator
the iterator for parsing the list of possible graph change operators
void notifyGetCompleted()
notifies the generator that we have parsed all its legal changes