Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
graph_paths.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_ADTS_GRAPH_PATHS_H
7#define ELEMENTA_ADTS_GRAPH_PATHS_H
8
9#include <type_traits>
10#include <vector>
11#include <functional>
13
14
15namespace elementa
16{
17
18namespace adts
19{
20
21namespace graphs
22{
23
44/* ***************************************************************************
45
46 Enum type: GPathKind
47 Template type: GPathKindType
48 Constepxr: kOtherGPathKind
49 Template type: GPathElement
50 Template class: GPath
51
52*******************************************************************************/
53
56 kVertexPath,
57 kEdgePath
58 );
59
61template <GPathKind KIND>
62struct GPathKindType {};
63
65constexpr GPathKind kOtherGPathKind(GPathKind kid)
66{ return(kid == GPathKind::kVertexPath ? GPathKind::kEdgePath :
67 GPathKind::kVertexPath); }
68
70template <class Vertex, class Edge, GPathKind KIND>
71using GPathElement = typename std::conditional<
72 KIND == GPathKind::kVertexPath,
74 typename Graph<Vertex,Edge>::eiterator >::type;
75
77template <class Vertex, class Edge, GPathKind KIND>
78class GPath: public std::vector< GPathElement<Vertex,Edge,KIND> >
79{
80 public:
81
86 static const GPathKind kKind = KIND;
87
90
92 using BasePath = std::vector<VectorElem>;
93
96
98 using Collection = std::vector<GPath>;
99
107 using BasePath::BasePath;
108
116
124 GPath< Vertex,Edge,kOtherGPathKind(KIND) > other(
125 const BaseGraph & g,
126 const typename BaseGraph::EPred & epred = BaseGraph::trivial_epred)const
127 { return(other_hidden(g,epred,GPathKindType<KIND>{})); }
128
130
133 std::string to_string(const BaseGraph & g,
134 const std::function<std::string(const Vertex & vd)> &
135 vtostr = [](const Vertex & vd)->std::string
136 { return(std::to_string(vd)); },
137 const std::function<std::string(const Edge & ed)> &
138 etostr = [](const Edge & ed)->std::string
139 { return(std::to_string(ed)); }) const
140 { return(to_string_hidden(g,vtostr,etostr,GPathKindType<KIND>{})); }
141
144 private:
145
147
149 GPath<Vertex,Edge,kOtherGPathKind(KIND)> other_hidden(
150 const BaseGraph & g,
151 const typename BaseGraph::EPred & p,
152 GPathKindType<GPathKind::kVertexPath>) const;
153
155
157 GPath<Vertex,Edge,kOtherGPathKind(KIND)> other_hidden(
158 const BaseGraph & g,
159 const typename BaseGraph::EPred & p,
160 GPathKindType<GPathKind::kEdgePath>) const;
161
162 std::string to_string_hidden(const BaseGraph & g,
163 const std::function<std::string(const Vertex & vd)> &
164 vtostr,
165 const std::function<std::string(const Edge & ed)> &
166 etostr,
167 GPathKindType<GPathKind::kVertexPath>) const;
168
169 std::string to_string_hidden(const BaseGraph & g,
170 const std::function<std::string(const Vertex & vd)> &
171 vtostr,
172 const std::function<std::string(const Edge & ed)> &
173 etostr,
174 GPathKindType<GPathKind::kEdgePath>) const;
175};
176
177
178/* ***************************************************************************
179
180 Template type: EdgeWeightFunction
181 Template constexpr: trivial_edge_weight, value_edge_weight
182
183*******************************************************************************/
184
186template <class Vertex, class Edge, class Weight = double>
188 std::function< Weight(const typename Graph<Vertex,Edge>::eiterator &) >;
189
191template <class Vertex, class Edge>
192constexpr double trivial_edge_weight(
193 const typename Graph<Vertex,Edge>::eiterator &) noexcept
194 { return(1.0); }
195
196
198template <class Vertex, class Edge>
199constexpr double value_edge_weight(
200 const typename Graph<Vertex,Edge>::eiterator & eit) noexcept
201 { return(*eit); }
202
203
204
205/* ===========================================================================
206
207 ========== IMPLEMENTATION OF TEMPLATES ===========
208
209============================================================================= */
210
211/* ***************************************************************************
212
213 Template class: GPath
214
215*******************************************************************************/
216
217template <class Vertex, class Edge, GPathKind KIND>
218GPath<Vertex,Edge,kOtherGPathKind(KIND)>
219 GPath<Vertex,Edge,KIND>::other_hidden(
220 const BaseGraph & g,
221 const typename BaseGraph::EPred & p,
222 GPathKindType<GPathKind::kVertexPath>) const
223{
224 // from vertex to edge path
225 GPath<Vertex,Edge,GPathKind::kEdgePath> np;
226
227 bool first{true};
228 typename BaseGraph::viterator prevvit;
229 for (const auto & vit : *this)
230 {
231 if (first) first = false;
232 else np.push_back(g.connected(prevvit,vit,p));
233 prevvit = vit;
234 }
235 return(np);
236}
237
238template <class Vertex, class Edge, GPathKind KIND>
239GPath<Vertex,Edge,kOtherGPathKind(KIND)>
240 GPath<Vertex,Edge,KIND>::other_hidden(
241 const BaseGraph & g,
242 const typename BaseGraph::EPred & p,
243 GPathKindType<GPathKind::kEdgePath>) const
244{
245 // from edge to vertex path
246 GPath<Vertex,Edge,GPathKind::kVertexPath> np;
247
248 auto eit = this->begin();
249 typename BaseGraph::viterator vit0,vit1;
250 bool first{true};
251 while (eit != this->end())
252 {
253 g.connection(eit,vit0,vit1);
254 if (first)
255 {
256 np.push_back(vit0);
257 first = false;
258 }
259 np.push_back(vit1);
260 ++eit;
261 }
262
263 return(np);
264}
265
266template <class Vertex, class Edge, GPathKind KIND>
267std::string GPath<Vertex,Edge,KIND>::to_string_hidden(
268 const BaseGraph & g,
269 const std::function<std::string(const Vertex & vd)> & vtostr,
270 const std::function<std::string(const Edge & ed)> & etostr,
271 GPathKindType<GPathKind::kVertexPath>) const
272{
273 std::string res{"VPATH with "};
274 res += std::to_string(this->size()) + " vertices: < ";
275 for (const auto & vit: *this) res += vtostr(*vit) + " ";
276 return(res + ">");
277}
278
279template <class Vertex, class Edge, GPathKind KIND>
280std::string GPath<Vertex,Edge,KIND>::to_string_hidden(
281 const BaseGraph & g,
282 const std::function<std::string(const Vertex & vd)> & vtostr,
283 const std::function<std::string(const Edge & ed)> & etostr,
284 GPathKindType<GPathKind::kEdgePath>) const
285{
286 std::string res{"EPATH with "};
287 res += std::to_string(this->size()) + " edges: < ";
288 typename BaseGraph::viterator vit0,vit1;
289 for (const auto & eit: *this)
290 {
291 g.connection(eit,vit0,vit1);
292 res += etostr(*eit) + ":(" + vtostr(*vit0) + " -> " +
293 vtostr(*vit1) + ") ";
294 }
295 return(res + ">");
296}
297
298
301} // end graphs namespace
302
303} // end adts namespace
304
305} // end elementa namespace
306
307
308#endif
309
310
#define ELE_CLASS_ENUM(NameEnumClass,...)
Define an extended enum type.
Definition: enums.h:502
GPathElement< Vertex, Edge, KIND > VectorElem
The type of the elements of the vector.
Definition: graph_paths.h:89
std::vector< VectorElem > BasePath
Base type of the path.
Definition: graph_paths.h:92
Graph< Vertex, Edge > BaseGraph
The graph class on which the path is defined.
Definition: graph_paths.h:95
std::vector< GPath > Collection
A collection of paths.
Definition: graph_paths.h:98
static const GPathKind kKind
The kind of the path.
Definition: graph_paths.h:86
std::string to_string(const BaseGraph &g, const std::function< std::string(const Vertex &vd)> &vtostr=[](const Vertex &vd) ->std::string { return(std::to_string(vd));}, const std::function< std::string(const Edge &ed)> &etostr=[](const Edge &ed) ->std::string { return(std::to_string(ed));}) const
Return a text version of the path.
Definition: graph_paths.h:133
GPath< Vertex, Edge, kOtherGPathKind(KIND) > other(const BaseGraph &g, const typename BaseGraph::EPred &epred=BaseGraph::trivial_epred) const
Construct a path of the other kind equivalent to this one.
Definition: graph_paths.h:124
A path in a graph whose vertices are of type Vertex and edges of type Edge.
Definition: graph_paths.h:79
std::function< Weight(const typename Graph< Vertex, Edge >::eiterator &) > EdgeWeightFunction
A family of functions that return the weight of an edge.
Definition: graph_paths.h:188
constexpr double value_edge_weight(const typename Graph< Vertex, Edge >::eiterator &eit) noexcept
A family of functions that return the edge value as the weight.
Definition: graph_paths.h:199
constexpr double trivial_edge_weight(const typename Graph< Vertex, Edge >::eiterator &) noexcept
A family of functions that return 1.0 as the weight of any edge.
Definition: graph_paths.h:192
typename std::conditional< KIND==GPathKind::kVertexPath, typename Graph< Vertex, Edge >::viterator, typename Graph< Vertex, Edge >::eiterator >::type GPathElement
Type of the elements of a path, according to its kind.
Definition: graph_paths.h:74
constexpr GPathKind kOtherGPathKind(GPathKind kid)
The kind opposite to a given one.
Definition: graph_paths.h:65
A type corresponding to each constant value of the kind of a path.
Definition: graph_paths.h:62
std::function< bool(const Edge &) > EPred
Predicate that indicates which edges to iterate on.
Definition: graphs.h:279
static constexpr bool trivial_epred(const Edge &) noexcept
A trivial predicate that always return true.
Definition: graphs.h:282
All graph classes derive from this one.
Definition: graphs.h:107
A mutable iterator that can have multiple iteration behaviors. Forward case.
Definition: iterators.h:299