【问题标题】:Find the shortest path in DLV在 DLV 中找到最短路径
【发布时间】:2016-09-15 06:20:14
【问题描述】:

我正在尝试使用 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) 

第三条规则的想法是添加 2 条现有路径,如果它们不返回 (X!=Z) 并且还没有一条路径连接相同边缘的更短距离(不是 path(X, Z, V),V

当我运行此代码时(使用标志 -N=5 设置 #maxint=5),我得到不应该存在的路径,例如 path(d,a,5)。我不知道问题出在#int(V) 还是其他问题上,但我不希望这些路径出现,因为我已经有了路径(d,a,1)。可能是因为#int(V) 但我不知道如何正确地做到这一点。

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

【问题讨论】:

  • 我刚刚解决了使用 path 谓词中的列表查找路径的问题,但我仍然想知道为什么我在这里发布的解决方案不起作用跨度>
  • 我还设法根据@CapelliC 的输入提出了一个解决方案。如果有人感兴趣,我将发布带有和不带有列表的解决方案

标签: path shortest-path declarative datalog answer-set-programming


【解决方案1】:

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

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.                  

不需要列表的解决方案(在CapelliC的帮助下)

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.

请注意,我们需要使用谓词node() 定义所有节点,并且谓词arc() 假定图的边是双向的。

【讨论】:

  • 没有列表的解决方案不起作用。现在我几乎可以肯定我需要使用列表,否则不可能获得所有路径。
【解决方案2】:

examples/spaths.dl 来自DES 分布。请参阅下面的注释代码... -

%
% 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.

【讨论】:

  • 感谢您发布您的解决方案。我正在使用 DLV,它不支持“L is L0 + 1”,但我只需将“is”更改为“=”就可以了。我不熟悉普通的数据记录,所以我真的不知道 count 应该做什么。它是否将边数存储在 Max 中?无论如何,当我执行这段代码时,我没有得到从 A -> B -> D 的路径,只有距离为 1 的路径。此外,没有 spaths 的证据。你能提供更多细节吗?另外,您能补充一下我的特定 DLV 问题吗?
  • 来自作者的书 (distribution/docs/manualDES.pdf), Note that the infinite computation that may raise from using the built-in is/2 is avoided by limiting the total length of a path to the number of edges in the graph.。所以我认为是的,count 就像它的名字所暗示的那样。对于这个问题,它是一个常数,不会改变任何数据
  • 抱歉,我没有可用的 DLV,所以帮不上忙……如果您有兴趣,SWI-Prolog 有表格,我认为 - 可以运行上述 DES 基本不变。比较会很有趣...
  • 再次感谢您的回复。我已经能够毫不费力地使代码适应我的需要。我将根据您的输入在 DLV 中发布解决方案 :-)
猜你喜欢
  • 2016-06-25
  • 2014-04-14
  • 2019-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-05
  • 2012-10-24
  • 1970-01-01
相关资源
最近更新 更多