简体   繁体   中英

How to select certain paths of a graph based on their length, using igraph in R

given a graph, for example:

require(igraph)
g <- graph.famous("Zachary")

such that some of its properties are:

diameter(g)
[1] 5
> farthest.nodes(g)
[1] 15 17  5
> average.path.length(g)
[1] 2.4082
> path.length.hist(g)
$res
[1]  78 265 137  73   8
$unconnected
[1] 0

As you can see there are 8 paths with length = 5, 73 with length = 4, and so on...

I would like to be able to isolate groups of nodes that are involved in a path of certain length. For example, I would like to know the nodes involve in the 73 paths of length 4, and their connected nodes respectively.

Let me clarify this with one easy example, the diameter of the graph. For this particular case one can do:

##names of the nodes involved in the diameter path of the graph
nodes.diameter<-get.diameter(g) 
edges <- as.data.frame(get.edgelist(g))
edges.diameter <- edges[which(edges$V1 %in% nodes.diameter),]
g.diameter <- graph.data.frame(edges.diameter, directed = FALSE)
##some aesthetics for the plot
V(g.diameter)$label.cex <- 1
plot(g.diameter,vertex.size=10) 

在此处输入图片说明

This is a particular example because is easy to get the node names for the diameter. But, is there a way to get the node names given a certain path length? (naively, something like get.path(g,length = X) , and in a naive, ideal world this would return a list with the nodes involved in the paths of length = X . For example, for length = 4 , the list would have length 73 elements each containing the nodes involved in each of the 73 paths of length 4)

many thanks in advance for your time.

The path.length.hist function looks at all possible shortest paths. So these two commands are the same

# path.length.hist(g)$res
[1]  78 265 137  73   8

sp <- shortest.paths(g)
table(sp[upper.tri(sp)])
#   1   2   3   4   5 
#  78 265 137  73   8

which means the the information you are after can be extracted from shortest.paths() . Here's a function that will return the index of the vertices involved in the paths

get_paths_by_length <- function(g, len) {
    sp <- shortest.paths(g)
    sp[lower.tri(sp,TRUE)] <- NA
    wp <- which(sp==len, arr.ind=TRUE)
    mapply(function(a,b) get.shortest.paths(g, a, b)$vpath, wp[,1], wp[,2])
}

which returns

get_paths_by_length(g,5)
# [[1]]
# [1] 15 33  3  1  6 17
# [[2]]
# [1] 16 33  3  1  6 17
# [[3]]
# [1] 17  6  1  3 33 19
# [[4]]
# [1] 17  6  1  3 33 21
# [[5]]
# [1] 17  6  1  3 33 23
# [[6]]
# [1] 17  6  1  3 28 24
# [[7]]
# [1] 17  6  1  9 34 27
# [[8]]
# [1] 17  6  1  3 33 30

for the eight paths of length 5.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM