我需要在距离方面找到给定的两个查询之间的相关性,例如:
Q1(Query1) = Computing
Q2(Query2) = RAM
让我们假设相关性路径是这样的:
计算 - >个人计算机 - >计算机硬件 - >计算机组件 - >随机存取存储器 - > RAM
结果应为5。
现在问题是大多数像FreeBase
这样的图形数据库不支持该功能。唯一的方法是递归地将一个查询与另一个查询进行比较。
问题:有一种简单快捷的方法可以做到这一点,还是有支持此功能的图形数据库?
请注意:这不是一个算法问题,我知道在理论上使用DFS
或BFS
可以轻松实现这一点,但是当涉及到现实时,可能会有一个节点(条目)有1000条边,我不想遍历它。
答案 0 :(得分:0)
首先,为了找到图之间的距离,只需计算从一个节点到另一个节点的边数,然后制定某种量化来找到距离。可以将freebase实体放入图形中,然后计算两个节点之间的边数。
让我们从一个更简单的资源WordNet开始。为简单起见,我们使用NLTK的WordNet API(http://www.nltk.org/)。您可以简单地量化路径相似性(http://www.nltk.org/_modules/nltk/corpus/reader/wordnet.html):
>>> from nltk.corpus import wordnet
>>> from nltk.corpus import wordnet as wn
>>> wn.synsets('computing')
[Synset('computer_science.n.01'), Synset('calculation.n.01'), Synset('calculate.v.01')]
>>> wn.synsets('ram')
[Synset('random-access_memory.n.01'), Synset('aries.n.01'), Synset('aries.n.03'), Synset('ram.n.04'), Synset('ram.n.05'), Synset('ram.v.01'), Synset('force.v.06'), Synset('crash.v.03'), Synset('jam.v.06')]
>>> computing = wn.synsets('computing')[0]
>>> ram = wn.synsets('ram')[0]
>>> computing.path_similarity(ram)
0.058823529411764705
请注意,使用Wordnet可能会导致比解决问题更多的问题; P.见
答案 1 :(得分:0)
您要查找的是图表中两个节点之间的最短路径。如果您的图表未加权,则归结为breadth first search。
我假设您的相关边缘已加权,因此您需要an algorithm like dijkstra。由于您最有可能对所有对最短路径问题感兴趣,因为您可能希望稍后在任何两个节点之间查询最短路径,因此可以使用floyd Warshall algorithm。这将创建一个矩阵,其中包含所有节点对之间的所有最短路径值。
如果您将图表导入neo4j,则可以使用their floyd warshall implementation.请注意,此算法的实现在顶点数量上是立方的。所以它真的取决于你的用例选择上述哪种算法。
我附上了一些示例代码(在neo4j 1.4中),它显示了它是多么容易:
CostEvaluator<Double> costEvaluator = new CostEvaluator<Double>() {
public Double getCost(Relationship relationship, Direction direction) {
return -Math.log((Double) relationship.getProperty(Messages
.getString("RelProperty.Cost")));
}
};
CostAccumulator<Double> costAccumulator = new CostAccumulator<Double>() {
public Double addCosts(Double c1, Double c2) {
// TODO Auto-generated method stub
return c1 + c2;
}
};
Comparator<Double> costComparator = new Comparator<Double>() {
public int compare(Double o1, Double o2) {
// TODO Auto-generated method stub
return o1.compareTo(o2);
}
};
FloydWarshall<Double> fw = new FloydWarshall<Double>(1.0,
Double.MIN_VALUE, Direction.OUTGOING, costEvaluator,
costAccumulator, costComparator, this.currencySet,
this.tradeSet);
fw.reset();
fw.calculate();
然后,您可以使用以下命令查询任何两个节点node1和node2的图形:
fw.getCost(node1, node2)
通过使用遍历框架或简单的cypher query ,btw广度优先搜索也可以在neo4j中轻松实现与您的查询完全匹配