简体   繁体   中英

Random Postorder traversal in neo4j

I'm trying to create an algorithm in Neo4j using the java API. The algorithm is called GRAIL ( http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.169.1656&rep=rep1&type=pdf ) and it assigns labels to a graph for later answering reachability queries.

This algorithm uses postorder depth first search but with random traversal each time (each child of a node is visited randomly in each traversal). In the neo4j java api there is an algorithm doing this ( https://github.com/neo4j/neo4j/blob/7f47df8b5d61b0437e39298cd15e840aa1bcfed8/community/kernel/src/main/java/org/neo4j/graphdb/traversal/PostorderDepthFirstSelector.java ) without the randomness and i can't seem to find a way to do this.

My code has a traversal description in which i want to add a custom order (BranchOrderingPolicy) in order to achieve the before mentioned algorithm. like this:

 .order(**postorderDepthFirst()**)

The answer to my question came rather easy but after a lot of thinking. I just had to alter the path expander (i created my own) which returns the relationhipss that the traversal takes as next and there a simple line of code to randomize the relationships. The code is :

public class customExpander implements PathExpander {

private final RelationshipType relationshipType;
private final Direction direction;
private final Integer times;

public customExpander (RelationshipType relationshipType, Direction direction ,Integer times)
{
    this.relationshipType = relationshipType;
    this.direction = direction;
    this.times=times;
}



@Override
public Iterable<Relationship> expand(Path path, BranchState state)
{
        List<Relationship> results = new ArrayList<Relationship>();
        for ( Relationship r : path.endNode().getRelationships( relationshipType, direction ) )
        {  
           results.add( r ); 
        }
        Collections.shuffle(results);
        }       
    return results;         
    }


@Override
public PathExpander<String> reverse()
{
    return null;
}

}

There's no such ordering by default in neo4j, however it should be possible to write one. TraversalBranch#next gives the next branch and so your implementation could get all or some and pick at random. However state keeping will be slightly tricky and as memory hungry as a breadth first ordering I'd guess. Neo4j keeps relationships in linked lists per node, so there's no easy way to pick one at random without first gathering all of them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM