Skip to content

Commit a49f556

Browse files
authored
Merge pull request #25 from vicennial/pgr_edwardMoore
pgr_edwardMoore GSOC-2019 week 10
2 parents 3baccbd + da929a6 commit a49f556

File tree

2 files changed

+242
-10
lines changed

2 files changed

+242
-10
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
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> &current_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> &current_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_

src/edwardMoore/edwardMoore_driver.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3434
#include <deque>
3535
#include <vector>
3636
#include <algorithm>
37-
//TODO : Correct the headers
38-
// #include "edwardMoore/pgr_edwardMoore.hpp"
37+
38+
#include "edwardMoore/pgr_edwardMoore.hpp"
3939

4040
//TODO : Remove below
4141

@@ -56,6 +56,30 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
5656
#include "cpp_common/pgr_alloc.hpp"
5757
#include "cpp_common/pgr_assert.h"
5858

59+
template < class G >
60+
std::deque< Path >
61+
pgr_edwardMoore(
62+
G &graph,
63+
std::vector < int64_t > sources,
64+
std::vector < int64_t > targets) {
65+
std::sort(sources.begin(), sources.end());
66+
sources.erase(
67+
std::unique(sources.begin(), sources.end()),
68+
sources.end());
69+
70+
std::sort(targets.begin(), targets.end());
71+
targets.erase(
72+
std::unique(targets.begin(), targets.end()),
73+
targets.end());
74+
75+
pgrouting::functions::Pgr_edwardMoore< G > fn_edwardMoore;
76+
auto paths = fn_edwardMoore.edwardMoore(
77+
graph,
78+
sources, targets);
79+
80+
return paths;
81+
}
82+
5983
void
6084
do_pgr_edwardMoore(
6185
pgr_edge_t *data_edges,
@@ -98,20 +122,20 @@ do_pgr_edwardMoore(
98122
pgrouting::DirectedGraph digraph(gType);
99123
digraph.insert_edges(data_edges, total_edges);
100124

101-
// paths = pgr_edwardMoore(
102-
// digraph,
103-
// start_vertices,
104-
// end_vertices);
125+
paths = pgr_edwardMoore(
126+
digraph,
127+
start_vertices,
128+
end_vertices);
105129

106130
} else {
107131
log << "\nWorking with Undirected Graph";
108132
pgrouting::UndirectedGraph undigraph(gType);
109133
undigraph.insert_edges(data_edges, total_edges);
110134

111-
// paths = pgr_edwardMoore(
112-
// undigraph,
113-
// start_vertices,
114-
// end_vertices);
135+
paths = pgr_edwardMoore(
136+
undigraph,
137+
start_vertices,
138+
end_vertices);
115139

116140
}
117141

0 commit comments

Comments
 (0)