7

My question is: is it possible to implement Dijkstra's algorithm using Cypher? the explanation on the neo4j website only talks about REST API and it is very difficult to understand for a beginner like me

Please note that I want to find the shortest path with the shortest distance between two nodes, and not the shortest path (involving least number of relationships) between two nodes. I am aware of the shortestPath algorithm that is very easy to implement using Cypher, but it does not serve my purpose.

Kindly guide me on how to proceed if I have a graph database with nodes, and relationships between the nodes having the property 'distance'. All I want is to write a code with the help of which we will be able to find out the shortest distance between two nodes in the database. Or any tips if I need to change my approach and use some other program for this?

Shazu
  • 587
  • 3
  • 10
  • there is a [recent question](http://stackoverflow.com/questions/27346686/implementing-dijkstras-algorithm-in-neo4j) related to this one, maybe that helps. – zaboco Dec 08 '14 at 15:52
  • yea I asked that question, the answer I received was correct in the sense that I could obtain shortest path (least number of relationships) and the sum of the distances between the nodes....but what I am looking for is the shortest path (least 'distance') so I have to put up another question to clarify that – Shazu Dec 08 '14 at 15:55
  • What does "distance" here mean? Do you have some attribute on your relationship that represents the distance over one relationship "hop" between two nodes? – FrobberOfBits Dec 08 '14 at 17:19
  • Yes, exactly. Each relationship has a property called distance – Shazu Dec 08 '14 at 18:25

2 Answers2

7

In this case you can implement the allShortestPaths, ordering the paths in an ascending order based on your distance property of the relationships and return only one, based on your last post it would be something like this :

MATCH (from: Location {LocationName:"x"}), (to: Location {LocationName:"y"}) , 
paths = allShortestPaths((from)-[:CONNECTED_TO*]->(to))
WITH REDUCE(dist = 0, rel in rels(paths) | dist + rel.distance) AS distance, paths
RETURN paths, distance
ORDER BY distance
LIMIT 1
Christophe Willemsen
  • 19,399
  • 2
  • 29
  • 36
  • thanks!! can you please edit your code: paths instead of path in the fourth line and paths instead of p in the fifth line so that if anyone else sees this in the future, they are not confused. – Shazu Dec 08 '14 at 21:37
  • yes sure, sorry about it, mixed with some tests in local :) – Christophe Willemsen Dec 08 '14 at 21:41
  • 1
    The dijkstra implementation in Neo4j can also be used as part of a server extension or via the REST API: http://neo4j.com/docs/stable/rest-api-graph-algos.html#rest-api-execute-a-dijkstra-algorithm-with-equal-weights-on-relationships – Michael Hunger Dec 10 '14 at 05:05
  • 3
    Caution - Above solution first filters all shortest paths *based on number of relationships*. Then it uses distance property to find the shortest. In step 1, we may already miss the paths that have more number of relationships but less total distance – Prashant Deep Sep 18 '15 at 15:22
  • They will be returned, all the sense of allShortestPath – Christophe Willemsen Sep 18 '15 at 17:51
1

No, it's not possible in a reasonable way unless you use transactions and basically rewrite the algorhythm. The previous answer is wrong as longer but less expensive paths will not be returned by the allShortestPaths subset. You will be filtering a subset of paths that have been chosen without considering relationship cost.

Pempo
  • 63
  • 7