簡體   English   中英

在遞歸中使用Prolog列表

[英]Using Prolog Lists in Recursion

因此,我嘗試使用遞歸方法在兩個人之間找到一條路徑。 快速背景如下:我in(X,Y)定義了一些事實。 那表明誰是相關的,即。 in(person1,project1)in(person2,project1)等。現在,如果兩個人彼此在同一個項目中,或者它們之間存在人與人之間的鏈接路徑,則它們是相關的。 例如,p1在A上工作,p2在A和B上工作,p3在B上工作,因此存在從p1到p3到p2的路徑。 這些路徑可以是任何長度。

我試圖遞歸解決此問題(沒有其他方法),但是有一個煩人的問題:

related(A,B) :-
        in(A,X),
        in(B,X),
        not(A=B).

chain(A,B) :-
        related(A,B).
chain(A,B) :-
        related(A,Y),       
        chain(Y,B).

問題是路徑可以重復。 它可以從p1到p2再回到p1無限次。 一個人在路徑上的停留時間不得超過1次。

我嘗試使用添加到的列表來解決此問題。 如果某個人已經在列表中,則無法再次添加:

related(A,B,L) :-
        in(A,X),
        in(B,X),not(A=B).

chain(A,B,L) :-
        related(A,B,L).
chain(A,B,L) :-
        related(A,Y,L),
        not(member(Y,L)),
        append(L,[Y],Q),
        chain(Y,B,Q).

這種方法行之有效,但卻造成了大量隨機錯誤,多次重復某些人,一次僅重復一次,然后失敗。 這種方法看起來正確嗎? 我完全使用列表錯誤嗎?

謝謝。

首先改進。 您是在尋找所有的關系鏈還是要檢查是否存在一個關系鏈? 在第一種情況下,添加剪切。

chain(A,B) :-
        related(A,B), !.
chain(A,B) :-
        related(A,Y),       
        chain(Y,B).

在第二種情況下,Prolog完全按照要求執行,即查找所有可能的鏈。

請發布會導致問題的查詢,以便我們可以共同推理並改善解決方案。

這是一種基於定點計算的替代方法,可能效率較低,但較為通用。

connected(Found, Connected) :-
    collect(Found, [], Ext),
    (   Ext == Found
    ->  Connected = Found
    ;   connected(Ext, Connected)
    ).

collect([], Set, Set).
collect([E|Es], Set, Fix) :-
    extend(E, Set, Ext),
    collect(Es, Ext, Fix).

extend(E, Set, Ext) :-
    directly(E, DirectConn),
    ord_union(DirectConn, Set, Ext).

directly(A, DirectConn) :-
    setof(B, P^(in(A, P), in(B, P)), DirectConn).

我們必須使用已排序的列表來調用connected(Found,Connected),它會循環直到無法擴展集合。 例如,使用此測試數據

in(anna,  project1).
in(bob,   project1).
in(bob,   project2).
in(chris, project2).
in(dan,   project3).

?- connected([bob],L).
L = [anna, bob, chris].

?- connected([dan],L).
L = [dan].

我直接允許故意/ 2獲得身份,即

?- directly(X,Y).
X = anna,
Y = [anna, bob] ;
...
X = dan,
Y = [dan].

我想我從來都不夠清楚,但是我最終自己解決了這個問題。 我把代碼放在下面。

真正重要的是有效的notchain謂詞,然后確保我正確執行了附加項。 我還創建了一個notsame謂詞來替換not(A = B)。 代碼如下。 大部分答案是要確保列表后面附有[]。 在要附加的內容周圍沒有正確的[]會導致錯誤。

notchain(X,L):-

成員(X,L),!,失敗。

notchain(X,L)。

接着:

鏈(A,B,L):-

related(A,B),append(L,[A],Q),append(Q,[B],Z),write(final),writeln(Z)。

chain(A,B,L):-notchain(A,L),append(L,[A],Q),related(A,Y),chain(Y,B,Q)。

這用於相關:

notsame(A,B):-
(A = B),!,失敗。

notsame(A,B)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM