Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:递归地构建图形中的所有路径?_Scala_Recursion_Graph - Fatal编程技术网

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

Scala:递归地构建图形中的所有路径?,scala,recursion,graph,Scala,Recursion,Graph,尝试使用以下算法为定义为边映射的udirected graph构建所有现有路径: 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 St

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

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")
作为输出,我需要获得所有路径的列表,其中每个路径都是相邻边的列表,如下所示:

  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)))

为什么会这样?

那么,嗯-?如果你想坚持递归,a应该做这项工作。这里有一篇关于谈论它的帖子。现在,去实施它吧!如果你被困在任何地方,在这里发布作为编辑。