3

タイトルが示すように、私は最良優先探索を使用して8パズルを解くプロローグプログラムを作成する必要があります。私はプロローグとAIに慣れていないため、苦労しています。

今のところ私が持っているのは移動ルールです:

%% move left in the top row
move([X1,0,X3, X4,X5,X6, X7,X8,X9],
     [0,X1,X3, X4,X5,X6, X7,X8,X9]).
move([X1,X2,0, X4,X5,X6, X7,X8,X9],
     [X1,0,X2, X4,X5,X6, X7,X8,X9]).

%% move left in the middle row
move([X1,X2,X3, X4,0,X6,X7,X8,X9],
     [X1,X2,X3, 0,X4,X6,X7,X8,X9]).
move([X1,X2,X3, X4,X5,0,X7,X8,X9],
     [X1,X2,X3, X4,0,X5,X7,X8,X9]).

%% move left in the bottom row
move([X1,X2,X3, X4,X5,X6, X7,0,X9],
     [X1,X2,X3, X4,X5,X6, 0,X7,X9]).
move([X1,X2,X3, X4,X5,X6, X7,X8,0],
     [X1,X2,X3, X4,X5,X6, X7,0,X8]).

%% move right in the top row 
    move([0,X2,X3, X4,X5,X6, X7,X8,X9],
     [X2,0,X3, X4,X5,X6, X7,X8,X9]).
move([X1,0,X3, X4,X5,X6, X7,X8,X9],
     [X1,X3,0, X4,X5,X6, X7,X8,X9]).

%% move right in the middle row 
move([X1,X2,X3, 0,X5,X6, X7,X8,X9],
     [X1,X2,X3, X5,0,X6, X7,X8,X9]).
move([X1,X2,X3, X4,0,X6, X7,X8,X9],
     [X1,X2,X3, X4,X6,0, X7,X8,X9]).

%% move right in the bottom row
move([X1,X2,X3, X4,X5,X6,0,X8,X9],
     [X1,X2,X3, X4,X5,X6,X8,0,X9]).
move([X1,X2,X3, X4,X5,X6,X7,0,X9],
     [X1,X2,X3, X4,X5,X6,X7,X9,0]).

%% move up from the middle row
move([X1,X2,X3, 0,X5,X6, X7,X8,X9],
     [0,X2,X3, X1,X5,X6, X7,X8,X9]).
move([X1,X2,X3, X4,0,X6, X7,X8,X9],
     [X1,0,X3, X4,X2,X6, X7,X8,X9]).
move([X1,X2,X3, X4,X5,0, X7,X8,X9],
     [X1,X2,0, X4,X5,X3, X7,X8,X9]).

%% move up from the bottom row
move([X1,X2,X3, X4,X5,X6, X7,0,X9],
 [X1,X2,X3, X4,0,X6, X7,X5,X9]).
move([X1,X2,X3, X4,X5,X6, X7,X8,0],
     [X1,X2,X3, X4,X5,0, X7,X8,X6]).
move([X1,X2,X3, X4,X5,X6, 0,X8,X9],
     [X1,X2,X3, 0,X5,X6, X4,X8,X9]).

%% move down from the top row
move([0,X2,X3, X4,X5,X6, X7,X8,X9],
     [X4,X2,X3, 0,X5,X6, X7,X8,X9]).
move([X1,0,X3, X4,X5,X6, X7,X8,X9],
     [X1,X5,X3, X4,0,X6, X7,X8,X9]).
move([X1,X2,0, X4,X5,X6, X7,X8,X9],
     [X1,X2,X6, X4,X5,0, X7,X8,X9]).

%% move down from the middle row
move([X1,X2,X3, 0,X5,X6, X7,X8,X9],
     [X1,X2,X3, X7,X5,X6, 0,X8,X9]).
move([X1,X2,X3, X4,0,X6, X7,X8,X9],
     [X1,X2,X3, X4,X8,X6, X7,0,X9]).
move([X1,X2,X3, X4,X5,0, X7,X8,X9],
     [X1,X2,X3, X4,X5,X9, X7,X8,0]).

(リストを使用するより簡単な方法があることは知っていますが、これが私にとってうまくいったことです)

