neo4j-contrib / neo4j-graph-algorithms

Efficient Graph Algorithms for Neo4j
https://github.com/neo4j/graph-data-science/
GNU General Public License v3.0
767 stars 196 forks source link

MaxDepth param for Breadth-first search #898

Open tomasonjo opened 5 years ago

tomasonjo commented 5 years ago

It looks like the DFS algorithm has the maxDepth parameter that includes the max value while the BFS algorithm does not include it. This can be confusing to an end user.

Create graph:

MERGE (nAlice:User {id:'Alice'})
MERGE (nBridget:User {id:'Bridget'})
MERGE (nCharles:User {id:'Charles'})
MERGE (nDoug:User {id:'Doug'})
MERGE (nMark:User {id:'Mark'})
MERGE (nMichael:User {id:'Michael'})

MERGE (nAlice)-[:FOLLOW]->(nBridget)
MERGE (nAlice)-[:FOLLOW]->(nCharles)
MERGE (nBridget)-[:FOLLOW]->(nMichael)
MERGE (nDoug)-[:FOLLOW]->(nMark)
MERGE (nAlice)-[:FOLLOW]->(nMichael)
MERGE (nCharles)-[:FOLLOW]->(nDoug);

BFS

MATCH (s:User{id:'Bridget'}) 
WITH id(s) as start_id 
CALL algo.bfs.stream('User', 'FOLLOW', 'BOTH', start_id, 
{maxDepth:2}) YIELD nodeIds 
UNWIND nodeIds as nodeId 
RETURN algo.asNode(nodeId).id as user

results:

user -----------| "Bridget"| "Alice"| "Michael"|

DFS

MATCH (s:User{id:'Bridget'}) 
WITH id(s) as start_id 
CALL algo.dfs.stream('User', 'FOLLOW', 'BOTH', start_id, 
{maxDepth:2}) 
YIELD nodeIds 
UNWIND nodeIds as nodeId 
RETURN algo.asNode(nodeId).id as user

results:

user -----------| "Bridget"| "Michael"| "Alice"| "Charles"|

tomasonjo commented 5 years ago

I inspected the code a bit and it is a simple difference in the comparing operator:

DFS:

exitFunction = (s, t, w) -> w > maxDepth ? Traverse.ExitPredicate.Result.CONTINUE : Traverse.ExitPredicate.Result.FOLLOW; BFS:

exitFunction = (s, t, w) -> w >= maxDepth ? Traverse.ExitPredicate.Result.CONTINUE : Traverse.ExitPredicate.Result.FOLLOW;