【问题标题】:Shortest path that has to include certain waypoints必须包含某些航路点的最短路径
【发布时间】:2016-01-20 04:10:16
【问题描述】:

我试图找到连接任意节点集合的最短路径。 start 和 end 都可以是集合中的任何节点,只要它们不相同即可。 标准密码函数 shortestPath() 或 allShortestPaths() 失败,因为它们找到从开始到结束的最短路径并且不包括航点。 以下密码有效,但有更快的方法吗?

//some collection of nodeids, as waypoints the path has to include
match (n) where id(n) IN [24259,11,24647,28333,196] 
with collect(n) as wps

// create possible start en endpoints
unwind wps as wpstart
unwind wps as wpend
with wps,wpstart,wpend where id(wpstart)<id(wpend)

// find paths that include all nodes in wps
match p=((wpstart)-[*..6]-(wpend))
where ALL(n IN wps WHERE n IN nodes(p))

// return  paths, ordered by length
return id(wpstart),id(wpend),length(p) as lp,EXTRACT(n IN nodes(p) | id(n)) order by lp asc

2015 年 10 月 23 日更新: 使用最新的 Neo4j 版本 2.3.0,可以将 shortestPath() 与在评估过程中某处拉入的 WHERE 子句结合起来。然后你会得到一个这样的构造,其中 {wps} 是 nodeIds 的集合。

// unwind the collection to create combinations of all start-end points
UNWIND {wps} AS wpstartid
UNWIND {wps} AS wpendid
WITH wpstartid,wpendid WHERE wpstartid<wpendid

// for each start-end combi,calculate shortestPath() with a WHERE clasue
MATCH (wpstart) WHERE id(wpstart)=wpstartid
MATCH (wpend) WHERE id(wpend)=wpendid
MATCH p=shortestPath((wpstart)-[*..5]-(wpend))
WHERE ALL(id IN {wps}  WHERE id IN EXTRACT(n IN nodes(p) | id(n))   )

//return the shortest of the shortestPath()s
WITH p, size(nodes(p)) as length order by length limit 1
RETURN EXTRACT(n IN nodes(p) | id(n))

这种方法并不总是有效,因为有一个内部优化决定了在哪个阶段应用 WHERE 子句。所以要小心,并准备好在项目的开头回退到更暴力的方法。

【问题讨论】:

  • 您是否有任何提示可以在此处应用,以了解航点可能出现的顺序?或者它们可以按任何顺序发生吗?
  • 我认为“最短路径”概念仅适用于某些已确定的 A 到 B。您提出问题的方式是指任何/所有节点,只要路径通过航路点节点。这个问题公式的问题是,如果通过航点节点不是从 A 到 B 的最短路径怎么办?还是您只想要合法的 shortestPath 也具有包含航点节点的属性的 A/B 对?
  • @FrobberOfBits 您对我的问题的理解是正确的。事实上,它在 Noe4j 上下文中被称为谓词。我需要有通过所有航点的最短路径,顺序无关紧要。从 Neo4j 2.3.0 开始, shortestPath() 函数有一个包含 predicate 的机制,它被考虑在内,但还不完全准确。所以当你有 (a)-[]->(b) 作为直接相关的节点并且你有 (a),(b),(c),(d),(e) 作为航点时,它有时会返回 0 结果,其中较短的航点列表,如 (a),(b),(c),(d) 可能返回 (c),(d),(e),(b),(a)

标签: neo4j cypher shortest-path


【解决方案1】:

这将是一个非常不令人满意的答案,但这里是:

我强烈怀疑您提出的问题可以归结为Hamiltonian Paths 的问题。这是一个经典的图算法问题,结果证明是 NP 完全的。所以实际上,这意味着虽然可以实现这一点,但性能可能会很糟糕。

如果你真的必须实现这一点,我可能会建议不要使用 cypher,而是使用 neo4j 遍历框架构建一些东西。您可以在网上找到至少可以完成其中一部分的示例代码和算法。但更广泛地说,如果您的数据大小大于微不足道,那么这个答案中令人不满意的部分是我可能根本不会这样做。

更好的选择可能是将您的图表分解成较小的子问题,您可以独立工作,或者提出另一种启发式方法,让您接近您想要的,但不是通过这种方法。

【讨论】:

  • 我知道这与刘易斯·汉密尔顿有关 :) 感谢您的指点。关于我们将遇到的性能问题,您很可能是对的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
相关资源
最近更新 更多