Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从Prolog中的选择中选择最短路径_Prolog_Shortest Path - Fatal编程技术网

如何从Prolog中的选择中选择最短路径

如何从Prolog中的选择中选择最短路径,prolog,shortest-path,Prolog,Shortest Path,我是一名prolog初学者,拥有以下代码,其中列出了从一个给定节点到另一个节点的所有可能路径。每一条边都是双向的,这是需要注意的 nodeLink(1,2,4). nodeLink(1,3,10). nodeLink(1,5,2). nodeLink(2,1,4). nodeLink(2,5,1). nodeLink(2,4,6). nodeLink(2,6,1). nodeLink(3,1,10). nodeLink(3,5,2). nodeLink(3,4,1). nodeLink(4

我是一名prolog初学者,拥有以下代码,其中列出了从一个给定节点到另一个节点的所有可能路径。每一条边都是双向的,这是需要注意的

nodeLink(1,2,4).
nodeLink(1,3,10).
nodeLink(1,5,2).

nodeLink(2,1,4).
nodeLink(2,5,1).
nodeLink(2,4,6).
nodeLink(2,6,1).

nodeLink(3,1,10).
nodeLink(3,5,2).
nodeLink(3,4,1).

nodeLink(4,3,1).
nodeLink(4,5,8).
nodeLink(4,2,6).

nodeLink(5,1,2).
nodeLink(5,2,1).
nodeLink(5,3,2).
nodeLink(5,4,8).

nodeLink(6,2,1).


path([B | BRest], B, [B | BRest], Length, Length).
path([A | ARest], B, Path, CurrentLength, Length) :-
    nodeLink(A, C, X),
    \+member(C, [A | ARest]),
    NewLength is CurrentLength + X,

    path([C, A | ARest], B, Path, NewLength, Length).

all_paths(Start, End) :-
    path([Start], End, Path, 0, Length),
    reverse(Path, RevPath),
    write('Path: '),
    printPath(RevPath),
    write(' with a cost of '),
    writeln(Length),
    fail.

printPath([]).
printPath([X]) :-
    !,
    write(X).
printPath([X|Xrest]) :-
    write(X),
    write(', '),
    printPath(Xrest).
例如:

?- all_paths(6,3).
打印出:

Path: 6, 2, 1, 3 with a cost of 15
Path: 6, 2, 1, 5, 3 with a cost of 9
Path: 6, 2, 1, 5, 4, 3 with a cost of 16
Path: 6, 2, 5, 1, 3 with a cost of 14
Path: 6, 2, 5, 3 with a cost of 4
Path: 6, 2, 5, 4, 3 with a cost of 11
Path: 6, 2, 4, 3 with a cost of 8
Path: 6, 2, 4, 5, 1, 3 with a cost of 27
Path: 6, 2, 4, 5, 3 with a cost of 17
false.
如何为给定的一对节点选择“最短”路径?
谢谢

一般来说,在Prolog中,您不希望使用
write
和故障驱动循环来显示所有解决方案。一种规范的方法是为每个解决方案设置一个成功的谓词(正如
path/5
谓词所做的那样),然后使用
findall/3
bagof/3
setof/3
收集列表中的所有解决方案
setof/3
有消除重复项和对结果集合排序的好处

这里有一个stackoverflow搜索。这已经在这个网站上被报道了很多次了,我不想只选择其中一个。我没有看到使用
setof/3
,所以这里有一个采用这种方法的解决方案

我将使用您现有的
path/5
定义。由于路径集合在设计上是唯一的,因此使用
setof/3
将比使用
findall/3
msort/2
稍有改进,您可以在至少一个链接解决方案中找到这一点。这里的想法是创建一个
成本路径
形式的解决方案列表,按
成本
排序。然后,您需要从列表中选择最低成本,这是自订购以来的第一个元素

shortest_path(Start, End, ShortestPath, ShortestLength) :-
    setof(Length-Path, path([Start], End, Path, 0, Length), [ShortestLength-ShortestPath|_]).
如果您想打印列表,可以使用
maplist

print_path(Cost-Path) :-
    write('Path: '),
    write(Path),
    write(' with a cost of '),
    write(Cost), nl.

print_paths(CostPaths) :-
    maplist(print_path, CostPaths).

其中,
costpath
是上面执行的
setof/3
的结果。

最简单的解决方案是将所有路径存储在一个列表中,然后选择最短路径。不是最优的,但实施速度快,易于管理understand@CFER你可能不接受我的回答。虽然它为枚举提供了有用的概念,但它并不是成本最低路径的最佳解决方案。一个合适的方法是使用。如果“这个网站已经讨论了这么多次”,你为什么不给出一个一劳永逸的明确的、通用的定义呢?@false,它已经被许多不同的方式讨论过了。目前,我不想说我发布的这个变体是其中最好的。@false:有更好的算法来寻找最短路径,所以这里提出的解决方案不应该是确定的解决方案。这样做的真正目的是一次又一次地发布非常相同的临时解决方案吗?@false不,不是。但我不认为这是“完全相同”的临时解决方案。在我的快速搜索中,我没有看到一个与之匹配的,尽管有些是相似的。这就是为什么我贴了它。然而,这并不意味着我的搜索不够彻底。如果你找到一个与我发布的“非常相同”的解决方案,我很乐意删除这个。