有时候,我听说过open-ended list
和difference-list
。我知道他们来自prolog:Difference between "open-ended lists" and "difference lists"
但OCaml是否使用它们?
我问这个问题,因为在OCaml 99 problems中,有一个问题:
图同构。 (介质)
如果存在a,则两个图G1(N1,E1)和G2(N2,E2)是同构的 双射f:N1→N2使得对于任何节点X,N1,Y和Y的Y是 当且仅当f(X)和f(Y)相邻时才相邻。
编写一个函数,确定两个图是否同构。 提示:使用开放式列表来表示函数f。
我甚至不理解提示:
使用开放式列表来表示函数f
问题:
答案 0 :(得分:1)
这是a solution in Prolog图同构问题;它可能使用开放式列表(我不熟悉执行检查或扩展同构的工作的标准库memberchk
的行为),但这只是一个实现细节。
算法的一般思想是对表示部分同构的结构进行回溯,到目前为止所处理的所有边都是一致的。你可以用任何语言实现它,例如使用非确定性monad,我不认为尾细胞统一在这里发挥重要作用;使用Map
(来自标准库的持久关联映射)来操纵从N1
的节点到N2
的节点的映射就可以了(并且在算法上比在线性搜索中更有效)开放式清单)。
算法的伪代码如下:
let add_edge iso (n1,n2) (n1', n2') =
if n1 is unbound in iso, extend it with n1->n1'
same for (n2, n2')
if n1 is bound to a node different from n1' return None
same for (n2, n2')
else Some iso
let graph_iso iso g1 g2 =
if g1 is empty then Some iso
else if has an edge e1 then
for any e2 in g2 such that add_edge iso e1 e2 is Some iso'
if graph_iso iso' (g1 - e1) (g2 - e2) is not None, return it
else return None