Graph Ocaml-两个节点之间的路径(如何调试)
我需要用一个BFS来做一个算法来解决这个问题: 给定一个有向加权图,一个开始节点,一个停止节点,和一个整数K,假设在开始和停止之间存在一条至少为K的路径 因此,首先我声明了我的加权定向图类型,一个三元组列表: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,
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
我认为我所需要的只是在函数中添加条件,所以我创建了这个函数,在这里我添加了一个intK
作为输入和一个条件:(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