そして私がインターネットで見つけた最高の最初のコード:http ://www.cs.unm.edu/~luger/ai-final/code/PROLOG.best.html

しかし、その最良の最初のコードには、実行されないこのヒューリスティック関数があります。

go(Start, Goal) :- 
   empty_set(Closed),
   empty_sort_queue(Empty_open),
   heuristic(Start, Goal, H),
   state_record(Start, nil, 0, H, H, First_record),
   insert_sort_queue(First_record, Empty_open, Open),
   path(Open,Closed, Goal).

問題によってヒューリスティックが変化するため、どこにも定義されておらず、自分で定義する必要があるためだと思います。

そこで、マンハッタン距離などよりもコーディングが簡単に聞こえるので、8パズルに「タイルがずれている」ヒューリスティックを使用することを考えました。しかし今、私はそれをプログラムする方法に固執しています、私はリストを比較する方法と変数を追加する方法についてどこでもグーグルで検索しました、そして私はちょっとこれを作りました、それは私がうまくいくかどうかわかりません:

heuristic([],[],H).
heuristic([Head1|Tail1],[Head2|Tail2], H):-
   not(samePlace(Head1,Head2))->H1 is H + 1,
   heuristic(Tail1, Tail2, H1).

私の考えでは、スタートリストのすべての要素を検索し、それをゴールリストと比較します。次に、それらが異なる場合は、Hに1を加算し、Hは場違いのタイルの数になります。

私が「同じ場所のタイルのルール」も定義したことについて:

samePlace([X,_,_,_,_,_,_],[X,_,_,_,_,_,_]).
samePlace([_,X,_,_,_,_,_],[_,X,_,_,_,_,_]). 
samePlace([_,_,X,_,_,_,_],[_,_,X,_,_,_,_]).
samePlace([_,_,_,X,_,_,_],[_,_,_,X,_,_,_]).
samePlace([_,_,_,_,X,_,_],[_,_,_,_,X,_,_]).
samePlace([_,_,_,_,_,X,_],[_,_,_,_,_,X,_]).
samePlace([_,_,_,_,_,_,X],[_,_,_,_,_,_,X]). 
(etc...)

しかしもちろん、「エラー:ヒューリスティック/ 3:引数が十分にインスタンス化されていません」というメッセージが表示されます。これは、Hを初期化したことがないことを意味すると思います。

コードの残りの部分が実際にどのように機能するかはわかりません。最良の最初のアルゴリズムは幅優先のようなものですが、キューを単に追加するのではなく、ヒューリスティックに従って並べ替えます。

私の質問は次のとおりです。-私は正しい方向に進んでいますか、それともそこにあるその「ヒューリスティック」機能が何を意味するのかを完全に読み違えましたか?-Hを初期化するにはどうすればよいですか?-私の「ヒューリスティック」関数コードは構文的に正しいですか?

長い投稿で申し訳ありませんが、ルールは私がたくさんの情報を与えるべきだと言っています。私はあなたがこれで私を助けてくれることを願っています、どんな助けでもありがたいです、それであなたがこれをする他の方法を知っているならそれらを自由に投稿してください、私は初心者です。

前もって感謝します。

4

1 に答える 1

0

Prologの(->)/ 2は、if..then..else ..ロジックのモデリングを容易にするために導入されましたが、命令型言語とは重要な違いがあります。'else'ブランチがないと、条件が失敗すると失敗します。

ここで、heuristic/3のelseブランチを見逃します。これは意図されたものかもしれませんが、samePlace(Head1、Head2)がどこかで真である場合、これは値を返さないため、コードの呼び出しでバックトラックを開始すると思います。私の経験では、これは、あなたが報告しているような、その後の奇妙なエラーメッセージの原因となることがよくあります。

もう1つの問題は、述語が成功した場合でも値を「返す」ことができないことです。代わりに試してください

heuristic([],[],0).
heuristic([Head1|Tail1],[Head2|Tail2], H):-
   heuristic(Tail1, Tail2, H1),
   (   not(samePlace(Head1,Head2))
   ->  H is H1 + 1
   ;   H is H1
   ).
于 2012-11-10T08:12:39.047 に答える