Scala:递归地构建图形中的所有路径?

时间:2014-05-29 16:29:43

标签: scala recursion graph

尝试使用以下算法构建定义为边缘图的udirected图的所有现有路径:

Start: with a given vertice A 
Find an edge (X.A, X.B) or (X.B, X.A), add this edge to path if not already in path
Find all edges Ys for which either (Y.C, Y.B) or (Y.B, Y.C) is true 
For each Ys: A=B, goto Start

提供边缘定义为以下贴图,其中键是由两个顶点组成的元组:

    val edges = Map(
      ("n1", "n2") -> "n1n2",
      ("n1", "n3") -> "n1n3",
      ("n3", "n4") -> "n3n4",
      ("n5", "n1") -> "n5n1",
      ("n5", "n4") -> "n5n4")

作为输出,我需要获得所有路径的列表,其中每个路径都是这样的adjecent边缘列表:

  val allPaths = List(
    List(("n1", "n2") -> "n1n2"),
    List(("n1", "n3") -> "n1n3", ("n3", "n4") -> "n3n4"),
    List(("n5", "n1") -> "n5n1"),
    List(("n5", "n4") -> "n5n4"),
    List(("n2", "n1") -> "n1n2", ("n1", "n3") -> "n1n3", ("n3", "n4") -> "n3n4", ("n5", "n4") -> "n5n4"))
    //...
    //... more pathes to go
}

注意:边缘XY =(x,y) - > " XY"和YX =(y,x) - > " YX"仅作为一个实例存在,可以是XY或YX

到目前为止,我已经设法实现了复制路径边缘的代码,这是错误的,我找不到错误:

object Graph2 {
  type Vertice = String
  type Edge = ((String, String), String)
  type Path = List[((String, String), String)]

  val edges = Map(
    //(("v1", "v2") , "v1v2"),
    (("v1", "v3") , "v1v3"),
    (("v3", "v4") , "v3v4")
    //(("v5", "v1") , "v5v1"),
    //(("v5", "v4") , "v5v4")
    )

  def main(args: Array[String]): Unit = {

    val processedVerticies: Map[Vertice, Vertice] = Map()
    val processedEdges: Map[(Vertice, Vertice), (Vertice, Vertice)] = Map()
    val path: Path = List()
    println(buildPath(path, "v1", processedVerticies, processedEdges))

  }

  /**
   * Builds path from connected by edges vertices starting from given vertice
   * Input: map of edges
   * Output: list of connected edges like:
   List(("n1", "n2") -> "n1n2"),
    List(("n1", "n3") -> "n1n3", ("n3", "n4") -> "n3n4"),
    List(("n5", "n1") -> "n5n1"),
    List(("n5", "n4") -> "n5n4"),
    List(("n2", "n1") -> "n1n2", ("n1", "n3") -> "n1n3", ("n3", "n4") -> "n3n4", ("n5", "n4") -> "n5n4"))
   */
  def buildPath(path: Path,
    vertice: Vertice,
    processedVerticies: Map[Vertice, Vertice],
    processedEdges: Map[(Vertice, Vertice), (Vertice, Vertice)]): List[Path] = {
    println("V: " + vertice + " VM:  " + processedVerticies + " EM: " + processedEdges)
    if (!processedVerticies.contains(vertice)) {
      val edges = children(vertice)
      println("Edges: " + edges)
      val x = edges.map(edge => {
        if (!processedEdges.contains(edge._1)) {
          addToPath(vertice, processedVerticies.++(Map(vertice -> vertice)), processedEdges, path, edge)
        } else {
          println("ALready have edge: "+edge+" Return path:"+path)
          path
        }
      })
      val y = x.toList
      y
    } else {
      List(path)
    }
  }

  def addToPath(
    vertice: Vertice,
    processedVerticies: Map[Vertice, Vertice],
    processedEdges: Map[(Vertice, Vertice), (Vertice, Vertice)],
    path: Path,
    edge: Edge): Path = {

    val newPath: Path = path ::: List(edge)
    val key = edge._1
    val nextVertice = neighbor(vertice, key)

    val x = buildPath (newPath, 
             nextVertice, 
             processedVerticies, 
             processedEdges ++ (Map((vertice, nextVertice) -> (vertice, nextVertice)))
          ).flatten // need define buidPath type 
    x
  }

  def children(vertice: Vertice) = {
    edges.filter(p => (p._1)._1 == vertice || (p._1)._2 == vertice)
  }

  def containsPair(x: (Vertice, Vertice), m: Map[(Vertice, Vertice), (Vertice, Vertice)]): Boolean = {
    m.contains((x._1, x._2)) || m.contains((x._2, x._1))
  }

  def neighbor(vertice: String, key: (String, String)): String = key match {
    case (`vertice`, x) => x
    case (x, `vertice`) => x
  }

}  

运行此结果:

List(List(((v1,v3),v1v3), ((v1,v3),v1v3), ((v3,v4),v3v4)))

为什么?

0 个答案:

没有答案