图从单个顶点遍历到 N 个顶点

Graph Traversing From Single Vertex to N Vertices

我有以下示例图:

我得到根节点 LVMap<Vertex, Vertex> 其中包含:

Map = {<A_T, A_V>, <B_T, B_V>, <C_T, C_V>, ... <N_T, N_V>}

我正在尝试创建一个从 LV 开始并到达每个叶子 A_T, A_V, B_T, B_V, C_T, C_V 的遍历。最初我想这样构建我的遍历:

GraphTraversal traversal = graph().traversal().V(LV.id());
traversal.and(out().hasId(A_T.id(), A_V.id()),
              out().hasId(B_T.id(), B_V.id()),
              out().hasId(C_T.id(), C_V.id()),
              ...
              out().hasId(N_T.id(), N_V.id()));

问题是 .and(Object . . .) 不能动态添加(据我所知)并且 N 可以是任何数字所以有一次我想要:

traversal.and(out().hasId(A_T.id(), A_V.id()),
              out().hasId(B_T.id(), B_V.id());

在另一个我想要的:

traversal.and(out().hasId(A_T.id(), A_V.id()),
              out().hasId(B_T.id(), B_V.id()),
              out().hasId(C_T.id(), C_V.id()),
              out().hasId(D_T.id(), D_V.id()));

此遍历应该用作 LVMap 中所有组件之间的现有结构的验证。

有什么方法可以实现这个功能吗?

解决了。一如既往,我将 post 我的解决方案适用于可能遇到类似问题的任何人。

问题是 and(...) 方法可以采用多个参数。所以我可以动态地构建最终的遍历。具体我可以做到以下几点。

public void awesomeTraversal(Vertex LV, Map<Vertex, Vertex> vertexMap){
    GraphTraversal<Vertex, Vertex> traversal = graph.traversal().V(LV.id()); //Start at LV

    ArrayList<GraphTraversal> innerTraversals = new ArrayList<>();
    for(Map.Entry<Vertex, Vertex> v : vertexMap){
        // Check you can go to X_T
        innerTraversals.add(__.out().out().is(entry.getKey())); 
        //Check you can go to X_V
        innerTraversals.add(__.out().out().is(entry.getValue()));
    }
    //Filter via and.
    traversal = traversal.and(innerTraversal.toArray(GraphTraversal[innerTraversals.size()]));
    if(traversal.hasNext()){
        System.out.println("Found structure");
    } else {
        System.out.println("No structure");
    }
}

这似乎对我有用。欢迎任何改进。

让我们先创建您的示例图表和地图:

graph = TinkerGraph.open()
names = ["LV",
         "A_C","A_T","A_V",
         "B_C","B_T","B_V",
         "C_C","C_T","C_V"]

vertices = names.collectEntries { def name ->
  [name, graph.addVertex("name", name)]
}

vertices["LV"].addEdge("link", vertices["A_C"])
vertices["LV"].addEdge("link", vertices["B_C"])
vertices["LV"].addEdge("link", vertices["C_C"])
vertices["A_C"].addEdge("link", vertices["A_T"])
vertices["A_C"].addEdge("link", vertices["A_V"])
vertices["B_C"].addEdge("link", vertices["B_T"])
vertices["B_C"].addEdge("link", vertices["B_V"])
vertices["C_C"].addEdge("link", vertices["C_T"])
vertices["C_C"].addEdge("link", vertices["C_V"])

m = [:]
m.put(vertices["A_T"], vertices["A_V"])
m.put(vertices["B_T"], vertices["B_V"])
m.put(vertices["C_T"], vertices["C_V"])

现在,要判断是否可以找到结构,您可以这样做:

leafs = m.keySet() + m.values()

g = graph.traversal()
found = g.V(vertices["LV"]).out().out().fold().
          where(count(local).is(m.size() << 1)).
          not(unfold().is(without(leafs))).hasNext()

这是 Gremlin 控制台中的结果:

gremlin> found = g.V(vertices["LV"]).out().out().fold().
gremlin>           where(count(local).is(m.size() << 1)).
gremlin>           not(unfold().is(without(leafs))).hasNext()
==>true

如果我们向地图添加一些不属于结构的项目:

gremlin> found = g.V(vertices["LV"]).out().out().fold().
gremlin>           where(count(local).is(m.size() << 1)).
gremlin>           not(unfold().is(without(leafs))).hasNext()
==>false