【问题标题】:Avoiding the same answer multiple times in prolog在序言中多次避免相同的答案
【发布时间】:2019-12-27 18:06:16
【问题描述】:

所以我有这个无向图要遍历,我应该找到所有连接到给定顶点的顶点。

edge(a, b).
edge(b, c).
edge(c, d).
edge(d, e).
edge(e, f).
edge(f, d).
edge(d, g).
edge(g, f).
edge(g, h).
edge(h, i).
edge(i, j).
edge(j, d).
edge(d, k).
edge(l, m).
edge(m, n).

undirectedEdge(X, Y) :- edge(X, Y).
undirectedEdge(X, Y) :- edge(Y, X).

connected(X, Y) :- undirectedEdge(X, Y).
connected(X, Y) :- connected(X, Z), connected(Z, Y), X \= Y.

一旦我输入connected(a, X).,它就会进入一个无限循环。 我明白我为什么会有它,但我不知道如何避免它,也许我可以在这里找到一些帮助?

【问题讨论】:

  • 你维护一个列表,这样它就不会开始循环了。

标签: prolog


【解决方案1】:

使用closure0/3setof/3 我们得到:

connected(A,B) :-
   setof(t, closure0(undirectedEdge, A, B), _).

【讨论】:

    【解决方案2】:

    一旦我输入connected(a, X)。它进入了一个无限循环。

    发生这种情况的原因是它正在检查a → b → a → b → a → b → … 形式的路径。所以它一直在两个节点之间“跳跃”。

    您可以维护算法已经访问过的节点列表,以防止类似的情况发生:

    connected(X, Y) :-
        connected(X, Y, [X]).
    
    connected(X, X, _).
    connected(X, Z, L) :-
        undirectedEdge(X, Y),
        \+ member(Y, L),
        connected(Y, Z, [Y|L]).

    您可以使用distinct/1 predicate [swi-doc] 生成不同的答案:

    ?- distinct(connected(a, X)).
    X = a ;
    X = b ;
    X = c ;
    X = d ;
    X = e ;
    X = f ;
    X = g ;
    X = h ;
    X = i ;
    X = j ;
    X = k ;
    false.
    

    【讨论】:

    • 感谢您的快速响应...现在我有 29 个 X 值而不是无限循环。但是29还是有重复的,是否可以定义一个全局列表?
    • @Question:大多数系统都有一个不可回溯的存储。但这通常不是一个好主意。您可以使用distinct/1 元谓词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 2012-08-16
    • 2022-06-14
    • 1970-01-01
    • 2017-08-15
    • 2012-03-25
    • 1970-01-01
    相关资源
    最近更新 更多