1 | //=======================================================================
|
---|
2 | // Copyright 2015 by Ireneusz Szcześniak
|
---|
3 | // Authors: Ireneusz Szcześniak
|
---|
4 | //
|
---|
5 | // Distributed under the Boost Software License, Version 1.0. (See
|
---|
6 | // accompanying file LICENSE_1_0.txt or copy at
|
---|
7 | // http://www.boost.org/LICENSE_1_0.txt)
|
---|
8 | //=======================================================================
|
---|
9 |
|
---|
10 | //=======================================================================
|
---|
11 | // The custom Dijkstra call, which returns the optional path as a list
|
---|
12 | // of edges along with the cost of the path. The search is stopped
|
---|
13 | // when the destination node is reached.
|
---|
14 | //=======================================================================
|
---|
15 |
|
---|
16 | #ifndef BOOST_GRAPH_CUSTOM_DIJKSTRA_CALL
|
---|
17 | #define BOOST_GRAPH_CUSTOM_DIJKSTRA_CALL
|
---|
18 |
|
---|
19 | #include <list>
|
---|
20 |
|
---|
21 | #include <boost/graph/dijkstra_shortest_paths.hpp>
|
---|
22 | #include <boost/graph/visitors.hpp>
|
---|
23 | #include <boost/optional.hpp>
|
---|
24 | #include <boost/property_map/property_map.hpp>
|
---|
25 | #include <boost/utility/value_init.hpp>
|
---|
26 |
|
---|
27 | namespace boost {
|
---|
28 |
|
---|
29 | //========================================================================
|
---|
30 | // Finish the search when a given node is examined, i.e. when the
|
---|
31 | // shortest path to that node is found.
|
---|
32 | // ========================================================================
|
---|
33 |
|
---|
34 | // The type of the exception thrown by the cdc_visitor.
|
---|
35 | struct cdc_exception {};
|
---|
36 |
|
---|
37 | template <class Graph>
|
---|
38 | struct cdc_visitor
|
---|
39 | {
|
---|
40 | typedef typename Graph::vertex_descriptor vertex_descriptor;
|
---|
41 | typedef on_examine_vertex event_filter;
|
---|
42 | cdc_visitor(vertex_descriptor t): m_t(t) {}
|
---|
43 | void operator()(vertex_descriptor v, const Graph& g) {
|
---|
44 | if (v == m_t)
|
---|
45 | throw cdc_exception();
|
---|
46 | }
|
---|
47 | vertex_descriptor m_t;
|
---|
48 | };
|
---|
49 |
|
---|
50 | //========================================================================
|
---|
51 | // The function.
|
---|
52 | //=======================================================================+
|
---|
53 |
|
---|
54 | template <typename Graph, typename WeightMap, typename IndexMap>
|
---|
55 | optional<std::pair<typename WeightMap::value_type,
|
---|
56 | std::list<typename Graph::edge_descriptor>>>
|
---|
57 | custom_dijkstra_call(const Graph &g,
|
---|
58 | typename Graph::vertex_descriptor s,
|
---|
59 | typename Graph::vertex_descriptor t,
|
---|
60 | WeightMap wm, IndexMap im)
|
---|
61 | {
|
---|
62 | typedef typename Graph::vertex_descriptor vertex_descriptor;
|
---|
63 | typedef typename Graph::edge_descriptor edge_descriptor;
|
---|
64 | typedef typename std::list<typename Graph::edge_descriptor> path_type;
|
---|
65 | typedef typename WeightMap::value_type weight_type;
|
---|
66 | typedef typename std::pair<weight_type, path_type> kr_type;
|
---|
67 |
|
---|
68 | std::vector<edge_descriptor> pred_vec(num_vertices(g));
|
---|
69 | auto pred = make_iterator_property_map(pred_vec.begin(), im);
|
---|
70 | auto rep = record_edge_predecessors(pred, on_edge_relaxed());
|
---|
71 | auto qat = cdc_visitor<Graph>(t);
|
---|
72 | auto dv = make_dijkstra_visitor(std::make_pair(rep, qat));
|
---|
73 |
|
---|
74 | try
|
---|
75 | {
|
---|
76 | dijkstra_shortest_paths(g, s,
|
---|
77 | weight_map(wm).vertex_index_map(im).
|
---|
78 | visitor(dv));
|
---|
79 | }
|
---|
80 | catch (cdc_exception) {}
|
---|
81 |
|
---|
82 | optional<kr_type> result;
|
---|
83 |
|
---|
84 | // Was the solution found?
|
---|
85 | if (pred[t] != edge_descriptor())
|
---|
86 | {
|
---|
87 | // The cost of the shortest path.
|
---|
88 | value_initialized<weight_type> cost;
|
---|
89 | // The path found.
|
---|
90 | path_type path;
|
---|
91 |
|
---|
92 | // Trace the solution to the source.
|
---|
93 | vertex_descriptor c = t;
|
---|
94 | while (c != s)
|
---|
95 | {
|
---|
96 | const edge_descriptor &e = pred[c];
|
---|
97 | // Build the path.
|
---|
98 | path.push_front(e);
|
---|
99 | // Calculate the cost of the path.
|
---|
100 | cost += get(wm, e);
|
---|
101 | // Find the predecessing vertex.
|
---|
102 | c = source(e, g);
|
---|
103 | }
|
---|
104 |
|
---|
105 | result = std::make_pair(cost, path);
|
---|
106 | }
|
---|
107 |
|
---|
108 | return result;
|
---|
109 | }
|
---|
110 |
|
---|
111 | } // boost
|
---|
112 |
|
---|
113 | #endif /* BOOST_GRAPH_CUSTOM_DIJKSTRA_CALL */
|
---|