Привет, прежде чем мне расскажут, что этот вопрос задан много раз, я просмотрел множество вопросов, но ни один из них не относится к Prolog. С чем я испытываю трудности.Пролог: Самый короткий путь для рыцаря
Я пытаюсь найти кратчайший путь между двумя точками на шахматной доске. Код, который у меня есть, специально для рыцаря. Это мой код до сих пор:
move1((X1,Y1), (X2,Y2)) :- up1(X1, X2), up2(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- up2(X1, X2), up1(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- up1(X1, X2), down2(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- up2(X1, X2), down1(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- down1(X1, X2), up2(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- down2(X1, X2), up1(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- down1(X1, X2), down2(Y1, Y2).
move1((X1,Y1), (X2,Y2)) :- down2(X1, X2), down1(Y1, Y2).
up1(U, V) :- successor(U, V).
up2(U, W) :- successor(U, V), successor(V, W).
down1(U, V) :- up1(V, U).
down2(U, V) :- up2(V, U).
successor(1, 2).
successor(2, 3).
successor(3, 4).
successor(4, 5).
edge((X1,Y1) , (X2,Y2)) :- move1((X1,Y1), (X2,Y2)).
path((X1,Y1), (X2,Y2),N,[(X1,Y1), (X2,Y2)]) :- N > 0, edge((X1,Y1), (X2,Y2)).
path((X1,Y1), (X3,Y3),N,[(X1,Y1)|P1]) :- N > 0, N1 is N-1, path((X2,Y2), (X3,Y3),N1,P1), edge((X1,Y1), (X2,Y2)), nonmember((X1,Y1),P1).
shortest((X1,Y1),(X2,Y2),P) :- path((X1,Y1),(X2,Y2),24,P),!.
visit((X1,Y1),P,N) :- path((X1,Y1), (X2,Y2),N,P),N2 is N+1,len(P,N2).
len([],0).
len([_|T],N) :- len(T,X), N is X+1.
nonmember(X,[]).
nonmember(X,[U|Y]) :- X \= U, nonmember(X,Y).
Как вы можете видеть, я только найти первый путь, а не самый короткий путь. Я не уверен, как закодировать в прологе и выяснить способ получить все кратчайшие пути. Я думал о том, чтобы составить список всех возможных путей, которые пройдут, и найти кратчайший, но я не могу написать код.
findAll((X1,Y1),(X2,Y2),P,L) :- path((X1,Y1),(X2,Y2),24,P),length(P,L).
Дает мне длину каждого пути, но я не уверен, что с ним делать. Любая помощь в том, как закодировать в Prolog, чтобы найти кратчайший путь, будет очень полезна и является тем, что я ищу.
Не могли бы вы попробовать с '\ + memberchk' вместо вашего предиката' nonmember'? –
Да, извините, я удалил свои комментарии, потому что я как бы понял, если я позвоню последнему, тогда он работает, так как у P1 теперь есть значения. Кроме того, я попытался использовать код, который вы указали выше, и я не могу заставить его работать. Используя кратчайший путь: кратчайший ((1,1), (4,4), P). Он просто продолжает цикл. – helpCompSci
С моим кодом я заметил, что когда я называю самый короткий путь без разреза, он начинается с кратчайшего пути и продолжает перечислять более длинные и более длинные пути. Можно ли сказать, что мой код сначала найдет самый короткий путь, а затем продолжит поиск более длинных? – helpCompSci