0

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")



} 
Peter H
  • 1
  • 1
  • 1
    Welcome to SO. This is a bit too broad at the moment. I suggest you skim over [reproducible questions](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) and [minimal, complete, verifiable examples](https://stackoverflow.com/help/mcve), and then come back and edit your question appropriately. At a minimum, I suggest *sample* data and minimal code required to demonstrate your problem(s). – r2evans Jul 02 '17 at 06:25
  • Thanks @r2evans, All I can do is post the code I have that works and produces the desired result. It doesn't work on large graphs because of the reliance on all_simple_paths. Inspection of the code will reveal I am a beginner, no doubt there is a better way. – Peter H Jul 02 '17 at 10:20

0 Answers0