【问题标题】:trouble maintaining the integrity of the data structure in a graph algorithm in a functional way难以以功能方式维护图算法中数据结构的完整性
【发布时间】:2016-08-03 04:12:11
【问题描述】:

我正在尝试解决来自 UVA 在线法官网站的问题,特别是 539 我需要使用 DFS 来找到最长的路径,我可以强制解决它,但我想在使用 scala 的更实用的惯用方式,问题是当算法从分支返回时,数据结构不会更新以用于其他分支,不想使用 vars,也不想使用副作用,这是我的代码:

type Vertex=Int

type Graph = Map[Vertex,Set[Vertex]]

def DFS(start: Vertex, g: Graph): Int = {

  def loop(v: Vertex, visited: List[Vertex], size: Int = 0): Int = {

  val neighbours: List[Vertex] = ( g(v) filterNot visited.contains ).toList
   if (neighbours == Nil) size
   else {
  ( for (elem <- neighbours) yield loop(elem, v :: visited, size + 1) ).max }
    }
loop(start, List())
}

【问题讨论】:

  • 看起来您需要将visitedmax 一起返回并使用foldLeft 而不是for 将状态传递给下一个loop 并在折叠后返回。
  • 你想要 foldLeft 这样的东西传递修改后的visited吗?编辑:嘿,@VictorMoroz,快点!

标签: algorithm scala data-structures functional-programming depth-first-search


【解决方案1】:

您需要存储路径,而不是访问 Set 中的 Vertex(比包含操作中的 List 性能更好)。你也应该从所有的顶点开始尝试这个。检查这个:

type Vertex = Int

type Graph = Map[Vertex, Set[Vertex]]

def DFS(g: Graph): Int = {

  def loop(current: Vertex, visited: Set[(Vertex, Vertex)]): Int = {
    val neighbours = g(current).filterNot(contains(visited, current, _))
    if (neighbours.isEmpty)
      visited.size
    else {
      (for {
        elem <- g(current).filterNot(contains(visited, current, _))
      } yield (loop(elem, add(visited, current, elem)))).max
    }
  }

  (for {
    elem <- g.keys
  } yield (loop(elem, Set()))).max
}

def add(set:Set[(Vertex,Vertex)], v1:Vertex, v2:Vertex): Set[(Vertex,Vertex)] =
  if(v1 < v2) add(set, v2,v1) else set.+((v1,v2))
def contains(set:Set[(Vertex,Vertex)], v1:Vertex, v2:Vertex):Boolean =
  if(v1 < v2) contains(set, v2,v1) else set.contains((v1,v2))

【讨论】:

    猜你喜欢
    • 2020-08-04
    • 2017-03-05
    • 2011-06-15
    • 2017-09-13
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2021-09-21
    相关资源
    最近更新 更多