Is there a simple way of finding all simple paths where an integer value on a edge is greater than the value of the previous edge? Thereby creating a list of paths that maintain an increasing value of an attribute.
I have successfully implemented this utilizing all_simple_paths and then inspecting for those that increase. However on large graphs this approach fails (takes more time than I have left to live). I have made many many attempts with my naive for loop approach failing.
Can anyone help with this?
Thanks in advance, Peter
EDIT... The code below works, how to I do it better? It produces two graphs, the input graph and the desired output
> nodes
id
1 s01
2 s02
3 s03
4 s04
5 s05
6 s06
7 s07
8 s08
9 s09
> links
from to attributeValue
1 s01 s03 1
2 s01 s05 2
3 s01 s06 1
4 s01 s04 2
5 s04 s05 3
6 s05 s07 3
7 s06 s08 2
8 s08 s07 3
9 s03 s08 2
10 s03 s04 2
11 s02 s07 3
12 s03 s07 3
13 s07 s09 1
#--------------------------------------------------
numberOfLevels <- 3
greaterAndEqual=">=" #>, >=, <
#---------------------------------------------------
net <- graph_from_data_frame(d=links, vertices=nodes, directed=T)
#all simple paths
asp <-list()
max <- vcount(net)
for(i in 1:max)
{
asp<- append(asp,all_simple_paths(net, from=i, to = V(net), mode = "out"))
}
#separate into edges with various levels
edge.list <-list()
for(i in 1:numberOfLevels)
{
edge.list [[i]]<-E(net)[[ attributeValue == i ]]
}
#trim to only sequences with the required length
endoflist <-length(asp)
newasp <- list()
for(i in 1:endoflist)
{
if(length(asp[[i]])== numberOfLevels+1)
{
newasp <- append(newasp, asp[i])
}
}
#function to find vertices on paths in which their edges progressively
#increase in attribute value OR based on the value of greaterAndEqual
#increase or even maintain that value in the subsequent hop. But never
#decrease.
findIncPaths<- function(plist)
{
lengthOflist <-length(plist)
counter<-0
for(j in 1:lengthOflist)
{
if(j+1 <= lengthOflist)
{
name1 <-newasp[[i]][[j]]$name
name2 <-newasp[[i]][[j+1]]$name
ei<-get.edge.ids(net, c(name1,name2), directed = TRUE, error = FALSE, multi = FALSE)
ed<-E(net)[ei]
if(j>1)
{
if(switch(greaterAndEqual,
">" = ed$attributeValue > edgeattribute,
">=" =ed$attributeValue >= edgeattribute,
"<" =ed$attributeValue < edgeattribute))
{
counter <- counter+1
if(counter == numberOfLevels)
{
return(TRUE)
}
edgeattribute <- ed$attributeValue # remember the last attribute level
}
}
else
{
edgeattribute <- ed$attributeValue
counter <- counter+1
}
}
}
return(FALSE)
}
edgeattribute <- 0
goodpaths<-list()
for(i in 1:length(newasp))
{
if(findIncPaths(newasp[[i]]))
{
goodpaths<- append(goodpaths, newasp[i])
}
}
if(length(goodpaths)<1)
{
print("--------------Error No Paths Found-----------------------")
}else
{
cnt<-0
newLinks <- data.frame(NULL, NULL,NULL)
numberOfPaths <- length(goodpaths)
for(i in 1: numberOfPaths)
{
numberOfVert <- length(goodpaths[[i]])
for (j in 1: numberOfVert)
{
cnt <- cnt +1
if(j<numberOfVert)
{
name1<-goodpaths[[i]][[j]]$name
name2<-goodpaths[[i]][[j+1]]$name
newLinks[cnt, 1]<- name1
newLinks[cnt, 2]<- name2
ei<-get.edge.ids(net, c(name1,name2), directed = TRUE, error = FALSE, multi = FALSE)
ed<-E(net)[ei]
newLinks[cnt, 3]<- ed$attributeValue
}
else
{
cnt <- cnt -1
}
}
names(newLinks)[3]<-"attributeValue"
names(newLinks)[2]<-"TO"
names(newLinks)[1]<-"FROM"
}
g2 <- graph_from_data_frame(newLinks, directed=TRUE, nodes)
l <- layout_with_fr(net)
tkplot(net, layout=l, edge.label=links$attributeValue, vertex.color = "yellow")
tkplot(g2, layout=l, edge.label=newLinks$attributeValue, vertex.color = "yellow")
}