Ich habe ein Programm in Prolog geschrieben, um Routen zwischen Metrostationen zu finden. Es funktioniert so ziemlich wie erwartet für lineare Routen (A -> B -> C -> D)
, aber ich weiß nicht, wie man die kreisförmigen (A -> B -> C -> D -> A -> B -> ...)
und so weiter behandelt.Umgang mit Kreisrouten im Routenfindungsalgorithmus
Die Datenbank:
stations.pl
train(
a,
[
station2,
station3,
station4,
station10
]
).
train(
b1,
[ station1,
station8,
station3,
station10,
station11
]
).
train(
b2,
[
station1,
station11,
station10,
station3,
station8
]
).
train(
c,
[
station0,
station8,
station21
]
).
Und das Programm:
rails.pl
:- include('stations.pl').
% Case: direct route (A) --> (B).
route(A, B, Trains, Acc, R) :-
train(Train, Stations),
\+ member(Train, Trains),
member(A, Stations),
member(B, Stations),
append(Acc, [[A, Train, B]], R).
% Case: intermediary station/s (I) between
% departure (A) and destination (B).
route(A, B, Trains, Acc0, R) :-
train(Train, Stations),
\+ member(Train, Trains),
member(A, Stations),
member(I, Stations),
A \= I,
I \= B,
length(Acc0, L),
L < 3, % do not find routes where more than 2 changes are needed
append(Acc0, [[A, Train, I]], Acc1),
route(I, B, [Train|Trains], Acc1, R).
Linear Routen:a
, c
Rundweg:b1
, b2
Nun wollen wir den folgenden Fall in Betracht ziehen. Zeigt alle Routen von station2
bis station21
an. Die Reihenfolge der Ergebnisse wurde der Einfachheit halber geändert.
?- route(station2, station21, [], [], R).
R = [[station2, a, station3], [station3, b1, station8], [station8, c, station21]] ;
R = [[station2, a, station3], [station3, b2, station8], [station8, c, station21]] ;
R = [[station2, a, station3], [station3, b1, station1], [station1, b2, station8], [station8, c, station21]] ;
R = [[station2, a, station3], [station3, b2, station1], [station1, b1, station8], [station8, c, station21]] ;
...
...
Das Problem:
Das Problem ist, wie das Programm bewusst zu machen, dass b1
und b2
die gleiche Strecke, auch wenn die Namen sind unterschiedlich. Ich mag ausschließen Routen wie:
station2 (a) station3 -> station3 (b1) station1 ->
station1 (b2) station8 -> station8 (c) station21
, weil der Abstand zwischen station3
und station8
kann auf beide b1
oder b2
, keine Notwendigkeit, um zwischen ihnen durchgeführt werden.
Also im Grunde möchte ich beide Routen als eins behandelt werden, aber unterschiedliche Namen haben, abhängig von der Richtung der Suche. Es ist nicht eine Frage der Effizienz an diesem Punkt, es geht darum, zwischen b1
und b2
auf der gleichen Route nicht zu springen.
EDIT:
- nach dem ersten Ergebnis Stoppt Rückzieher ist keine Option
- Diese Zugstrecke
b1/b2
unter singulär ist 10+, so bin ich nicht unbedingt für eine generische Lösung suchen, so Atom Namensprüfung würde Arbeit (keine Ahnung, wie es geht).
Könnten Sie bitte erklären 'Diese Zugroute b1/b2 ist Singular unter 10+, also bin ich nicht unbedingt auf der Suche nach einer generischen Lösung ' –
Ich habe nicht auf Ihren Code im Detail, sondern nur durch Lesen der Frage, die ich würde Kosten von 1 für die Fahrt von einer Station zur nächsten Station und dann eine Gebühr von 1 für den Umstieg hinzufügen. So wird die selbe Route gefahren, aber das Wechseln der Züge wird höhere Kosten verursachen. Wenn ich die Frage richtig verstehe, ist die Antwort nur die niedrigsten Kosten. –
Auch ein Atem zuerst Suche statt einer Tiefe zuerst Suche wird zuerst die richtige Antwort zu erreichen. –