Traverse the graph through an arbitrary number of vertices

31 views
Skip to first unread message

Sean Morton

unread,
Apr 2, 2015, 12:40:08 AM4/2/15
to pacer...@googlegroups.com
Hi all,
 
I'm starting to understand how traversing with out_e / in_v works, but I'm wondering about how to do this with an arbitrary number of vertices in the path. For example,

If I wanted to find a path between vertices 1 and 2 with an intermediate vertex in that path, I'd do

vertex(1).out_e.in_v.out_e.in_v(vertex(2))


How could I write a similar traversal for a path between 1 and 2 with N intermediate vertices?

Darrick Wiebe

unread,
Apr 2, 2015, 1:06:15 AM4/2/15
to Pacer Group
Hi Sean,

You could use either the all or deepest methods to traverse over an arbitrary number of intermediate steps, or if you're using Neo4j, you could use its built-in pathfinding algorithms, so one of these:

vertex(1).all { |v| v.out_e.in_v }.only(vertex(2)).paths
vertex(1).deepest { |v| v.out_e.in_v }.only(vertex(2)).paths
vertex(1).paths_to(vertex(2)) # neo4j only

Hope that helps!

Darrick

--
You received this message because you are subscribed to the Google Groups "pacer-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pacer-users...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

张轩

unread,
Apr 2, 2015, 10:43:46 PM4/2/15
to pacer...@googlegroups.com
Hey Darrick,

Thanks a lot for the answer, so we have yet another tricky question.

I have links that together form a route, and routes are formed by links with the same route id as long as possible that means each link has a route id property, and during a traversal we pick the edges that have a mathcing route id as long as possible,if we run out of options then we choose a link with a different route id. and eventually form an entire route.

How would this be done?

在 2015年4月2日星期四 UTC-5上午12:06:15,Darrick Wiebe写道:

张轩

unread,
Apr 3, 2015, 1:25:05 AM4/3/15
to pacer...@googlegroups.com
Actually my question is not entirely accurate, here's what we are trying to achieve,

with this code 

DB.vertex("13:1").all { |v| v.out_e.in_v }.only(DB.vertex("13:5")).paths


we get


[#<V[13:1]>, #<E[12:4]:13:1-eLink-13:4>, #<V[13:4]>, #<E[12:14]:13:4-eLink-13:5>, #<V[13:5]>, #<E[12:18]:13:5-eLink-13:6>, #<V[13:6]>]


and more,


so each of the eLink edge has a RID property, so we only want routes that all the eLink edge has uniq RID.


Thanks a lot!


Xuan


在 2015年4月2日星期四 UTC-5上午12:06:15,Darrick Wiebe写道:
Hi Sean,

Darrick Wiebe

unread,
Apr 3, 2015, 12:12:26 PM4/3/15
to Pacer Group
Hi Xuan,

I'm not certain that I understand your question, but I'll try to answer.

It sounds like you want only paths that contain vertex 13:5 somewhere in them, and only if they are not circular.

To do that, you probably would need to use the more explicit loop / while construct. Something like this:

target = DB.vertex("13:5")
DB.vertex("13:1").loop do |v|
  v.out_e.in_v
end.while do |vertex, depth, path|
  if path != path.uniq
     nil
  elsif path.any? { |el| el == target }
    :loop_and_emit
  else
    :loop
  end
end

If you can filter edges globally so that you only ever follow any edge once, you can simplify a little this way:

DB.vertex("13:1").all { |v| v.out_e.uniq.in_v }.paths.lookahead { |p| p.vertices.scatter.is(DB.vertex("13:5")) }

Hope that helps!

Darrick

张轩

unread,
Apr 3, 2015, 1:24:17 PM4/3/15
to pacer...@googlegroups.com
Thanks a lot for the response!

so its not quite what i was try to achieve,

so for this

[#<V[13:1]>, #<E[12:4]:13:1-eLink-13:4>, #<V[13:4]>, #<E[12:14]:13:4-eLink-13:5>, #<V[13:5]>, #<E[12:18]:13:5-eLink-13:6>, #<V[13:6]>]

im finding all the routes from 13:1 to 13:6 and this is one of the result that returned.

so we can see all the edge that connect them are

#<E[12:4]:13:1-eLink-13:4>
#<E[12:14]:13:4-eLink-13:5>
#<E[12:18]:13:5-eLink-13:6>

and for each of these edges(called eLink) has a property named LID

so what i want to do is to find all the routes between say 13:1 to 13:6  but with the condition that all the edge connecting 13:1 to 13:6 has unique LID

which means if

 [#<V[13:1]>, #<E[12:4]:13:1-eLink-13:4>, #<V[13:4]>, #<E[12:14]:13:4-eLink-13:5>, #<V[13:5]>, #<E[12:18]:13:5-eLink-13:6>, #<V[13:6]>] 

satisfied the condition then 

#<E[12:4]:13:1-eLink-13:4>
#<E[12:14]:13:4-eLink-13:5>
#<E[12:18]:13:5-eLink-13:6>

All has unique LID property values.

Thanks again for the help!!

Xuan

在 2015年4月3日星期五 UTC-5上午11:12:26,Darrick Wiebe写道:

Darrick Wiebe

unread,
Apr 3, 2015, 1:55:48 PM4/3/15
to Pacer Group
In that case, it is even simpler. In your example it looked like you were looking for 13:5 which is what confused me.

DB.vertex("13:1").loop do |v|
  v.out_e.in_v
end.while do |vertex, depth, path|
  if path != path.uniq
     nil
  else
    :loop_and_emit
  end
end.is(DB.vertex("13:6").paths

I recommend you experiment with this a bit to see how it works. It's pretty easy to get what you want once you figure out the pattern and how the pieces Pacer gives you can be combined.

Darrick

张轩

unread,
Apr 5, 2015, 12:18:41 AM4/5/15
to pacer...@googlegroups.com
Hi, thanks agin for the help,

so i ruined this 

DB.vertex("13:1").loop do |v|

  v.out_e.in_v

end.while do |vertex, depth, path|

  if path != path.uniq

     nil

  else

    :loop_and_emit

  end

end.is(DB.vertex("13:6")).paths


It gives me back the following 

/home/ec2-user/.rvm/gems/jruby-1.7.19/gems/pacer-2.0.13-java/lib/pacer/pipe/loop_pipe.rb:13 warning: ambiguous Java methods found, using setStarts(java.util.Iterator)

Total: 0

 => #<V-Loop(#<V -> outE -> inV>) -> is(nil) -> Path-Path> 


And here's what I was actually trying to achieve

DB.vertex("13:1").loop do |v|
  v.out_e.in_v
end.while do |edge|
  if edge[:RouteID] != edge[:RouteID].uniq  <------ the edge has a RouteID property and I would like it to me unique for every edge that connects that one path
                                                                              *different edge may have the same RouteID.
     nil
  else
    :loop_and_emit
  end
end.is(DB.vertex("13:6")).paths

My questions is that when i tried this it seems edge docent really have a uniq method so is there a way to achieve this?

Thanks a lot!

Xuan


在 2015年4月3日星期五 UTC-5下午12:55:48,Darrick Wiebe写道:

Darrick Wiebe

unread,
Apr 5, 2015, 1:05:44 AM4/5/15
to Pacer Group
Hi Xuan,

The signature of the while block is |element, depth, path|. The element is each vertex produced by the loop block. I'm sure with a little experimentation you can figure this one out. It's good to use irb to experiment. I often edit code in my text editor, save it, then use load "path/to/filename.rb" to reload my changed code and get a fast feedback loop going.

Good luck!
Darrick
Reply all
Reply to author
Forward
0 new messages