Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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
Algorithm 纯函数图连通性_Algorithm_Scala_Functional Programming - Fatal编程技术网

Algorithm 纯函数图连通性

Algorithm 纯函数图连通性,algorithm,scala,functional-programming,Algorithm,Scala,Functional Programming,我试图更好地理解函数式编程,并决定实现一些经典的图算法。我已经通过将BFS循环包装到尾部递归函数中实现了连接性,但这段代码看起来并不比命令式代码好多少。有没有更好的方法来实现它(使用来理解、单子等等) 顺便说一句,使用递归DFS看起来更好一些 def reachableDfs(v: Int): Seq[Boolean] = reachableDfs(v, Vector.fill(n)(false)) private def reachableDfs(v: Int, visited: S

我试图更好地理解函数式编程,并决定实现一些经典的图算法。我已经通过将BFS循环包装到尾部递归函数中实现了连接性,但这段代码看起来并不比命令式代码好多少。有没有更好的方法来实现它(使用
来理解、单子等等)

顺便说一句,使用递归DFS看起来更好一些

  def reachableDfs(v: Int): Seq[Boolean] = reachableDfs(v, Vector.fill(n)(false))

  private def reachableDfs(v: Int, visited: Seq[Boolean]) : Seq[Boolean] = {
    val newV = visited.updated(v, true)
    adj(v).filterNot{x => newV(x)}.foldLeft(newV){(acc, x) => reachableDfs(x, acc)}
  }

您可以使用
Set
操作来表达这一点,尽管这可能效率较低:

object Graph {
  def apply(n: Int) = new Graph(n, Vector.fill(n)(Set.empty))
}

class Graph private (val n: Int, val adj: IndexedSeq[Set[Int]]) {
  def addEdge(u: Int, v: Int) = {
    new Graph(n, adj.updated(u, adj(u) + v).updated(v, adj(v) + u))
  }

 def connected = {
  @tailrec
  def connectedIter(q: Queue[Int], visited: Set[Int]): Boolean = {
    if (q.isEmpty) visited.size == n else {
      val (v, newq) = q.dequeue
      connectedIter(newq enqueue (adj(v) -- visited), visited ++ adj(v))
    }
  }

 connectedIter(Queue(0), Set.empty)
 }
}

您可以使用
Set
操作来表达这一点,尽管这可能效率较低:

object Graph {
  def apply(n: Int) = new Graph(n, Vector.fill(n)(Set.empty))
}

class Graph private (val n: Int, val adj: IndexedSeq[Set[Int]]) {
  def addEdge(u: Int, v: Int) = {
    new Graph(n, adj.updated(u, adj(u) + v).updated(v, adj(v) + u))
  }

 def connected = {
  @tailrec
  def connectedIter(q: Queue[Int], visited: Set[Int]): Boolean = {
    if (q.isEmpty) visited.size == n else {
      val (v, newq) = q.dequeue
      connectedIter(newq enqueue (adj(v) -- visited), visited ++ adj(v))
    }
  }

 connectedIter(Queue(0), Set.empty)
 }
}

对于图形数据类型,您可以尝试另一种更实用的方法:


马丁·埃尔维格。2001归纳图和函数图算法。J.Funct。节目。11、5(2001年9月),467-492。DOI=10.1017/S0956796801004075

对于图形数据类型,您可以尝试另一种更实用的方法:

马丁·埃尔维格。2001归纳图和函数图算法。J.Funct。节目。11、5(2001年9月),467-492。DOI=10.1017/S0956796801004075