BFS是否缺少参数?

时间:2018-09-29 10:34:31

标签: ocaml

我有以下代码在图中执行BFS:

open Queue 


type 'a node = {id: 'a; edges: 'a list}
type 'a graph = 'a node list


let bfs g s = 
    let seen = Array.make (Array.length g) false
    and treated = Queue.create() in 
    Queue.add s treated ; seen.(s) <- true ;
    let rec add_neighbors = function
    |[]                    -> ()
    |t::q when seen.(t)  -> add_neighbors q
    |t::q                  -> Queue.add t treated ; seen.(t) <- true ; add_neighbors q
    in
    try while true do 
      let s = Queue.take treated in 
      print_int s ;
      add_neighbors g.(s)
      done
    with Empty -> ()

问题是我不了解函数bfs的工作方式。首先,我们给出图g和第一个节点s,但是函数add_neighbors为:

let rec add_neighbors = function

这里的问题是该函数正在等待参数,但是我看不到代码在何处将此参数赋予函数add_neighbors

更准确地说。假设我有一个图g,并且我想从节点s开始对该图执行BFS。

因此我调用了函数bfs g s。所以这是函数的作用:

  • 创建一个名为seen的数组,其中所有条目都等于false
  • 创建一个名为treated的队列,在其中添加节点s
  • 我们更新数组s中节点seen的值。因此,在数组seen中,s的值为true
  • 这是我的问题。我们在这里调用一个名为add_neighbors的递归函数,但此函数在这里等待一个参数,但是在这里,我们给该函数提供的参数是什么?算法如何从这里继续?

1 个答案:

答案 0 :(得分:1)

  

该函数执行[创建]一个名为seen […]的数组,[创建]一个名为treated的队列[…],[并更新]节点s的值在seen数组中。
  [然后]我们在这里调用名为add_neighbors的递归函数,但是此函数在这里等待一个参数,但是我们给该函数提供的参数是什么?

否,let rec add_neighbors = function不调用该函数。它使用函数值声明本地add_neighbors,然后允许我们在以下代码块中使用此变量in

  

算法如何从此处继续?

算法执行的下一件事是块

try while true do 
  let s = Queue.take treated in 
  print_int s ;
  add_neighbors g.(s)
  done
with Empty -> ()

在无限循环中,它从treated队列中取出第一个节点,进行打印,然后 then 调用add_neighbors并假定该节点为邻居s。此g.(s)(或Array.get g s)调用表明g的类型不是graph,而是列表的数组,数组索引是某些边的节点ID源,列表值是边缘指向的节点ID。

Queue.take操作抛出一个Empty异常时,此无限循环结束,该异常被无所事事地捕获和处理。我想最好还是写

while not (Queue.is_empty treated) do 
  let s = Queue.take treated in 
  print_int s ;
  add_neighbors g.(s)
done