1
+ /* PGR-GNU*****************************************************************
2
+ File: pgr_edwardMoore.hpp
3
+ Copyright (c) 2019 pgRouting developers
4
+ Mail: project@pgrouting.org
5
+ Copyright (c) 2019 Gudesa Venkata Sai AKhil
6
+ Mail: gvs.akhil1997@gmail.com
7
+ ------
8
+ This program is free software; you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation; either version 2 of the License, or
11
+ (at your option) any later version.
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program; if not, write to the Free Software
18
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
+ ********************************************************************PGR-GNU*/
20
+
21
+ #ifndef INCLUDE_MST_PGR_EDWARDMOORE_HPP_
22
+ #define INCLUDE_MST_PGR_EDWARDMOORE_HPP_
23
+ #pragma once
24
+
25
+ #include < deque>
26
+
27
+ #include " cpp_common/basePath_SSEC.hpp"
28
+ #include " cpp_common/pgr_base_graph.hpp"
29
+ // ******************************************
30
+
31
+ namespace pgrouting
32
+ {
33
+ namespace functions
34
+ {
35
+
36
+ template <class G >
37
+ class Pgr_edwardMoore
38
+ {
39
+ public:
40
+ typedef typename G::V V;
41
+ typedef typename G::E E;
42
+ typedef typename G::B_G B_G;
43
+ typedef typename G::EO_i EO_i;
44
+ typedef typename G::E_i E_i;
45
+
46
+ std::deque<Path> edwardMoore (
47
+ G &graph,
48
+ std::vector<int64_t > start_vertex,
49
+ std::vector<int64_t > end_vertex)
50
+ {
51
+
52
+ std::deque<Path> paths;
53
+
54
+ for (auto source : start_vertex)
55
+ {
56
+ std::deque<Path> result_paths = one_to_many_edwardMoore (
57
+ graph,
58
+ source,
59
+ end_vertex);
60
+
61
+ paths.insert (
62
+ paths.begin (),
63
+ std::make_move_iterator (result_paths.begin ()),
64
+ std::make_move_iterator (result_paths.end ()));
65
+ }
66
+
67
+ std::sort (paths.begin (), paths.end (),
68
+ [](const Path &e1 , const Path &e2 ) -> bool {
69
+ return e1 .end_id () < e2 .end_id ();
70
+ });
71
+ std::stable_sort (paths.begin (), paths.end (),
72
+ [](const Path &e1 , const Path &e2 ) -> bool {
73
+ return e1 .start_id () < e2 .start_id ();
74
+ });
75
+
76
+ return paths;
77
+ }
78
+
79
+ private:
80
+ E DEFAULT_EDGE;
81
+
82
+ std::deque<Path> one_to_many_edwardMoore (
83
+ G &graph,
84
+ int64_t start_vertex,
85
+ std::vector<int64_t > end_vertex)
86
+ {
87
+
88
+ std::deque<Path> paths;
89
+
90
+ if (graph.has_vertex (start_vertex) == false )
91
+ {
92
+ return paths;
93
+ }
94
+
95
+ std::vector<double > current_cost (graph.num_vertices (), std::numeric_limits<double >::infinity ());
96
+ std::vector<bool > isInQ (graph.num_vertices (), false );
97
+ std::vector<E> from_edge (graph.num_vertices ());
98
+ std::deque<int64_t > dq;
99
+ DEFAULT_EDGE = from_edge[0 ];
100
+
101
+ int64_t bgl_start_vertex = graph.get_V (start_vertex);
102
+
103
+ current_cost[bgl_start_vertex] = 0 ;
104
+ isInQ[bgl_start_vertex] = true ;
105
+ dq.push_front (bgl_start_vertex);
106
+
107
+ while (dq.empty () == false )
108
+ {
109
+ int64_t head_vertex = dq.front ();
110
+
111
+ dq.pop_front ();
112
+ isInQ[head_vertex] = false ;
113
+
114
+ updateVertexCosts (graph, current_cost, isInQ, from_edge, dq, head_vertex);
115
+ }
116
+
117
+ for (auto target_vertex : end_vertex)
118
+ {
119
+ if (graph.has_vertex (target_vertex) == false )
120
+ {
121
+ continue ;
122
+ }
123
+
124
+ int64_t bgl_target_vertex = graph.get_V (target_vertex);
125
+
126
+ if (from_edge[bgl_target_vertex] == DEFAULT_EDGE)
127
+ {
128
+ continue ;
129
+ }
130
+
131
+ paths.push_front (
132
+ getPath (graph, bgl_start_vertex, target_vertex, bgl_target_vertex, from_edge, current_cost));
133
+ }
134
+
135
+ return paths;
136
+ }
137
+
138
+ Path getPath (
139
+ G &graph,
140
+ int64_t bgl_start_vertex,
141
+ int64_t target,
142
+ int64_t bgl_target_vertex,
143
+ std::vector<E> &from_edge,
144
+ std::vector<double > ¤t_cost)
145
+ {
146
+ int64_t current_node = bgl_target_vertex;
147
+
148
+ Path path = Path (graph[bgl_start_vertex].id , graph[current_node].id );
149
+
150
+ path.push_back ({target, -1 , 0 , current_cost[current_node]});
151
+
152
+ do
153
+ {
154
+ E e = from_edge[current_node];
155
+ auto from = graph.source (e);
156
+
157
+ path.push_back ({graph[from].id , graph[e].id , graph[e].cost , current_cost[from]});
158
+
159
+ current_node = from;
160
+ } while (from_edge[current_node] != DEFAULT_EDGE);
161
+
162
+ std::reverse (path.begin (), path.end ());
163
+ return path;
164
+ }
165
+
166
+ void updateVertexCosts (
167
+ G &graph,
168
+ std::vector<double > ¤t_cost,
169
+ std::vector<bool > &isInQ,
170
+ std::vector<E> &from_edge,
171
+ std::deque<int64_t > &dq,
172
+ int64_t &head_vertex)
173
+ {
174
+ auto out_edges = boost::out_edges (head_vertex, graph.graph );
175
+ E e;
176
+ EO_i out_i;
177
+ EO_i out_end;
178
+ V v_source, v_target;
179
+
180
+ for (boost::tie (out_i, out_end) = out_edges;
181
+ out_i != out_end; ++out_i)
182
+ {
183
+
184
+ e = *out_i;
185
+ v_target = graph.target (e);
186
+ v_source = graph.source (e);
187
+ double edge_cost = graph[e].cost ;
188
+
189
+ if (std::isinf (current_cost[v_target]) or current_cost[v_source] + edge_cost < current_cost[v_target])
190
+ {
191
+
192
+ current_cost[v_target] = current_cost[v_source] + edge_cost;
193
+
194
+ from_edge[v_target] = e;
195
+
196
+ if (isInQ[v_target] == false )
197
+ {
198
+ dq.push_back (v_target);
199
+ isInQ[v_target] = true ;
200
+ }
201
+ }
202
+ }
203
+ }
204
+ };
205
+ } // namespace functions
206
+ } // namespace pgrouting
207
+
208
+ #endif // INCLUDE_MST_PGR_EDWARDMOORE_HPP_
0 commit comments