gpt4 book ai didi

neo4j - Gremlin 中是否可以计算树形图之间的差异?

转载 作者:行者123 更新时间:2023-12-02 04:11:26 32 4
gpt4 key购买 nike

我有两个图,它们实际上是树(即单根,无循环)。它们之间的差别很小:其中一个有叶子,而另一个则没有。有没有办法使用 Gremlin 或其他可能的图形查询语言(例如 Cypher)来返回表示这两棵树之间差异的图形?

点示例:

graph A {
a -- b -- c;
}

graph B {
a -- b -- c;
b -- d;
}

graph C = graph B - graph A : // <-- How do I do that?

graph C {
b -- d;
}

最佳答案

下面的junit测试是解决这个问题的一个简单可行的解决方案。请参阅算法的注释。有很多更好的方法可以做到这一点,但这只是为了表明有一个解决方案。

package com.graph.test;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
import org.junit.Test;

/**
* https://stackoverflow.com/questions/38786038/is-it-possible-to-calculate-difference-between-tree-graphs-in-gremlin
* https://stackoverflow.com/questions/16553343/diff-for-directed-acyclic-graphs
* @author wz
*
* Algorithm:
* Step one: Intersect all vertices and edges of a and b
* Step two: Remove all edges that are the same in a and b
* Step tree: Remove all non connected vertices
*
* Step three is not implemented here and one and two are very inefficient. This
* is just to show the principle and have a viable solution
*
*/
public class TestGraphDiff {

public static final String SORTKEY="sortKey";
public static final String LINK="link";

public Graph getGraph() {
Graph g = TinkerGraph.open();
Vertex a = g.addVertex("a");
Vertex b = g.addVertex("b");
Vertex c = g.addVertex("c");
b.addEdge(LINK,a);
c.addEdge(LINK, b);
return g;
}

@Test
public void testGraphDiff() {
Graph A=getGraph();
Graph B=getGraph();
Vertex d = B.addVertex("d");
Vertex b= B.traversal().V().hasLabel("b").next();
d.addEdge(LINK, b);
Graph C=diff(A,B);
// there should be one edge left
assertEquals(1,C.traversal().E().count().next().longValue());
// there should be two vertices left
assertEquals(2,C.traversal().V().count().next().longValue());
// the left over edge should be "b-d"
assertEquals("b-d",C.traversal().E().next().property(SORTKEY).value().toString());

}

/**
* add a sort key to the given edge
* @param e
* @return - the sort key
*/
private String addSortKey(Edge e) {
String sortKey=e.inVertex().label()+"-"+e.outVertex().label();
e.property(SORTKEY,sortKey);
return sortKey;
}

/**
* get the difference of two Graphs
* @param a
* @param b
* @return
*/
public Graph diff(Graph a, Graph b) {
// step one: intersect both graphs
Graph c= TinkerGraph.open();
// copy all vertices of a
a.traversal().V().forEachRemaining(v->c.addVertex(v.label()));
// copy all edges of a
a.traversal().E().forEachRemaining(e->{
Vertex iva = e.inVertex();
Vertex ova = e.outVertex();
Vertex ivc=c.traversal().V().hasLabel(iva.label()).next();
Vertex ovc=c.traversal().V().hasLabel(ova.label()).next();
addSortKey(e);
Edge edge=ovc.addEdge(e.label(), ivc);
addSortKey(edge);
});
// copy all vertices of b that are not yet in c
b.traversal().V().forEachRemaining(v->{
if (c.traversal().V().hasLabel(v.label()).count().next().longValue()==0) {
c.addVertex(v.label());
}
// copy all edges of b that are not yet in c
b.traversal().E().forEachRemaining(e->{
Vertex ivb = e.inVertex();
Vertex ovb = e.outVertex();
Vertex ivc=c.traversal().V().hasLabel(ivb.label()).next();
Vertex ovc=c.traversal().V().hasLabel(ovb.label()).next();
String sortKey=addSortKey(e);
if (!c.traversal().E().has(SORTKEY,sortKey).hasNext()) {
Edge edge = ovc.addEdge(e.label(), ivc);
addSortKey(edge);
}
});
});
// step two: remove all edges that are "the same" in both graphs
// inefficient version - would be much quicker with sorted lists
// of edges ...
c.traversal().E().forEachRemaining(e->{
String sortKey=e.property(SORTKEY).value().toString();
if (a.traversal().E().has(SORTKEY, sortKey).hasNext() &&
c.traversal().E().has(SORTKEY, sortKey).hasNext()) {
e.remove();
}
});
// step three remove all "unconnected" vertices
c.traversal().V().forEachRemaining(v->{
if (!v.edges(Direction.BOTH).hasNext())
v.remove();
});
return c;
}

}

关于neo4j - Gremlin 中是否可以计算树形图之间的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38786038/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com