zoukankan      html  css  js  c++  java
  • neo4j遍历和图算法

    这篇blog主要和大家分享一下neo4j中是如何对节点进行遍历,和其中集成的图论的一些常用算法。

    遍历

    http://docs.neo4j.org.cn/tutorials-java-embedded-traversal.html   这是neo4j官方的中文教程。

    Java代码  收藏代码
    1. private static Traverser getFriends(Node node )  
    2. {  
    3.     TraversalDescription td = Traversal.description()  
    4.             .breadthFirst()  
    5.             .relationships( RelTypes.KNOWS, Direction.OUTGOING )  
    6.             .evaluator( Evaluators.excludeStartPosition() );  
    7.     return td.traverse( node );  
    8. }  
     TraversalDescription提供了用户遍历节点的方法,并且用户需要自己添加遍历的条件。
    首先用户可以定义是使用深度优先还收广度优先 breadthFirst() 和 depthFirst();relationships定义了遍历取得节点的关系类型,是入度Direction.INCOMING还是出度Direction.OUTGOING还是both;evaluator用来定义筛选的条件,比如去掉开始节点,结束节点,遍历深度(toDepth(3))等,具体可以参照官方的API文档。
    Java代码  收藏代码
    1. int num = 0;  
    2. String result = neoNode.getProperty( "name" ) + "'s friends: ";  
    3. Traverser friendsTraverser = getFriends( neoNode );  
    4. for ( Path friendPath : friendsTraverser )  
    5. {  
    6.     output += "At depth " + friendPath.length() + " => "  
    7.               + friendPath.endNode()  
    8.                       .getProperty( "name" ) + " ";  
    9.     numberOfFriends++;  
    10. }  
    11. output += "Number of friends found: " + numberOfFriends + " ";  
      打印出结果
    Java代码  收藏代码
    1. Thomas Anderson's friends:  
    2. At depth 1 => Trinity  
    3. At depth 1 => Morpheus  
    4. At depth 2 => Cypher  
    5. At depth 3 => Agent Smith  
    6. 找到朋友的数量: 4  
     下面介绍如何按照一个预先定义好的顺序遍历图。
    创建一个数据库
    Java代码  收藏代码
    1. Node A = db.createNode();  
    2. Node B = db.createNode();  
    3. Node C = db.createNode();  
    4. Node D = db.createNode();  
    5. A.createRelationshipTo( B, REL1 );  
    6. B.createRelationshipTo( C, REL2 );  
    7. C.createRelationshipTo( D, REL3 );  
    8. A.createRelationshipTo( C, REL2 );  
    现在关系(REL1-->REL2-->REL), 当遍历的时候,Evaluator能够对它进行检验,确保只有该关系顺序的路径才会被包括。
    Java代码  收藏代码
    1. ArrayList<RelationshipType> orderedPathContext = new ArrayList<RelationshipType>();  
    2. orderedPathContext.add( REL1 );  
    3. orderedPathContext.add( withName( "REL2" ) );  
    4. orderedPathContext.add( withName( "REL3" ) );  
    5. TraversalDescription td = Traversal.description()  
    6.         .evaluator( new Evaluator()  
    7.         {  
    8.             @Override  
    9.             public Evaluation evaluate( final Path path )  
    10.             {  
    11.                 if ( path.length() == 0 )  
    12.                 {  
    13.                     return Evaluation.EXCLUDE_AND_CONTINUE;  
    14.                 }  
    15.                 RelationshipType expectedType = orderedPathContext.get( path.length() - 1 );  
    16.                 boolean isExpectedType = path.lastRelationship()  
    17.                         .isType( expectedType );  
    18.                 boolean included = path.length() == orderedPathContext.size()  
    19.                                    && isExpectedType;  
    20.                 boolean continued = path.length() < orderedPathContext.size()  
    21.                                     && isExpectedType;  
    22.                 return Evaluation.of( included, continued );  
    23.             }  
    24.         } );  
     打印出结果
    Java代码  收藏代码
    1. Traverser traverser = td.traverse( A );  
    2. PathPrinter pathPrinter = new PathPrinter( "name" );  
    3. for ( Path path : traverser )  
    4. {  
    5.     output += Traversal.pathToString( path, pathPrinter );  
    6. }  
     用户也可以通过自定义格式输出路径。
    Java代码  收藏代码
    1. static class PathPrinter implements Traversal.PathDescriptor<Path>  
    2. {  
    3.     private final String nodePropertyKey;  
    4.    
    5.     public PathPrinter( String nodePropertyKey )  
    6.     {  
    7.         this.nodePropertyKey = nodePropertyKey;  
    8.     }  
    9.    
    10.     @Override  
    11.     public String nodeRepresentation( Path path, Node node )  
    12.     {  
    13.         return "(" + node.getProperty( nodePropertyKey, "" ) + ")";  
    14.     }  
    15.    
    16.     @Override  
    17.     public String relationshipRepresentation( Path path, Node from,  
    18.             Relationship relationship )  
    19.     {  
    20.         String prefix = "--", suffix = "--";  
    21.         if ( from.equals( relationship.getEndNode() ) )  
    22.         {  
    23.             prefix = "<--";  
    24.         }  
    25.         else  
    26.         {  
    27.             suffix = "-->";  
    28.         }  
    29.         return prefix + "[" + relationship.getType().name() + "]" + suffix;  
    30.     }  
    31. }  

     图算法

    neo4j中集成了一些常用的图算法,包括最短路径,Dijkstra,A*算法。
    最短路径
    Java代码  收藏代码
    1. public Iterable<Path> findShortestPath(Node node1, Node node2) {  
    2.     PathFinder<Path> finder = GraphAlgoFactory.shortestPath(  
    3.         Traversal.expanderForTypes(RelTypes.KNOWS, Direction.BOTH), 10);  
    4.         Iterable<Path> paths = finder.findAllPaths(node1, node2);  
    5.     return paths;  
    6. }  
     
    Java代码  收藏代码
    1. for(Path shortestPath: findShortestPath(aa, ab)) {    
    2.             System.out.println(shortestPath.toString());    
    3. }  
     Traversal.expanderForTypes用来定义遍历的深度和节点关系的出入度。
    Dijkstra解决有向图中任意两个顶点之间的最短路径问题。
    Java代码  收藏代码
    1. PathFinder<WeightedPath> finder = GraphAlgoFactory.dijkstra(  
    2.         Traversal.expanderForTypes( ExampleTypes.MY_TYPE, Direction.BOTH ), "cost" );  
    3.    
    4. WeightedPath path = finder.findSinglePath( nodeA, nodeB );  
    5. path.weight();  

     使用 A*算法是解决静态路网中求解最短路最有效的方法。

    Java代码  收藏代码
    1. Node nodeA = createNode( "name""A""x", 0d, "y", 0d );  
    2. Node nodeB = createNode( "name""B""x", 7d, "y", 0d );  
    3. Node nodeC = createNode( "name""C""x", 2d, "y", 1d );  
    4. Relationship relAB = createRelationship( nodeA, nodeC, "length", 2d );  
    5. Relationship relBC = createRelationship( nodeC, nodeB, "length", 3d );  
    6. Relationship relAC = createRelationship( nodeA, nodeB, "length", 10d );  
    7.    
    8. EstimateEvaluator<Double> estimateEvaluator = new EstimateEvaluator<Double>()  
    9. {  
    10.     public Double getCost( final Node node, final Node goal )  
    11.     {  
    12.         double dx = (Double) node.getProperty( "x" ) - (Double) goal.getProperty( "x" );  
    13.         double dy = (Double) node.getProperty( "y" ) - (Double) goal.getProperty( "y" );  
    14.         double result = Math.sqrt( Math.pow( dx, 2 ) + Math.pow( dy, 2 ) );  
    15.         return result;  
    16.     }  
    17. };  
    18. PathFinder<WeightedPath> astar = GraphAlgoFactory.aStar(  
    19.         Traversal.expanderForAllTypes(),  
    20.         CommonEvaluators.doubleCostEvaluator( "length" ), estimateEvaluator );  
    21. WeightedPath path = astar.findSinglePath( nodeA, nodeB );  

     

  • 相关阅读:
    VS 2010 C#入门操作小技巧
    spring-data-jpa 多数据源
    Spring--3.Spring的单元测试
    Spring--5.IOC总结
    Spring--4.实验23.IOC容器的测试泛型依赖注入*
    Spring--2.Spring之IOC--IOC容器的22个实验(3)
    Spring--2.Spring之IOC--IOC容器的22个实验(2)
    Spring--2.Spring之IOC--IOC容器的22个实验(1)
    Spring--2.Spring之IOC--了解IOC容器
    Spring--1.了解Spring
  • 原文地址:https://www.cnblogs.com/jpfss/p/11280898.html
Copyright © 2011-2022 走看看