Java 使用neo4j搜索强连通组件

Java 使用neo4j搜索强连通组件,java,algorithm,neo4j,Java,Algorithm,Neo4j,我正在尝试使用neo4j实现SCC算法来存储图形 以下是我对DFS的实现: void dfs(GraphDatabaseService g, Node node, long counter) { Transaction tx = g.beginTx(); node.setProperty("explored", true); tx.success(); tx.finish(); System.out.println("Exporing node " +

我正在尝试使用neo4j实现SCC算法来存储图形

以下是我对DFS的实现:

void dfs(GraphDatabaseService g, Node node, long counter) {

    Transaction tx = g.beginTx();
    node.setProperty("explored", true);
    tx.success();
    tx.finish();
    System.out.println("Exporing node " + node.getProperty("name") + "with depth " + counter);

    Iterator<Relationship> it = node.getRelationships(Direction.OUTGOING, RelTypes.KNOWS).iterator();
    while (it.hasNext()) {
        Node end = it.next().getEndNode();
        if (!(boolean) end.getProperty("explored"))
            dfs(g, end, ++counter);
    }  
}
void dfs(GraphDatabaseService g、节点节点、长计数器){
事务tx=g.beginTx();
node.setProperty(“explored”,true);
成功();
tx.finish();
System.out.println(“Exporing节点”+节点.getProperty(“名称”)+”和深度“+计数器);
Iterator it=node.getRelationships(Direction.outing,RelTypes.KNOWS).Iterator();
while(it.hasNext()){
Node end=it.next().getEndNode();
if(!(布尔)end.getProperty(“explored”))
dfs(g,end,++计数器);
}  
}
它抛出堆栈溢出错误。很明显的原因是递归的深度太大了。
但是我的代码可能有问题?

没有必要编写自己的递归DFS,因为Neo4j提供了现成的功能。我将按照以下方式重写您的方法:

void dfs(GraphDatabaseService g, Node node) {

    //neo4j provided traversal API
    TraversalDescription traversalDescription = new TraversalDescriptionImpl()
            .depthFirst()
            .relationships(RelTypes.KNOWS, Direction.OUTGOING)
            .uniqueness(Uniqueness.NODE_GLOBAL);

    Iterable<Node> nodesInComponent = traversalDescription.traverse(node).nodes();

    //uses GraphAware to save some lines of code
    new IterableInputBatchTransactionExecutor<>(g, 1000, nodesInComponent, new UnitOfWork<Node>() {
        @Override
        public void execute(GraphDatabaseService database, Node input) {
            System.out.println("Exploring node " + input.getProperty("name"));
            if (!(boolean) input.getProperty("explored", false)) {
                input.setProperty("explored", true);
            }
        }
    }).execute();
}
void dfs(GraphDatabaseService g,节点){
//neo4j提供了遍历API
TraversalDescription TraversalDescription=新的TraversalDescriptionImpl()
.depthFirst()
.关系(RelTypes.KNOWS、Direction.OUTGOING)
.唯一性(唯一性.节点\全局);
Iterable nodesInComponent=traversalDescription.traverse(node.nodes();
//使用GraphAware保存一些代码行
新的IterableInputBatchTransactionExecutor(g,1000,nodesInComponent,新的UnitOfWork(){
@凌驾
public void execute(GraphDatabaseService数据库,节点输入){
System.out.println(“探索节点”+input.getProperty(“名称”);
if(!(布尔)input.getProperty(“explored”,false)){
input.setProperty(“已探索”,真);
}
}
}).execute();
}
前四行使用纯neo4japi并检索一个lazy-iterable,以获得所需的节点

出于性能原因,剩余的行以1000个为一批写入“explored”属性,而不是在单独的事务中写入。对于brewity来说,使用了这个框架(免责声明:我是它的作者),但是它可以用几行纯Neo4j代码来编写


我尝试了10000个节点(单个连接的组件),花了大约26秒。

感谢您的回答。实际上,我已经解决了将图表示为节点列表的问题,每个顶点都知道列表中相邻顶点的位置。这节省了我的记忆。但给了我另一个stackoverflow例外。我通过在eclipse中增加java堆栈解决了这个问题。但正确的方法是,我认为还是使用一些图形数据库。我知道neo4j中的dfs,但我想自己在教育方面实现它。