Prolog Labyrinth der Lösung des Algorithmus
Will ich implementieren Sie eine Lösung des Labyrinth-Algorithmus in Prolog. Daher suchte ich für einige Labyrinth lösungsalgorithmen und Folgendes gefunden: http://www.cs.bu.edu/teaching/alg/maze/
FINDEN-PFAD(x, y):
if (x,y outside maze) return false
if (x,y is goal) return true
if (x,y not open) return false
mark x,y as part of solution path
if (FIND-PATH(North of x,y) == true) return true
if (FIND-PATH(East of x,y) == true) return true
if (FIND-PATH(South of x,y) == true) return true
if (FIND-PATH(West of x,y) == true) return true
unmark x,y as part of solution path
return false
Ich schon bauen Sie eine matrix, in prolog, das entspricht einem Labyrinth, und wo 0 ist öffnen und 1 ist zum Beispiel eine Mauer (Start-position wäre (2/1) und das Ziel befindet sich auf (4/1)):
11111
10001
10101
Weiter mehr definierte ich eine Klausel namens mazeDataAt(Coord_X, Coord_Y, MazeData, Result)
, das gibt mir den Wert der matrix an einer bestimmten position.
So weit. Jetzt habe ich aber ein problem der Umsetzung dieses Algorithmus in prolog. Ich habe bereits versucht, "the dirty way" (zu übersetzen durch die Verwendung von geschachtelten if-Anweisungen), aber das eskalierte Komplexität und ich glaube nicht, dass es die Art und Weise Sie es tun in prolog.
Also versuchte ich Folgendes:
isNotGoal(X, Y) :-
X = 19, Y = 2.
notOpen(X, Y, MazeData) :-
mazeDataAt(X, Y, MazeData, 1).
findPath(X, Y, MazeData) :-
isNotGoal(X, Y),
notOpen(X, Y, MazeData),
increase(Y, Y_New),
findPath(X, Y_New, MazeData),
increase(X, X_New),
findPath(X_New, Y, MazeData),
decrease(Y, Y_New),
findPath(X, Y_New, MazeData),
decrease(X, X_New),
findPath(X, Y_New, MazeData).
Aber dieser Versuch hat nicht funktioniert wie erwartet.
Eigentlich ist das ein richtiger prolog-Implementierung des Algorithmus oben?
Wie kann ich sehen, ob dieser Ansatz findet wirklich einen Weg durch das Labyrinth?
Also wie kann ich notieren Sie den Pfad oder den Lösungsweg (was geschieht durch markieren /abwählen der Pfad in der oben angegebenen Algorithmus)?
Danken Ihnen sehr für Ihre Hilfe!
//UPDATE
Dank für Eure Antworten! Ich nahm eine weitere prolog-wie-Lösung (siehe hier) um mein problem zu lösen. Also ich habe jetzt:
d([2,1], [2,2]).
d([2,2], [1,2]).
d([2,2], [2,3]).
go(From, To, Path) :-
go(From, To, [], Path).
go(P, P, T, T).
go(P1, P2, T, NT) :-
(d(P1, P3) ; d(P3, P2)),
\+ member(P3, T),
go(P3, P2, [P3|T], NT).
So weit, das funktioniert. Und ich glaube, ich verstehe, warum das prolog-Weg ist wesentlich besser.
Jetzt habe ich aber ein kleines problem übrig.
Möchte ich meine knowledge base "dynamisch". Ich kann nicht definieren Sie die Ränder für jede einzelne Wegpunkt in das Labyrinth. Daher schrieb ich eine Klausel namens is_adjacent([X1, Y1], [X2, Y2])
was wahr ist, wenn [X1, Y1]
ist ein Nachbar von [X2, Y2]
.
Ich habe auch eine Liste Waypoints = [[2, 1], [2, 2]| ...]
enthält alle möglichen Wegpunkte in meinem Labyrinth.
Nun die Frage: Wie kann ich diese nutzen, um meine knowledge base "dynamisch"? So dass ich es verwenden können, in der go
- Klausel für die Suche nach dem Weg?
Vielen Dank für Ihre Hilfe!
//UPDATE 2
Ok, jetzt habe ich alle Wegpunkte als Fakten:
w(2, 1).
w(2, 2).
...
Nahm ich die Lösung von Boris in einem seiner Antworten:
d(X0, Y0, X , Y) :-
w(X0, Y0),
next_w(X0, Y0, X, Y),
w(X, Y).
next_w(X0, Y0, X0, Y) :- Y is Y0 + 1.
next_w(X0, Y0, X0, Y) :- Y is Y0 - 1.
next_w(X0, Y0, X, Y0) :- X is X0 + 1.
next_w(X0, Y0, X, Y0) :- X is X0 - 1.
Nach, dass, ich aktualisiert die go
- Klausel, so dass es passt:
go(X1, Y1, X2, Y2, Path) :-
go(X1, Y1, X2, Y2, [], Path).
go(X, Y, X, Y, T, T).
go(X1, Y1, X2, Y2, T, NT) :-
(d(X1, Y1, X3, Y3) ; d(X3, Y3, X1, Y1)),
\+ member([X3, Y3], T),
go(X3, Y3, X2, Y2, [[X3, Y3]|T], NT).
Aber wenn ich versuche zu Fragen go(2, 1, 19, 2, R)
prolog in eine unendliche Schleife. Wenn ich versuche etwas einfacher wie go(2, 1, 3, 8, R)
es funktioniert und ich bekomme die Lösung Pfad in R
.
Was mache ich falsch? Was habe ich vergessen?
- Siehe hier: stackoverflow.com/questions/8672046/... (gefunden mit "[prolog] Labyrinth"). Dieser Ansatz zeigt mögliche übergänge mit Fakten der form
d(From, To)
. - Danke, aber das wird nicht wirklich zu meinen Anforderungen passen, denn meine motivation ist die übersetzung der oben angegebenen Algorithmus in prolog, bzw. verwenden Sie es als ein Versuch für eine entsprechende prolog-Algorithmus.
- Tatsächlich, ich denke, das ist im Grunde die exakt gleichen Algorithmus, nur geschrieben in der richtigen "native" Prolog, unter Ausnutzung der möglichen übergänge als Fakten und backtracking. Ich würde vorschlagen, Sie versuchen zu bauen der Struktur der Lösung für den Algorithmus gezeigt und die Prolog-Lösung, und Sie sollten es selbst sehen.
- Sie sollten wirklich check out die Frage @Boris verbunden, als es zeigt, wie das zu tun diese Art der Sache in der Sprache Prolog. Ihre übersetzung des gegebenen Algorithmus ist nicht zur Arbeit zu gehen, solange Sie nicht die Sprache verstehen.
- Ok, ich habe es! Danke. Aber jetzt will ich meine knowledge base "dynamisch", siehe meinen aktualisierten post. Können Sie mir helfen mit, dass?
Du musst angemeldet sein, um einen Kommentar abzugeben.
(diese Antwort verwendet den gleichen Pfad zu finden-Algorithmus als diese Antwort)
EDIT 2
In der Tat, wenn Sie Ihre Eingabe ist nur, die Zellen der rechteckigen matrix sind keine Mauern, die Sie benötigen würden, um irgendwie übersetzen dieses auf Regeln der Art "man kann von A nach B kommen". Wenn Sie Ihre Wegpunkte sind dann:
etc, dann kann man übersetzen Sie den Algorithmus, den Sie ursprünglich wies in eine Prolog-Regel:
Beachten Sie zwei Dinge:
next_w
. Wennd
aufgerufen wird, verwendetnext_w
zu generieren, die die vier möglichen Nachbarn Quadrate (vorausgesetzt, Sie kann nur nach oben/unten/Links/rechts) und prüft dann, ob dieser Platz ist in der Tat ein Wegpunkt. Würden Sie nicht brauchen, um zu überprüfen, in beide Richtungen nicht mehr.Noch ein EDIT: Vollständigen code
Rufen Sie es mit
und man sollte die zwei möglichen Lösungen.
In anderen Worten, ich glaube, dein problem ist das Semikolon; es ist nicht mehr notwendig, da Sie explizit erstellen, die alle möglichen Züge.