查找给定连接的2点之间的路径

时间:2019-05-03 08:53:00

标签: prolog ocaml

我想解决Ocaml中here的典型Prolog问题

连接由以下数据表示:

arc(1,2).
arc(2,3).
arc(3,4).
arc(3,5).
arc(2,5).
arc(5,6).
arc(2,6).

必须找到给定起点和终点的路径(解决方案存储在P中),例如:

?- path(1,6,P).

为此的序言代码如下:

path(X,Y,[arc(X,Y)]) :- arc(X,Y).
path(X,Y,[arc(X,Z)|P]) :- arc(X,Z),path(Z,Y,P).

输出将为:

P = [arc(1, 2), arc(2, 6)] .

我看到Ocaml中有很多模式匹配功能。以上问题如何在Ocaml中解决?

编辑:我不坚持统一方法。

1 个答案:

答案 0 :(得分:1)

OCaml不是逻辑编程语言。它是一种常规的多范式,功能,命令式和面向对象的语言。因此,没有用于解决逻辑问题(除了类型检查之外)或类似方法的内置构造。

但是,您的问题是典型的图形问题,因此您可以使用OCaml中可用的任何图形库来解决它,这是使用Graphlibshortest path算法实现的解决方案经典的Dijkstra's algorithm

open Core_kernel
open Graphlib.Std

module G = Graphlib.Make(Int)(Unit)

let graph = Graphlib.create (module G) () ~edges:[
          1,2,();
          2,3,();
          3,4,();
          3,5,();
          2,5,();
          5,6,();
          2,6,();
]

let () = 
  match Graphlib.shortest_path (module G) graph 1 6 with
  | None -> printf "No path\n"
  | Some p -> 
    Path.edges p |> Sequence.iter ~f:(fun e ->
      printf "Arc(%d, %d)\n" (G.Edge.src e) (G.Edge.dst e))

您可以使用opam安装graphlib

  opam install graphlib

然后,如果您将程序放在单独的文件夹和名称中,例如check_path.ml,则可以使用ocamlbuild构建并运行该程序,例如

 $ ocamlbuild -package graphlib check_path.native --
 Arc(1, 2)
 Arc(2, 6)