Graph Ocaml-两个节点之间的路径(如何调试)

Graph Ocaml-两个节点之间的路径(如何调试),graph,path,ocaml,Graph,Path,Ocaml,我需要用一个BFS来做一个算法来解决这个问题: 给定一个有向加权图,一个开始节点,一个停止节点,和一个整数K,假设在开始和停止之间存在一条至少为K的路径 因此,首先我声明了我的加权定向图类型,一个三元组列表: type 'a graph = Gr of ('a * 'a * 'a) list;; let grafo1 = Gr [(1,3,2);(1,1,5);(2,2,3);(5,5,3);(5,4,6);(3,1,6);(3,7,4);(6,2,7);(4,4,6)];; 在(x,

我需要用一个BFS来做一个算法来解决这个问题: 给定一个有向加权图,一个开始节点,一个停止节点,和一个整数K,假设在开始和停止之间存在一条至少为K的路径

因此,首先我声明了我的加权定向图类型,一个三元组列表:

 type 'a graph = Gr of ('a * 'a * 'a) list;;

 let grafo1 =  Gr [(1,3,2);(1,1,5);(2,2,3);(5,5,3);(5,4,6);(3,1,6);(3,7,4);(6,2,7);(4,4,6)];;
(x,y,z)
中,
x
是起始节点,
y
是边缘权重,
z
是到达节点

然后我做了一个
such
函数:

let succ (Gr arcs) n=
     let rec aux = function
         [] -> []
         | (x,y,z):: rest ->
           if n = x then z::(aux rest)
           else aux rest 
    in aux arcs;;
此函数将节点的后续节点作为oputput,因此:

succ grafo1 1 
给我

   int list = [2; 5]
作为输出

最后,我做了这个
bf_path
函数,它是一个经过修改的BFS,可以在2个节点之间找到路径(否则会引发异常),它需要3个输入:一个图、一个谓词和一个起始节点

 let bf_path g p start =  
       let rec aux visited = function  
           [] -> raise Not_found  
           | x::rest -> if List.mem x visited then aux visited rest  
              else if p x then [x]  
              else try aux (x::visited) rest  
                with Not_found ->  
                  x:: aux (x::visited) (succ g x)  
       in aux [] [start];; 
谓词指定了条件,因此调用:

  bf_path grafo1 ((=)7)1
为我提供
int list=[1;5;6;7]
作为输出,节点1和7之间的路径

现在,我可以找到一条路径,但我需要找到一条至少具有权重
K
的路径,因此我制作了一个小函数,它将三元组列表作为输入,并将权重值相加:

let rec tot = function
   [] -> 0
   |(v,c,p)::t -> c + (tot t);;
因此,调用并输出:

  tot [(2,2,3);(4,5,6);(8,9,0)]

   - : int = 16
我认为我所需要的只是在函数中添加条件,所以我创建了这个函数,在这里我添加了一个int
K
作为输入和一个条件:
(tot path>=K)

该函数编译时不会出现问题:

   val bf_path_final : ('a * int * 'b) graph -> 
  ('a * int * 'b -> bool) -> 'a * int * 'b -> int -> ('a * int * 'b) list = <fun>
那么,这个函数是错误的还是我必须用另一种方式调用它

另一个解决方案是将函数bf_path输出(路径)作为我的tot函数的输入,但我的输出是一个int列表,而不是一个三元组列表,因此我尝试转换我的第一个函数以给出三元组的输出:

(例如:它应该给出
[(1,1,5);(5,4,6);(6,2,7)]而不是
[1;5;6;7]

同样的结果,函数被编译

 val bf_path_tr :
  ('a * 'b * 'c) graph ->
  ('a -> bool) -> 'a * 'b * 'c -> ('a * 'b * 'c) list = <fun>

有没有办法解决这两个问题中的至少一个

调试这类事情的最佳方法是开始在所有地方添加显式类型注释,直到您发现期望与推断类型不匹配的地方

let bf_path_final (g : int graph) (p : int -> bool) (start : int) (k : int) =   
  let rec aux (visited : int list) = function  
      [] -> raise Not_found  
    | x::rest -> if List.mem x visited then aux visited rest  
      else if p x then ( 
        if (tot [x]) >= k then [x] 
        else aux visited rest )
      else try aux (x::visited) rest  
        with Not_found ->  
          x:: aux (x::visited) (succ g x)  
  in aux [] [start];; 
引起错误

File "test.ml", line 32, characters 17-18:
Error: This expression has type int but an expression was expected of type
         'a * int * 'b
它指向
if(tot[x])
其中确实
tot
需要一个三元组列表,但您已经向它传递了一个int列表


你真的想打电话给tot[x]
?这不算什么;x只是其中的一个节点。

调试这类事情的最佳方法是开始在所有地方添加显式类型注释,直到找到期望与推断类型不匹配的地方

let bf_path_final (g : int graph) (p : int -> bool) (start : int) (k : int) =   
  let rec aux (visited : int list) = function  
      [] -> raise Not_found  
    | x::rest -> if List.mem x visited then aux visited rest  
      else if p x then ( 
        if (tot [x]) >= k then [x] 
        else aux visited rest )
      else try aux (x::visited) rest  
        with Not_found ->  
          x:: aux (x::visited) (succ g x)  
  in aux [] [start];; 
引起错误

File "test.ml", line 32, characters 17-18:
Error: This expression has type int but an expression was expected of type
         'a * int * 'b
它指向
if(tot[x])
其中确实
tot
需要一个三元组列表,但您已经向它传递了一个int列表


你真的想打电话给tot[x]?这不算什么;x只是一个节点。

我尝试返回T来解决问题,所以我修改了第一个bf_patg函数,以适应使用三元组的情况,这样函数tot将正常工作。(我更新了问题)。是否尝试向所有内容添加类型批注?这仍然可以帮助你们找出哪里出了问题,我试着回退来解决问题,所以我修改了第一个bf_patg函数,以适应使用三元组的情况,所以函数tot将正确工作。(我更新了问题)。是否尝试向所有内容添加类型批注?这仍然可以帮助你找出哪里出了问题
let bf_path_final (g : int graph) (p : int -> bool) (start : int) (k : int) =   
  let rec aux (visited : int list) = function  
      [] -> raise Not_found  
    | x::rest -> if List.mem x visited then aux visited rest  
      else if p x then ( 
        if (tot [x]) >= k then [x] 
        else aux visited rest )
      else try aux (x::visited) rest  
        with Not_found ->  
          x:: aux (x::visited) (succ g x)  
  in aux [] [start];; 
File "test.ml", line 32, characters 17-18:
Error: This expression has type int but an expression was expected of type
         'a * int * 'b