本次主要学习图数据库中常用到的一些算法,以及如何在Neo4j
中调用,所以这一篇偏实战,每个算法的原理就简单的提一下。
1. 图数据库中常用的算法
PathFinding & Search
一般用来发现Nodes之间的最短路径,常用算法有如下几种
- Dijkstra - 边不能为负值
- Folyd - 边可以为负值,有向图、无向图
- Bellman-Ford
- SPFA
Centrality
一般用来计算这个图中节点的中心性,用来发现比较重要的那些Nodes。这些中心性可以有很多种,比如
- Degree Centrality - 度中心性
- Weighted Degree Centrality - 加权度中心性
- Betweenness Centrality - 介数中心性
- Closeness Centrality - 紧度中心性
Community Detection
用于发现这个图中局部联系比较紧密的Nodes,类似我们学过的聚类算法。
- Strongly Connected Components
- Weakly Connected Components (Union Find)
- Label Propagation
- Lovain Modularity
- Triangle Count and Average Clustering Coefficient
2. 路径搜索算法
Shortest Path
1234567
MATCH (start:Loc{name:"A"}), (end:Loc{name:"F"})CALL algo.shortestPath.stream(start, end, "cost")YIELD nodeId, costMATCH (other:Loc) WHERE id(other) = nodeIdRETURN other.name AS name, cost
Single Source Shortest Path
123456
MATCH (n:Loc {name:"A"})CALL algo.shortestPath.deltaStepping.stream(n, "cost", 3.0YIELD nodeId, distanceMATCH (destination) WHERE id(destination) = nodeIdRETURN destination.name AS destination, distance
All Pairs Shortest Path
1234567891011
CALL algo.allShortestPaths.stream("cost",{nodeQuery:"Loc",defaultValue:1.0})YIELD sourceNodeId, targetNodeId, distanceWITH sourceNodeId, targetNodeId, distanceWHERE algo.isFinite(distance) = trueMATCH (source:Loc) WHERE id(source) = sourceNodeIdMATCH (target:Loc) WHERE id(target) = targetNodeIdWITH source, target, distance WHERE source <> targetRETURN source.name AS source, target.name AS target, distanceORDER BY distance DESCLIMIT 10
Minimum Weight Spanning Tree
12345
MATCH (n:Place {id:"D"})CALL algo.spanningTree.minimum("Place", "LINK", "cost", id(n), {write:true, writeProperty:"MINST"})YIELD loadMillis, computeMillis, writeMillis, effectiveNodeCountRETURN loadMillis, computeMillis, writeMillis, effectiveNodeCount;
CASE
123456789101112131415
MERGE (a:Loc {name:"A"})MERGE (b:Loc {name:"B"})MERGE (c:Loc {name:"C"})MERGE (d:Loc {name:"D"})MERGE (e:Loc {name:"E"})MERGE (f:Loc {name:"F"})MERGE (a)-[:ROAD {cost:50}]->(b)MERGE (a)-[:ROAD {cost:50}]->(c)MERGE (a)-[:ROAD {cost:100}]->(d)MERGE (b)-[:ROAD {cost:40}]->(d)MERGE (c)-[:ROAD {cost:40}]->(d)MERGE (c)-[:ROAD {cost:80}]->(e)MERGE (d)-[:ROAD {cost:30}]->(e)MERGE (d)-[:ROAD {cost:80}]->(f)MERGE (e)-[:ROAD {cost:40}]->(f);
3. 中心性算法
PageRank
123456
CALL algo.pageRank.stream("Page", "LINKS",{iterations:20})YIELD nodeId, scoreMATCH (node) WHERE id(node) = nodeIdRETURN node.name AS page,scoreORDER BY score DESC
Degree Centrality
Betweenness Centrality
12345
CALL algo.betweenness.stream("User", "MANAGES", {direction:"out"})YIELD nodeId, centralityMATCH (user:User) WHERE id(user) = nodeIdRETURN user.id AS user,centralityORDER BY centrality DESC;
Closeness Centrality
123456
CALL algo.closeness.stream("Node", "LINK")YIELD nodeId, centralityMATCH (n:Node) WHERE id(n) = nodeIdRETURN n.id AS node, centralityORDER BY centrality DESCLIMIT 20;
CASE
12345678910111213141516171819202122
MERGE (home:Page {name:"Home"})MERGE (about:Page {name:"About"})MERGE (product:Page {name:"Product"})MERGE (links:Page {name:"Links"})MERGE (a:Page {name:"Site A"})MERGE (b:Page {name:"Site B"})MERGE (c:Page {name:"Site C"})MERGE (d:Page {name:"Site D"})MERGE (home)-[:LINKS]->(about)MERGE (about)-[:LINKS]->(home)MERGE (product)-[:LINKS]->(home)MERGE (home)-[:LINKS]->(product)MERGE (links)-[:LINKS]->(home)MERGE (home)-[:LINKS]->(links)MERGE (links)-[:LINKS]->(a)MERGE (a)-[:LINKS]->(home)MERGE (links)-[:LINKS]->(b)MERGE (b)-[:LINKS]->(home)MERGE (links)-[:LINKS]->(c)MERGE (c)-[:LINKS]->(home)MERGE (links)-[:LINKS]->(d)MERGE (d)-[:LINKS]->(home)
4. 社区发现算法
Strongly Connected Components
1234
CALL algo.scc.stream("User","FOLLOWS")YIELD nodeId, partitionMATCH (u:User) WHERE id(u) = nodeIdRETURN u.id AS name, partition
Weakly Connected Components (Union Find)
1234
CALL algo.unionFind.stream("User", "FRIEND", {})YIELD nodeId,setIdMATCH (u:User) WHERE id(u) = nodeIdRETURN u.id AS user, setId
Label Propagation
12
CALL algo.labelPropagation.stream("User", "FOLLOWS", {direction: "OUTGOING", iterations: 10})
Lovain Modularity
12345
CALL algo.louvain.stream("User", "FRIEND", {})YIELD nodeId, communityMATCH (user:User) WHERE id(user) = nodeIdRETURN user.id AS user, communityORDER BY community;
Triangle Count and Average Clustering Coefficient
123456
CALL algo.triangle.stream("Person","KNOWS")YIELD nodeA,nodeB,nodeCMATCH (a:Person) WHERE id(a) = nodeAMATCH (b:Person) WHERE id(b) = nodeBMATCH (c:Person) WHERE id(c) = nodeCRETURN a.id AS nodeA, b.id AS nodeB, c.id AS node
5. References
- Neo4j in deep
- 官方文档:Comprehensive-Guide-to-Graph-Algorithms-in-Neo4j-ebook