Skip to content

Commit 8dca7eb

Browse files
authored
Add files via upload
1 parent bf92f07 commit 8dca7eb

File tree

7 files changed

+832
-3
lines changed

7 files changed

+832
-3
lines changed

README.Rmd

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ Data has to be a 3 columns data.frame or matrix containing from, to and a cost/d
5555
- `get_distance_pair` : compute distances between origin and destination by pair (*one-to-one*),
5656
- `get_path_pair` : compute shortest paths between origin and destination by pair (*one-to-one*),
5757
- `get_multi_paths` : compute shortest paths between all origin nodes and all destination nodes (*one-to-many*),
58-
- `get_isochrone` : compute isochrones/isodistances with one or multiple breaks.
59-
58+
- `get_isochrone` : compute isochrones/isodistances with one or multiple breaks.
59+
- `cpp_simplify` : remove non-intersection nodes, duplicated edges and isolated loops in the graph. Graph topology is preserved so distance calculation is faster and remains true. This function can be applied to very large graphs (several millions of nodes).
60+
61+
62+
###Path algorithms
6063
The choice between all the algorithms is available for *one-to-one* calculation like `get_distance_pair` and `get_path_pair`.
6164
In these functions, uni-directional Dijkstra algorithm is stopped when the destination node is reached.
6265
`A*` and `NBA*` are relevant if geographic coordinates of all nodes are provided. Note that coordinates should be expressed in a **projection system**.
@@ -184,7 +187,104 @@ p
184187
185188
```
186189

190+
###Graph simplification
191+
`cpp_simplify`'s internal function performs two major steps :
192+
193+
- removing non-intersection nodes between two intersection nodes then calculate cost of the new edges,
194+
- removing duplicate edges that are potentially created in the first step.
195+
In order to remove maximum number of nodes, some iterations are needed until only intersection nodes are remained.
196+
197+
Let's see a small example :
198+
```{r,echo=TRUE,message=FALSE,warning=FALSE}
199+
library(igraph)
200+
#Create directed graph
201+
edges<-data.frame(from=c("a","b","c","d",
202+
"d","e","e","e",
203+
"f","f","g","h","h","h",
204+
"i","j","k","k","k",
205+
"l","l","l","m","m","m",
206+
"n","n","o","p","q","r"),
207+
to=c("b","c","d","e","k","f","d",
208+
"h","g","e","f","e","i","k",
209+
"j","i","h","d","l","k",
210+
"m","n","n","o","l","l","m","m",
211+
"r","p","q"),
212+
dist=rep(1,31))
213+
214+
#Plotting with igraph
215+
par(mfrow=c(1,2),mar=c(3,0,3,0))
216+
217+
igr1<-graph_from_data_frame(edges)
218+
set.seed(2)
219+
plot.igraph(igr1,edge.arrow.size=.3,main="Original graph")
220+
box(col="black")
221+
222+
#Instantiate cppRouting graph, then simplify without iterations
223+
graph_ex<-makegraph(edges,directed = TRUE)
224+
simp<-cpp_simplify(graph_ex,rm_loop = FALSE)
225+
#Convert graph to df
226+
edges2<-to_df(simp$graph)
227+
228+
#Plotting simplified graph
229+
igr2<-graph_from_data_frame(edges2)
230+
set.seed(2)
231+
plot(igr2,edge.arrow.size=.3,edge.label=E(igr2)$dist,main="One iteration - keeping loop")
232+
box(col="black")
233+
```
234+
235+
Here, junction nodes are `e`, `h`, `d`, `k`, `l`, `i` and `m`. So `b`, `c`, `f` and `n` have been contracted in the first step of the function. By contracting `n`, an edge with cost of 2 has been created between `m` and `l` nodes.
236+
The second step of the function has removed this edge which is greater than the original one (e.g 1), and the whole process now need a second iteration to remove `m` and `l` that aren't intersection nodes anymore.
237+
Let's try with `iterate` argument set to `TRUE` :
238+
239+
```{r,echo=TRUE,message=FALSE,warning=FALSE}
240+
par(mfrow=c(1,2),mar=c(3,0,3,0))
241+
#Simplify with iterations
242+
simp2<-cpp_simplify(graph_ex,rm_loop = FALSE,iterate = TRUE)
243+
edges3<-to_df(simp2$graph)
244+
igr3<-graph_from_data_frame(edges3)
245+
set.seed(2)
246+
plot(igr3,edge.arrow.size=.3,edge.label=E(igr3)$dist,main="Second iteration - keeping loop")
247+
box(col="black")
248+
249+
#The same but removing loops
250+
simp3<-cpp_simplify(graph_ex,rm_loop = TRUE,iterate = TRUE)
251+
edges4<-to_df(simp3$graph)
252+
253+
igr4<-graph_from_data_frame(edges4)
254+
set.seed(2)
255+
plot(igr4,edge.arrow.size=.3,edge.label=E(igr4)$dist,main="Second iteration - removing loop")
256+
box(col="black")
257+
```
258+
259+
####French road network simplification
260+
```{r,echo=TRUE,message=FALSE,warning=FALSE}
261+
#Simplify original graph by keeping nodes of interest
262+
graph2<-cpp_simplify(graph,
263+
iterate = TRUE,
264+
keep = unique(c(origin,destination)))
265+
266+
#Running NBA*
267+
system.time(
268+
pair_nba_2<-get_distance_pair(graph2$graph,origin,destination,algorithm = "NBA",constant = 110/0.06)
269+
)
270+
271+
```
272+
#####Compare outputs
273+
```{r,echo=TRUE,message=FALSE,warning=FALSE}
274+
summary(pair_nba-pair_nba_2)
275+
276+
```
187277

278+
####Running time
279+
Here are running times in second on graphs of different sizes (data presented here, TEXAS road network from [SNAP](http://snap.stanford.edu/data/roadNet-TX.html) and french road network from OpenStreetMap and extracted with [osm2po](https://osm2po.de/) tool).
280+
281+
```{r,echo=FALSE,message=FALSE,warning=FALSE}
282+
library(kableExtra)
283+
bench<-read.csv2("benchmark_simplify.csv")
284+
colnames(bench)<-gsub("\\."," ",colnames(bench))
285+
knitr::kable((bench),format.args = list(big.mark = ","))
286+
```
287+
188288
#Applications
189289
## Application 1 : Calculate Two Step Floating Catchment Areas (2SFCA) of general practitioners in France
190290

@@ -364,5 +464,4 @@ setdiff(test_dodgr[[1]][[1]],test_cpp[[1]])
364464
#New algorithms `cppRouting` will provide in the future
365465

366466
- Detours admitting shortest paths : finding the nodes that are reachable under a fixed detour time around the shortest path
367-
- Graph simplification by removing irrelevant nodes in order to compute in a faster way the shortest distance or travel time
368467
- Contraction hierarchies implementation

0 commit comments

Comments
 (0)