aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
undiGraph.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief Base classes for undirected graphs
24  *
25  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
26  */
27 #ifndef GUM_UNDIGRAPH_H
28 #define GUM_UNDIGRAPH_H
29 
30 #include <iostream>
31 #include <utility>
32 
33 #include <agrum/agrum.h>
34 
35 #include <agrum/tools/graphs/parts/edgeGraphPart.h>
36 #include <agrum/tools/graphs/parts/nodeGraphPart.h>
37 
38 namespace gum {
39 
40  /* ===========================================================================
41  */
42  /* === BASE CLASS FOR MANIPULATING ALL UNDIRECTED GRAPHS ===
43  */
44  /* ===========================================================================
45  */
46  /** @class UndiGraph
47  * @brief Base class for undirected graphs
48  *
49  * \ingroup graph_group
50  *
51  *
52  * This is the base class for graphs containing undirected edges
53  * (so-called edges).
54  *
55  * @par Usage example:
56  * @code
57  * // creating empty graphs
58  * UndiGraph g1,g2;
59  *
60  * // adding nodes and edges to g1
61  * NodeId i1=g1.addNode();
62  * NodeId i2=g1.addNode();
63  * NodeId i3=g1.addNode();
64  * g1.addEdge( i1,i2 );
65  * g1.addEdge( i1,i3 );
66  * g1.addEdge( i2,i3 );
67  *
68  * //throw an InvalidNode
69  * // g1.addEdge( i1+i2+i3,i1 );
70  *
71  * // copying graphs
72  * UndiGraph g3 = g1;
73  * g2 = g1;
74  * UndiGraph g4=g1;
75  *
76  * // check if a graph has no node
77  * if ( g1.empty() ) cerr << "graph g1 is empty" << endl;
78  *
79  * // remove all the nodes (as well as their adjacent edges)
80  * g1.clear();
81  *
82  * // remove some edge
83  * g4.eraseEdge( Edge ( i1,i3 ) );
84  *
85  * // remove node
86  * g2.eraseNode( i2 );
87  *
88  * // parse a graph
89  * for ( const auto node : g3.nodes() )
90  * cerr << node << endl;
91  *
92  * for ( const auto& edge : g3.edges())
93  * cerr << edge << endl;
94  *
95  * const EdgeSet& a=g3.neighbours( 3 );
96  * for ( const auto& edge : a)
97  * cerr << " - "<<edge;
98  *
99  * cerr<<endl;
100  *
101  * // remove all the edges that are adjacent to a given node
102  * g3.eraseNeighbours( 2 );
103  * @endcode
104  */
105  /* ===========================================================================
106  */
107 
108  class UndiGraph: public virtual NodeGraphPart, public EdgeGraphPart {
109  public:
110  // ############################################################################
111  /// @name Constructors / Destructors
112  // ############################################################################
113  /// @{
114 
115  /// default constructor
116  /** @param nodes_size the size of the hash table used to store all the nodes
117  * @param nodes_resize_policy the resizing policy of this hash table
118  * @param edges_size the size of the hash table used to store all the edges
119  * @param edges_resize_policy the resizing policy of this hash table */
120  explicit UndiGraph(Size nodes_size = HashTableConst::default_size,
121  bool nodes_resize_policy = true,
122  Size edges_size = HashTableConst::default_size,
123  bool edges_resize_policy = true);
124 
125  /// copy constructor
126  /** @param g the UndiGraph to copy */
127  UndiGraph(const UndiGraph& g);
128 
129  /// destructor
130  virtual ~UndiGraph();
131 
132  /// @}
133 
134  // ############################################################################
135  /// @name Operators
136  // ############################################################################
137  /// @{
138 
139  /// copy operator
140  /** @param g the DiGraph to copy */
141  UndiGraph& operator=(const UndiGraph& g);
142 
143  /// tests whether two UndiGraphs are identical (same nodes, same edges)
144  /** @param g the UndiGraph with which "this" is compared */
145  // not virtual : it is a feature !!! :)
146  bool operator==(const UndiGraph& g) const;
147 
148  /// tests whether two UndiGraphs are different
149  /** @param g the UndiGraph with which "this" is compared */
150  // not virtual : it is a feature !!! :)
151  bool operator!=(const UndiGraph& g) const;
152 
153  /// @}
154 
155  // ############################################################################
156  /// @name Accessors/Modifiers
157  // ############################################################################
158  /// @{
159 
160  /// insert a new edge into the undirected graph
161  /** The order in which the extremal nodes are specified is not important.
162  * @param first the id of one extremal node of the new inserted edge
163  * @param second the id of the other extremal node of the new inserted edge
164  * @warning if the edge already exists, nothing is done. In particular, no
165  * exception is raised.
166  * @throw InvalidNode if first and/or second do not belong to the
167  * graph nodes */
168  void addEdge(NodeId first, NodeId second) override;
169 
170  /// remove a node and its adjacent edges from the graph
171  /** @param id the id of the node to be removed
172  * @warning if the node does not exist, nothing is done. In particular, no
173  * exception is raised.*/
174  void eraseNode(NodeId id) override;
175 
176  /// removes all the nodes and edges from the graph
177  void clear() override;
178 
179  /// to friendly display the content of the graph
180  std::string toString() const override;
181 
182  /// to friendly display graph in DOT format
183  virtual std::string toDot() const;
184 
185  /// checks whether the graph contains cycles
186  bool hasUndirectedCycle() const;
187 
188  /// returns the partial graph formed by the nodes given in parameter
189  virtual UndiGraph partialUndiGraph(NodeSet nodes);
190 
191  /// returns a property {node:id of connected component}
192  NodeProperty< NodeId > nodes2ConnectedComponent() const;
193 
194  /// @}
195  };
196 
197  /// for friendly displaying the content of undirected graphs
198  std::ostream& operator<<(std::ostream&, const UndiGraph&);
199 
200 } /* namespace gum */
201 
202 #ifndef GUM_NO_INLINE
203 # include <agrum/tools/graphs/undiGraph_inl.h>
204 #endif // GUM_NOINLINE
205 
206 #endif /* GUM_UNDIGRAPH_H */