获取两条Neo4j路径中的公共节点序列

时间:2020-06-09 14:59:36

标签: neo4j cypher

例如,在Neo4j中,我们有以下旅行路线:

汤姆:纽约->莫斯科->柏林->巴黎->孟买->开罗->里约->阿姆斯特丹->纳什维尔

玛丽:马德里->纽约->莫斯科->柏林->孟买->开罗->纽约->纳什维尔->多伦多

鲍勃:纽约->纳什维尔->阿姆斯特丹->里约->开罗->孟买->巴黎->柏林->莫斯科

现在,我需要获得与汤姆的路线最相似的旅行路线。相似性是指允许以相同顺序访问的常见城市的数量,而在两者之间跳过城市。

预期结果:

汤姆和玛丽的常用路线:纽约->莫斯科->柏林->孟买->开罗->纳什维尔=> 相似度= 6

汤姆和鲍勃的常用路线:纽约->纳什维尔(也是纽约->阿姆斯特丹和其他路径)=> 相似度= 2

注意:即使汤姆和鲍勃也有9个共同的城市,但它们的排列顺序不同,因此不算相似性!

Neo4j是否有可能获得这种相似性?

我将能够读取所有路径,然后在Neo4j之外比较它们。但是最好使用Neo4j来做到这一点,因为它会更优雅并且可能更快。


已添加:

我当前的算法是一个相似度矩阵,我在x轴上有一条路径,在y轴上有另一条路径。 x和y之间的每次匹配都会导致该匹配右侧下方所有值的增加。换句话说,矩阵中的每个值都代表单元格之前公共路径的计数。

增加值的条件是该值尚未更大。如果存在多个公用路径,则可能会发生这种情况,在这种情况下,必须赢得最长的路径。

上述示例矩阵的两个示例: enter image description here

完整的Java代码:

public static int getLongestCommonWordsInSequence(List<String> yList, List<String> xList) {
    // right = X, left = Y
    // Need dimension +1, because matches-count is incremented not on match point, but on next indexes
    int[][] matrix = new int[xList.size() + 1][yList.size() + 1];

    // Iterate y
    for (int y = 0; y < yList.size(); y++) {
        // Iterate x
        for (int x = 0; x < xList.size(); x++) {
            // Check if y = x
            if (yList.get(y).equals(xList.get(x))) {
                // Increment the count
                int newCount = matrix[x][y] + 1;
                // Update all counts that are on right side AND below the current match
                for (int _x = x + 1; _x <= xList.size(); _x++) {
                    for (int _y = y + 1; _y <= yList.size(); _y++) {
                        // Update only if value is < newCount
                        if (matrix[_x][_y] < newCount) {
                            matrix[_x][_y] = newCount;
                        }
                    }
                }
            }
        }
    }

    return matrix[matrix.length - 1][matrix[matrix.length - 1].length - 1];
}

已添加

这是我的Java代码,用于创建单次旅程的数据。这只是实验性的。如果有优势,我将对其进行扩展或创建任何其他结构。

Node journeyNode = graphDb.createNode(Label.label("Journey"));
for (Destination destination : journey.destinations) {
    Node destinationNode = graphDb.createNode(Label.label("Destination"));
    destinationNode.setProperty("name", destination.name);
    journey.createRelationshipTo(destinationNode, RelationshipType.withName("Destination"));
}

0 个答案:

没有答案