Path 在DLV中查找最短路径

Path 在DLV中查找最短路径,path,shortest-path,declarative,datalog,answer-set-programming,Path,Shortest Path,Declarative,Datalog,Answer Set Programming,我正在尝试使用DLV查找具有最小距离的图中的所有路径。假设我有以下图表: 我希望获得谓词(我希望不会跳过任何谓词): 路径(a,b,1),路径(a,d,1),路径(a,e,1),路径(a,c,2) 路径(b,a,1),路径(b,c,1),路径(d,d,2),路径(b,e,2) 路径(c,b,1),路径(c,e,1),路径(c,a,2),路径(c,d,3) 路径(d,a,1),路径(d,b,2),路径(d,e,2),路径(d,c,3) 路径(e,a,1),路径(e,c,1),路径(e,d,2)

我正在尝试使用DLV查找具有最小距离的图中的所有路径。假设我有以下图表:

我希望获得谓词(我希望不会跳过任何谓词):

  • 路径(a,b,1),路径(a,d,1),路径(a,e,1),路径(a,c,2)
  • 路径(b,a,1),路径(b,c,1),路径(d,d,2),路径(b,e,2)
  • 路径(c,b,1),路径(c,e,1),路径(c,a,2),路径(c,d,3)
  • 路径(d,a,1),路径(d,b,2),路径(d,e,2),路径(d,c,3)
  • 路径(e,a,1),路径(e,c,1),路径(e,d,2),路径(e,b,2)
我假设你可以左右移动一个拱门。因此,我尝试了以下方法:

path(X, Y, 1) :- arc(X, Y).
path(Y, X, 1) :- arc(X, Y).
path(X, Z, L) :- path(X, Y, M), path(Y, Z, N), 
                 X!=Z, 
                 L = M + N,
                 not path(X, Z, V), V < L, #int(V) 
路径(X,Y,1):-弧(X,Y)。 路径(Y,X,1):-弧(X,Y)。 路径(X,Z,L):-路径(X,Y,M),路径(Y,Z,N), X=Z L=M+N, 非路径(X,Z,V),V 第三条规则的思想是,如果两条现有路径不返回(X!=Z),并且还没有一条路径将相同的边连接到较短的距离(不是路径(X,Z,V),V 当我运行这段代码时(将-N=5标记设置为#maxint=5),我得到了不应该存在的路径,例如路径(d,a,5)。我不知道问题是否出在#int(V)或其他方面,但我不希望出现这些路径,因为我已经有了一个路径(d,a,1)。可能是因为#int(V),但我不知道如何正确地执行此操作

谁能帮我解决这个问题?提前感谢。

示例/spaths.dl来自发行版。请参阅下面的注释代码…-

%
% Shortest Paths in a Graph
%
% Datalog Formulation
%
% Program: Shortest paths in a graph
% Author : Fernando Sáenz-Pérez
% Date   : September, 2009

edge(a,b).
edge(a,c).
edge(b,a).
edge(b,d).

path(X,Y,1) :- 
  edge(X,Y).
path(X,Y,L) :-
  path(X,Z,L0),
  edge(Z,Y),
  count(edge(A,B),Max),
  L0<Max,
  L is L0+1.

spaths(X,Y,L) :-
   min(path(X,Y,Z),Z,L).


% Note that the following is not stratifiable in DES

%sp(X,Y,1) :- 
%  edge(X,Y).
%sp(X,Y,L) :-
%  sp(X,Z,L0),
%  not(shorter(X,Z,L0)), 
%  edge(Z,Y),
%  L is L0+1.

%shorter(X,Y,L) :-
%  sp(X,Y,L0),
%  L0<L.
%
%图中的最短路径
%
%数据记录公式
%
%程序:图中的最短路径
%作者:费尔南多·萨恩斯·佩雷斯
%日期:2009年9月
边缘(a,b)。
边缘(a,c)。
边(b,a)。
边缘(b,d)。
路径(X,Y,1):-
边(X,Y)。
路径(X,Y,L):-
路径(X,Z,L0),
边缘(Z,Y),
计数(边缘(A,B),最大值),

L0使用列表跟踪路径的问题解决方案:

path(X, Y, [X, Y], 1) :- arc(X, Y).
path(Y, X, [Y, X], 1) :- arc(X, Y).
path(X, Z, P, D) :- path(X, Y, P1, D1),
                    path(Y, Z, P2, 1),
                    #insLast(P1, Z, P), 
                    D = D1 + 1,
                    not #member(Z, P1).
shortest_path(X, Y, D) :-   node(X), node(Y), 
                            #min{L: path(X, Y, P, L)} = D.                  
无需列表的解决方案(借助)

路径(X,Y,1):-弧(X,Y)。 路径(Y,X,1):-弧(X,Y)。 路径(X,Y,D):-路径(X,Z,D0),弧(Z,Y), #计数{A:node(A)}=Max,
D0我刚刚解决了使用路径谓词中的列表查找路径的问题,但我仍然想知道为什么我在这里发布的解决方案不起作用。我还设法根据@capelical的输入提出了一个解决方案。如果有人感兴趣,我将发布带列表和不带列表的解决方案。谢谢发布您的解决方案。我使用的是DLV,它不支持“L是L0+1”,但我只需要将“is”改为“=”就可以了。我不熟悉普通数据日志,所以我真的不知道count应该做什么。它是否以最大值存储边数?无论如何,当我执行这段代码时,我没有从A->B->D得到路径,只有距离为1的路径。此外,也没有证据表明发生了口角。你能提供更多的细节吗?另外,你能把我特别的DLV问题加起来吗?从作者的书(distribution/docs/manualDES.pdf)中,
注意,通过将路径的总长度限制为图形中的边数,可以避免使用内置is/2可能引起的无限计算。
。所以我认为是的,
count
做到了它的名字所暗示的。对于这个问题,它是一个常数,它不会改变任何数据。对不起,我没有可用的DLV,因此无法帮助。。。如果您感兴趣,SWI Prolog有tabling,我认为,它可以运行上面的DES,基本上保持不变。比较起来会很有趣…再次感谢您的回复。我已经能够根据自己的需要调整代码,而无需付出太多努力。我将根据您的输入在DLV中发布解决方案:-)没有列表的解决方案不起作用。现在我几乎可以肯定我需要使用列表,否则不可能获得所有路径。
path(X, Y, 1)   :-  arc(X,Y).
path(Y, X, 1)   :-  arc(X,Y).
path(X, Y, D)   :-  path(X,Z,D0), arc(Z,Y),
                    #count{A: node(A)} = Max,
                    D0<Max, X != Y,
                    D = D0+1.

shorter_paths(X, Y, D) :- node(X), node(Y), 
                          #min{L: path(X, Y, L)} = D.