Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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_Meta Predicate - Fatal编程技术网

Prolog 找到所有可能的路径,无需重新访问

Prolog 找到所有可能的路径,无需重新访问,prolog,meta-predicate,Prolog,Meta Predicate,我需要一个谓词路由,它给出起点和终点之间的所有城市。例如: path(chicago,atlanta). path(chicago,milwaukee). path(milwaukee,detroit). path(milwaukee,newyork). path(chicago,detroit). path(detroit, newyork). path(newyork, boston). path(atlanta,boston). path(atlanta, milwaukee). ?-

我需要一个谓词路由,它给出起点和终点之间的所有城市。例如:

path(chicago,atlanta).
path(chicago,milwaukee).
path(milwaukee,detroit).
path(milwaukee,newyork).
path(chicago,detroit).
path(detroit, newyork).
path(newyork, boston).
path(atlanta,boston).
path(atlanta, milwaukee).

?- routing(chicago,newyork,X).
X=[chicago,milwaukee,newyork];
X=[chicago,detroit,newyork];
X=[chicago,milwaukee,detroit,newyork];
X=[chicago,atlanta,milwaukee,newyork];
X=[chicago,atlanta,milwaukee,detroit,newyork]
我已经试过了,并且一直在重复

routing(FromCity,ToCity,[FromCity|ToCity]) :-
  path(FromCity,ToCity).

routing(FromCity,ToCity,[FromCity|Connections]) :- 
  path(FromCity,FromConnection), 
  path(FromConnection,ToConnection),
  path(ToConnection,ToCity),
  routing(ToConnection,ToCity,Connections).

routing(FromCity,ToCity,[]).
但它只是不断地给予

X=[chicago,milwaukee,newyork];
X=[chicago,chicago,newyork];
X=[chicago,chicago,chicago,newyork]
...
..
有人能告诉我正确的方向吗

如果您确信(根据定义)您的图是非循环的,您可以利用Prolog深度优先搜索简化规则:

routing(FromCity, ToCity, [FromCity, ToCity]) :-
  path(FromCity, ToCity).

routing(FromCity, ToCity, [FromCity|Connections]) :- 
  path(FromCity, ToConnection),
  routing(ToConnection, ToCity, Connections).
这将在回溯时查找所有可用路径:

?- routing(chicago,newyork,X).
X = [chicago, atlanta, milwaukee, newyork] ;
X = [chicago, atlanta, milwaukee, detroit, newyork] ;
X = [chicago, milwaukee, newyork] ;
X = [chicago, milwaukee, detroit, newyork] ;
X = [chicago, detroit, newyork] ;
false.
请注意列表构造的第一种和第二种模式之间的差异:
[FromCity,ToCity]
[FromCity | Connections]
。这是因为
连接
将是一个
列表
,而
ToCity
将是一个原子,当规则成功时


如果图形包含循环,则此代码将循环。您可以参考以获得处理此问题的简单模式。

以下是我的解决方案,它适用于有环或无环的有向图或无向图

它还试图找到所有路径,而无需重新访问

c(1,2).
% ... c(X,Y) means X and Y are connected

d(X,Y):- c(X,Y).
d(X,Y):- c(Y,X).
% Use d instead of c to allow undirected graphs

findPathHelper(_, Begin, [], End):- d(Begin, End).
findPathHelper(Front, Begin, [Next|NMiddle], End):-
    not(member(Begin,Front)),
    d(Begin, Next),
    append([Front,[Begin]], NFront),
    findPathHelper(NFront, Next, NMiddle, End).

findPath(Start, End, Path):-
    findPathHelper([], Start, Middle, End),
    append([[Start],Middle,[End]], Path).

按照下面的步骤进行怎么样

首先,我们选择一个比
path
更好的谓词名称。边怎么样

edge(chicago  , atlanta  ).
edge(chicago  , milwaukee).
edge(milwaukee, detroit  ).
edge(milwaukee, newyork  ).
edge(chicago  , detroit  ).
edge(detroit  , newyork  ).
edge(newyork  , boston   ).
edge(atlanta  , boston   ).
edge(atlanta  , milwaukee).
如上所述,
edge/2
显然不是,否则下面的查询将不会成功

?- edge(X, Y), \+ edge(Y, X).
  X = chicago  , Y = atlanta
; X = chicago  , Y = milwaukee
; X = milwaukee, Y = detroit
; X = milwaukee, Y = newyork
; X = chicago  , Y = detroit
; X = detroit  , Y = newyork
; X = newyork  , Y = boston
; X = atlanta  , Y = boston
; X = atlanta  , Y = milwaukee.
接下来,我们将连接到/2的
定义为
边/2
的对称闭包:

connected_to(X, Y) :- edge(X, Y).
connected_to(X, Y) :- edge(Y, X).
?- path(connected_to, Path, From, To).
; From = To                   , Path = [To]
; From = chicago, To = atlanta, Path = [chicago,atlanta]
; From = chicago, To = boston , Path = [chicago,atlanta,boston]
; From = chicago, To = newyork, Path = [chicago,atlanta,boston,newyork]
...
最后,我们与
连接到/2
一起使用:

connected_to(X, Y) :- edge(X, Y).
connected_to(X, Y) :- edge(Y, X).
?- path(connected_to, Path, From, To).
; From = To                   , Path = [To]
; From = chicago, To = atlanta, Path = [chicago,atlanta]
; From = chicago, To = boston , Path = [chicago,atlanta,boston]
; From = chicago, To = newyork, Path = [chicago,atlanta,boston,newyork]
...
所以。。。对
路径/4
(与
连接到/2
)的最一般查询是否普遍终止

?- path(connected_to, Path, From, To), false. false. % terminates universally
您好,我有一个类似的问题,但我想使用“write”函数来写出程序内部的路径。因此,我只需在函数中调用start和end是否有任何方法来配置上面的示例以使其工作?@Fjodor:由于回溯,您无法可靠地编写路径。尝试在递归调用之后写入(连接)