Reputation: 39
I have the following problem : In a directed weighted graph i want to compute the paths from a node u to the leaves of the graph and then, based on that list, i need to compute the paths from node u to every node v in order to make some computations. Currently i calculate the paths from u to the leaves using
leaves<- which(degree(g, v = V(g), mode = "out")==0, useNames = T)
paths<-all_simple_paths(g, from = V(g)[u], to = leaves)
then, i do some (not related to the thread) calculations on those paths,and after that i compute every path from u to v using
for(v in V(g)){
Pspaths<-all_simple_paths(g,from = V(g)[u],to=V(g)[v])
}
But in this is not an efficient way because most paths are computed more than once so this way is time wasting.
Is there a way to compute the paths from u to v by using the list variable paths
?
Thanks a lot in advance!
Upvotes: 1
Views: 80
Reputation: 3647
You can just turn the calculations around, and first get the paths from u
to everywhere, and then extract from those paths the ones which terminate at a leaf (also, all_simple_paths()
can compute the paths to many vertices at once so you don't need the for loop):
# Generate some data
set.seed(123)
library(igraph)
g <- random.graph.game(20, .05, directed = T)
leaves <- which(degree(g, mode = 'out')==0, useNames = T)
leaves
#> [1] 6 7 9 10 11 12 15 16 17 18
# lets say u = 4
u <- 4
V(g)[u]
#> + 1/20 vertex, from f1ba243:
#> [1] 4
First we'll get all the paths from u
# Get all the paths from u to all other nodes
all_paths_from_u <- all_simple_paths(g, from = V(g)[u])
all_paths_from_u
#> [[1]]
#> + 2/20 vertices, from f1ba243:
#> [1] 4 6
#>
#> [[2]]
#> + 2/20 vertices, from f1ba243:
#> [1] 4 8
#>
#> [[3]]
#> + 3/20 vertices, from f1ba243:
#> [1] 4 8 3
#>
#> [[4]]
#> + 4/20 vertices, from f1ba243:
#> [1] 4 8 3 14
#>
#> [[5]]
#> + 5/20 vertices, from f1ba243:
#> [1] 4 8 3 14 7
#>
#> [[6]]
#> + 2/20 vertices, from f1ba243:
#> [1] 4 18
We can see there are six paths, terminating in 6, 8, 3, 14, 7 and 18. We know from our computations above, that 6, 7, and 18 are leaf nodes. We can therefore use our known leaves to create a new list of paths from u that terminate at a leaf:
# now we extract from these paths the ones that terminate at a leaf
# this means we extract the last element of the path and compare it
# to the known leaves.
leaf_paths <- all_paths_from_u[unlist(lapply(all_paths_from_u, function(p){p[length(p)] %in% leaves}))]
leaf_paths
#> [[1]]
#> + 2/20 vertices, from f1ba243:
#> [1] 4 6
#>
#> [[2]]
#> + 5/20 vertices, from f1ba243:
#> [1] 4 8 3 14 7
#>
#> [[3]]
#> + 2/20 vertices, from f1ba243:
#> [1] 4 18
Upvotes: 1