查找从顶点开始的所有路径,直到没有其他直接后继为止

时间:2018-10-10 08:52:37

标签: scala graph

我正在开发一个将工作流程模拟为图形形式的应用程序。我正在使用Scala-Graph来实现这一目标,我想找出所有可能的直接边缘路径,直到没有其他直接后继路径为止。

例如,对于此图:

val z = Graph(1~>2, 2~>3, 2~>4, 3~>4, 5~>4)

我想找出从顶点1 到没有更多直接连接的顶点的所有可能路径。因此,逻辑输出应类似于

1~>2~>3~>4
2~>4

主要问题:

  1. scala-graph是否提供了本地API来实现这一目标?
  2. 我应该编写客户遍历方法吗?

关于问题2,我已经编写了代码的初始版本来实现它,但是它总是返回一个空值;(我也希望对此有一些反馈

def getAllPaths(g: z.NodeT, paths: List[Any]): Unit = {
  val directs = g.diSuccessors.toList
  if (directs.length == 0) {
    paths
  } else {
    getAllPaths(directs(0), paths :+ directs(0))
  }
}

val accum = List[Any]()

println(getAllPaths(z.get(1), accum)) // nothing

这样的想法是,通过将起始点传递给方法getAllPaths,它将根据diSuccessors遍历并在其长度为0时停止。示例图z的理想输出是

[
  [1~2, 2~3, 3~4]
  [2~4]
]

为什么自定义方法返回一个空列表?

1 个答案:

答案 0 :(得分:0)

所以我已经写了这篇文章来实现它

// Example graph 1
val z = Graph(1~>2, 2~>3, 2~>4, 3~>4, 5~>4)
// Example graph 2
val z1 = Graph(1~>2, 2~>3, 2~>4, 3~>4, 4~>6, 6~>7, 5~>4)

def getAllPaths(g: z1.NodeT, paths: List[z1.NodeT]): List[Any] = {
  val directs = g.diSuccessors.toList

      if (directs.length == 0) {
          // No more direct successor left, return the array itself
        paths
      } else if (directs.length == 1) {
        // Node with single direction, simply returns itself
        if (paths.length == 0) {
          // appends g itself and its direct successor for the first iteration
          getAllPaths(directs(0), paths :+ g :+ directs(0))
        } else {
          // Appends only the direct successor
          getAllPaths(directs(0), paths :+ directs(0))
        }
      } else {
        directs.map(d => {
          getAllPaths(d, paths :+ d)
        })
      }
    }
val accum = List[z1.NodeT]()

println(getAllPaths(z1.get(1), accum))

// Results in: List(List(1, 2, 3, 4, 6, 7), List(1, 2, 4, 6, 7))

把它留在这里,以防万一有兴趣解决同样的问题!

也请帮助我写得更优美;)..我仍然是Scala的初学者

后续问题:

  • 如何通过不经过上面示例的变量来引用NodeT类型,该变量是通过z1.NodeT访问的?