ruby-on-rails - Neo4j.rb 和 Ruby On Rails 的最短加权路径
问题描述
我正在尝试计算两个节点之间的最短加权路径。这是我的用户类:
class User
include Neo4j::ActiveNode
property :name, type: String
has_many :both, :friends, rel_class: :Friendship, model_class: :User
end
用户是节点,它们之间的关系是:
class Friendship
include Neo4j::ActiveRel
before_save :set_weight
from_class :User
to_class :User
type 'FRIENDSHIP'
property :weight
def set_weight
...
end
属性权重是两个节点之间的半正弦距离值。
我想出了如何编写查询以获取将 user_a 与 user_b 连接的所有路径:
all_paths = a.query_as(:a).match_nodes(b: b).match('p=((a)-[*]-(b))').pluck(:p)
而且我确信我可以将方法链接到该查询以根据权重获得最短路径,但我找不到正确的 Cypher 语法,所以我结束了迭代每条路径并计算每条路径的总权重以获得最短路径一:
def shortest_weighted_path(start_user_id, end_user_id)
a = User.find(start_user_id)
b = User.find(end_user_id)
all_paths = a.query_as(:a).match_nodes(b: b).match('p=((a)-[*]-(b))').pluck(:p)
paths_and_weights = {}
all_paths.each_with_index do |path, index|
total_weight = 0
path.relationships.each { |relationship| total_weight = total_weight + relationship.properties[:weight] }
paths_and_weights[index] = total_weight
end
paths_and_weights = paths_and_weights.sort_by {|_key, value| value}.to_h
shortest_path_index = paths_and_weights.keys.first
shortest_path = all_paths[shortest_path_index]
nodes_in_path = []
shortest_path.nodes.each { |node| nodes_in_path << node.properties[:uuid] }
nodes_in_path
end
谷歌搜索我发现的更多内容以及如何使用 Cypher 计算最短路径的示例:
START startNode=node:node_auto_index(name={startNode}),
endNode=node:node_auto_index(name={endNode})
MATCH p=(startNode)-[:CONNECTED_TO*1..4]->(endNode)
RETURN p AS shortestPath,
reduce(weight=0, r in relationships(p) : weight+r.weight) AS totalWeight
ORDER BY totalWeight ASC
LIMIT 1
所以我的问题是:如何根据我的 User-Friendship 示例为 Neo4j.rb 编写此查询?
解决方案
推荐阅读
- unity3d - Unity:我可以在运行时更改网格对撞机的形状吗?
- batch-file - 自动备份的批处理文件
- django - 如何在使用 django、django-rest-auth 制作的网站中处理令牌密钥并做出反应?
- html - 我在为 svg 图片制作动画时遇到问题
- jquery - 元素不使用 CSS 隐藏
- c# - 从小黄瓜功能文件中的存储过程验证 GETUTCDATE()
- c# - Puppeteersharp 的访问被拒绝
- vue.js - 如何使用 ES6 模块系统在根实例中注册两个组件?
- iis - 上传图片但大小为 0 KB
- docker - 跨 docker 容器共享内存会限制整体内存使用吗?在 Windows 上可以吗?