【发布时间】:2018-05-26 12:18:19
【问题描述】:
这是我在 Prolog 课程中所做的扩展。在课堂上,我被要求编写一个谓词path(X, Y, N),当且仅存在从节点X 到节点Y 且长度为N 的路径时返回true。给出的是具有相应权重的有向边列表,例如edge(a, b, 3) 和 edge(c, d, 10)。
给定的问题非常简单(只有一些递归和基本情况)。但是,我想也许我可以进一步扩展它。鉴于简单的有向图输入可能包含循环并且仅包含非负权重,那么从给定节点 A 和 B 到 唯一最短路径 的长度是多少。 (通过unique,我的意思是如果从A 到B 存在多个最短路径,则该谓词应返回false。
这是一个包含循环(a,b,c,e,a)的数据库示例。
edge(a, b, 1).
edge(b, c, 2).
edge(c, d, 1).
edge(b, d, 4).
edge(c, e, 1).
edge(e, a, 10).
edge(e, d, 6).
我认为为了满足 unique 条件,我认为应该增加原始的 path/3 谓词以将路径信息也包含为列表(以便稍后比较路径唯一性)。这种新的增强反映在新的path/4 谓词中。
path(X, X, 0, []).
path(X, Y, N, [Y]) :- edge(X, Y, N).
path(X, Y, N, [Z|T]) :- edge(X, Z, N1), N2 is N - N1, N2 > 0, path(Z, Y, N2, T).
path(X, Y, N) :- path(X, Y, N, _).
在这段代码中,我已经发现了一个问题:如果我尝试将谓词与path(a, b, N, Z) 统一,这将不起作用,因为N 将无法与N2 is N - N1 统一。但是,如果我将这部分更改为N is N1 + N2,这仍然不起作用,因为N2 仍然没有统一。如果我将整个谓词行更改为:
path(X, Y, N, [Z|T]) :- edge(X, Z, N1), path(Z, Y, N2, T), N is N1 + N2.
然后这将无休止地运行,因为路径的数量可能是无限的,因为图形可能包含循环(我想尝试保持这种方式作为挑战)。
至于shortestpath/3谓词,我找不到所有路径并检查是否所有路径都更长,因为路径的数量可能由于有一个循环而无限。相反,我试图找到长度在 0 和给定 N 之间的任何路径;如果不存在路径,那么这绝对是最短路径。
countdown(N, N).
countdown(N, X) :- N1 is N - 1, N1 >= 0, countdown(N1, X).
shortestpath(A, B, N) :- path(A, B, N), \+((countdown(N, N1), N > N1, path(A, B, N1))).
但这并不能解决作为变量给出的N(因为倒计时功能不起作用),更不用说唯一约束了。
所以我的问题是,有没有办法让这个问题发挥作用,或者实际上不可能这样做?如果有这样的解决方案,请在此处提供(或者如果您认为这是一个“家庭作业”问题,请至少指导我正确的方向)。
约束:
我不想使用任何内置谓词。例如,只有“简单”或“核心”谓词,例如
\+、is、+。var、nonvar、asserta和类似的谓词在某种程度上也是可以接受的(因为没有替代品可以实现相同的功能)。我希望它尽可能通用;也就是说,谓词的任何参数都应该能够作为变量给出。 (或者至少有
shortestpath/3的最后一个参数,也就是最短路径的长度,一个变量)。
我已经查看了以下问题,但它并没有回答我的情况:
Find the shortest path between two nodes in a graph in Prolog(不处理加权边,也使用复杂的谓词(例如
path/4)。search all paths and the shortest path for a graph - Prolog(不处理带循环的图)。
Find the shortest path between two nodes in a graph in (Prolog) and display the result as array(不处理加权边缘)。
请随时向我指出解决我问题的任何其他问题。
【问题讨论】:
-
您能否提供一个包含循环的数据库的简单示例,用于测试...?
-
可以做到,而且你的做法没有错。在某些方面,你让自己的生活变得比你不得不做的更难; Prolog 的解析算法是深度优先的,而你正在与之抗争,再加上只想返回一个独特的解决方案,最终只是一个卑鄙的小转折。但这是一个绝对可以解决的有趣问题;我敢肯定,其他伟大的头脑已经在研究答案。
-
看看Dijkstra's algorithm。它字面意思就是为此而生的。
标签: prolog unique graph-theory shortest-path