aGrUM  0.16.0
mixedGraph.cpp
Go to the documentation of this file.
1 
30 
31 #ifdef GUM_NO_INLINE
33 #endif // GUM_NOINLINE
34 
35 namespace gum {
36 
38  bool nodes_resize_policy,
39  Size arcs_size,
40  bool arcs_resize_policy,
41  Size edges_size,
42  bool edges_resize_policy) :
43  // Note that we need to initialize the NodeGraphPart by ourselves
44  // because
45  // it is a virtual inherited class (see C++ FAQ Lite #25.12 for details)
46  NodeGraphPart(nodes_size, nodes_resize_policy),
47  UndiGraph(edges_size, edges_resize_policy),
48  DiGraph(arcs_size, arcs_resize_policy) {
49  // for debugging purposes
50  GUM_CONSTRUCTOR(MixedGraph);
51  }
52 
54  NodeGraphPart(g), UndiGraph(g), DiGraph(g) {
55  // for debugging purposes
56  GUM_CONS_CPY(MixedGraph);
57  }
58 
60  // for debugging purposes
61  GUM_DESTRUCTOR(MixedGraph);
62  }
63 
64  const std::string MixedGraph::toString() const {
65  std::string s = NodeGraphPart::toString();
66  s += " , ";
68  s += " , ";
70  return s;
71  }
72 
73  const std::vector< NodeId >
74  MixedGraph::mixedOrientedPath(const NodeId n1, const NodeId n2) const {
75  // not recursive version => use a FIFO for simulating the recursion
76  List< NodeId > nodeFIFO;
77  nodeFIFO.pushBack(n2);
78 
79  // mark[node] = successor if visited, else mark[node] does not exist
81  mark.insert(n2, n2);
82 
83  NodeId current;
84 
85  while (!nodeFIFO.empty()) {
86  current = nodeFIFO.front();
87  nodeFIFO.popFront();
88 
89  // check the neighbours
90  for (const auto new_one : neighbours(current)) {
91  if (mark.exists(new_one)) // if the node has already been visited
92  continue; // do not check it again
93 
94  mark.insert(new_one, current);
95 
96  if (new_one == n1) {
97  std::vector< NodeId > v;
98 
99  for (current = n1; current != n2; current = mark[current])
100  v.push_back(current);
101 
102  v.push_back(n2);
103 
104  return v;
105  }
106 
107  nodeFIFO.pushBack(new_one);
108  }
109 
110  // check the parents
111  for (const auto new_one : parents(current)) {
112  if (mark.exists(new_one)) // if this node is already marked, do not
113  continue; // check it again
114 
115  mark.insert(new_one, current);
116 
117  if (new_one == n1) {
118  std::vector< NodeId > v;
119 
120  for (current = n1; current != n2; current = mark[current])
121  v.push_back(current);
122 
123  v.push_back(n2);
124 
125  return v;
126  }
127 
128  nodeFIFO.pushBack(new_one);
129  }
130  }
131 
132  GUM_ERROR(NotFound, "no path found");
133  }
134 
135  const std::vector< NodeId >
136  MixedGraph::mixedUnorientedPath(const NodeId n1, const NodeId n2) const {
137  // not recursive version => use a FIFO for simulating the recursion
138  List< NodeId > nodeFIFO;
139  nodeFIFO.pushBack(n2);
140 
141  // mark[node] = successor if visited, else mark[node] does not exist
143  mark.insert(n2, n2);
144 
145  NodeId current;
146 
147  while (!nodeFIFO.empty()) {
148  current = nodeFIFO.front();
149  nodeFIFO.popFront();
150 
151  // check the neighbours
152  for (const auto new_one : neighbours(current)) {
153  if (mark.exists(new_one)) // if the node has already been visited
154  continue; // do not check it again
155 
156  mark.insert(new_one, current);
157 
158  if (new_one == n1) {
159  std::vector< NodeId > v;
160 
161  for (current = n1; current != n2; current = mark[current])
162  v.push_back(current);
163 
164  v.push_back(n2);
165 
166  return v;
167  }
168 
169  nodeFIFO.pushBack(new_one);
170  }
171 
172  // check the parents
173  for (const auto new_one : parents(current)) {
174  if (mark.exists(new_one)) // the node has already been visited
175  continue;
176 
177  mark.insert(new_one, current);
178 
179  if (new_one == n1) {
180  std::vector< NodeId > v;
181 
182  for (current = n1; current != n2; current = mark[current])
183  v.push_back(current);
184 
185  v.push_back(n2);
186 
187  return v;
188  }
189 
190  nodeFIFO.pushBack(new_one);
191  }
192 
193  // check the children
194  for (const auto new_one : children(current)) {
195  if (mark.exists(new_one)) // the node has already been visited
196  continue;
197 
198  mark.insert(new_one, current);
199 
200  if (new_one == n1) {
201  std::vector< NodeId > v;
202 
203  for (current = n1; current != n2; current = mark[current])
204  v.push_back(current);
205 
206  v.push_back(n2);
207  return v;
208  }
209 
210  nodeFIFO.pushBack(new_one);
211  }
212  }
213 
214  GUM_ERROR(NotFound, "no path found");
215  }
216 
217  const std::string MixedGraph::toDot() const {
218  std::stringstream output;
219  std::stringstream nodeStream;
220  std::stringstream edgeStream;
221  List< NodeId > treatedNodes;
222  output << "digraph \""
223  << "no_name\" {" << std::endl;
224  nodeStream << "node [shape = ellipse];" << std::endl;
225  std::string tab = " ";
226 
227  for (const auto node : nodes()) {
228  nodeStream << tab << node << ";";
229 
230  for (const auto nei : neighbours(node))
231  if (!treatedNodes.exists(nei))
232  edgeStream << tab << node << " -> " << nei << " [dir=none];"
233  << std::endl;
234 
235  for (const auto chi : children(node))
236  edgeStream << tab << node << " -> " << chi << ";" << std::endl;
237 
238  treatedNodes.insert(node);
239  }
240 
241  output << nodeStream.str() << std::endl
242  << edgeStream.str() << std::endl
243  << "}" << std::endl;
244 
245  return output.str();
246  }
247 
249  std::ostream& operator<<(std::ostream& stream, const MixedGraph& g) {
250  stream << g.toString();
251  return stream;
252  }
253 
254 } /* namespace gum */
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
Definition: list_tpl.h:1970
const std::vector< NodeId > mixedUnorientedPath(const NodeId node1, const NodeId node2) const
returns a mixed/directed path from node1 to node2 in the arc/edge set
Definition: mixedGraph.cpp:136
const std::string toString() const
to friendly display the content of the ArcGraphPart
virtual const std::string toString() const
to friendly display the content of the MixedGraph
Definition: mixedGraph.cpp:64
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Generic doubly linked lists.
Definition: list.h:372
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
void popFront()
Removes the first element of a List, if any.
Definition: list_tpl.h:1964
The class for generic Hash Tables.
Definition: hashTable.h:679
const NodeSet & neighbours(const NodeId id) const
returns the set of edges adjacent to a given node
virtual const std::string toDot() const
to friendly display mixed graph in DOT format
Definition: mixedGraph.cpp:217
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map&#39;s DAG in output using the Graphviz-dot format.
Definition: BayesNet_tpl.h:605
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
Definition: list_tpl.h:1592
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
Base class for all oriented graphs.
Definition: diGraph.h:111
std::string toString() const
a function to display the set of nodes
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Class for node sets in graph.
bool exists(const Val &val) const
Checks whether there exists a given element in the list.
Definition: list_tpl.h:1857
MixedGraph(Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=true, Size arcs_size=HashTableConst::default_size, bool arcs_resize_policy=true, Size edges_size=HashTableConst::default_size, bool edges_resize_policy=true)
default constructor
Definition: mixedGraph.cpp:37
const std::string toString() const
to friendly display the content of the EdgeGraphPart
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
Definition: list_tpl.h:1619
Val & front() const
Returns a reference to first element of a list, if any.
Definition: list_tpl.h:1831
const NodeSet & children(const NodeId id) const
returns the set of nodes with arc outgoing from a given node
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Base class for undirected graphs.
Definition: undiGraph.h:109
const std::vector< NodeId > mixedOrientedPath(const NodeId node1, const NodeId node2) const
returns a mixed edge/directed arc path from node1 to node2 in the arc/edge set
Definition: mixedGraph.cpp:74
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
virtual ~MixedGraph()
destructor
Definition: mixedGraph.cpp:59
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
Base class for mixed graphs.
Definition: mixedGraph.h:127