0

これがコードです

flight(roc,syr,25).
flight(roc,jfk,55).
flight(jfk,bos,65).
flight(bos,syr,40). 
flight(jfk,syr,50). 
flight(bos,roc,50).

layover(roc,25). 
layover(jfk,55).
layover(syr,30).  
layover(bos,40).

route(X,Y,R,D) :-
   flight(X,Y,L),
   D is L,
   R = [X,Y].
route(X,Y,R,D) :-
   flight(X,Z,L),
   route(Z,Y,P,M), 
   R = [X|P],
   layover(Z,T),
   D is M+L+T,
   \+ member(X,P).

これが何が起こっているかです。第二節

route(X,Y,R,D) :-
   flight(X,Z,L),
   route(Z,Y,P,M), 
   R = [X|P], 
   layover(Z,T),
   D is M+L+T,
   \+ member(X,P).

無限ループに入ります。それは私が望む答えを表示し、さらに多くの答えを見つけ続け(基本的に停止をループし続けることができるため)、停止するまで無限ループを実行します。プログラムは、ストップをループしない可能なすべての飛行ルートを見つけることになっています。これが発生する理由はわかっていますが、コードを変更して修正する方法がわかりません。助けてください。

ここに1つの解決策があります

?- route(roc, syr, Routing, Duration).
Routing = [roc, syr],
Duration = 25 ;
Routing = [roc, jfk, syr],
Duration = 160 ;
Routing = [roc, jfk, bos, syr],
Duration = 255 ;
false.
4

2 に答える 2

0

私の答えに対する1つの注意点 - 私はあなたの変数についていくつかの仮定をしています。X は出発点、Y は目的地、R は X から Y までのパスに沿った場所のリスト (包括的)、D は移動距離ですか? もしくは待ち時間。関係ありません。

基本ケースに問題があるようです。基本ケースはflight(X,Y,L)、ルートを満たす a の存在をチェックしています。チェックする必要があるのは、X から Y までの位置のリスト (間違いでなければ R) が既に X から Y までをカバーしているかどうかです。つまり、リスト R の最後の要素が Y であり、R の最初の要素が= X の場合は、完了です。

最後に使用できる関数は次のとおりです。

last([X],X).
last([H|T],R):- last(T,R).

次に、基本ケースを作成できます。

route(X,Y,R,D):- last(R,L), L == Y, [H|T] = R, H == X.

とにかく、そのようなもの。プロローグを使用してからしばらく経ちました...

それが役立つかどうか教えてください。

于 2013-04-29T23:11:17.413 に答える
0

再帰呼び出しの\+member(X,P) 前に問題を解決する必要があると思います。これは、Prolog が句の深さ優先検索、つまり上から下へ、左から右への選択と一致によってロジックを実装しているためです。

もちろん、テストを移動するには、P計算の変更が必要です。現在は訪問後に構築されています。簡単な方法は、最初の呼び出しで [] に初期化されたアキュムレータを使用し、宛先でフル パスに統一することです。いえ

route(X,Y,Acc, [X,Y|Acc], D) :- flight(X,Y,L), D is L.
...

?- route(roc, syr, [], Routing, Duration).
于 2013-04-30T05:39:40.890 に答える