在prolog中遍历无向图

时间:2010-10-19 17:24:31

标签: graph prolog

3 个答案:

答案 0 :(得分:2)

这里有一些指示: 要建模无向图,你不需要事实'node',只需要事实'arc'。 你想用'arc'来确认什么,以及两个节点之间有一个弧。所以你只需要像

这样的东西
arc(1, 2).
arc(1, 4).
...

现在,根据您对Path的定义,如果存在从X到Y的总路径权重为A的路径,您似乎希望查询成功。 如果你正在处理可以用这样的谓词表达的有向图:

path(X, Y, 1):- arc(X, Y).
path(X, Y, A):- arc(X, Z), Z\=Y,
                path(Z, Y, A1),
                A is A1+1.

但请注意,如果图形是循环的,这可能会导致无限循环。 为避免此问题,您可能希望跟踪访问的节点,以便您几乎每个节点访问一次:

path(X, Y, A):- path(X, Y, [X], A).

path(X, Y, _, 1):- arc(X, Y).
path(X, Y, Visited, A):-  arc(X, Z),
                          not(member(Z, Visited)),
                          path(Z, Y, [Z|Visited], A1),
                          A is A1+1.

现在可以对这个算法进行简单修改以处理无向图,只添加一个子句。

答案 1 :(得分:1)

感谢您指点我正确的方向。我已经修改了一些代码以实现遍历无向图的目标:

path(X, Y, A):-  % this method allows user to input a path to be checked
   path(X, Y, [X], A). % this is to ensure a list exists, to determine visited nodes later.

member(X,[X|_]). % X can be head of list.
member(X,[_|Tail]) :-
   member(X,Tail). %X can be tail of list, regardless of what the head is.

path(X, Y, Visited, A):- 
   (  arc(X,Y), A is 1
   ;  not(arc(X,Y)),
      arc(X, Z),
      not(member(Z,Visited)),
      path(Z, Y, [Z|Visited], A1),
      A is A1+1
   ).  
% this method checks if a direct/indirect path exists between X,Y in undirected graph

我仍然觉得我还没有很好地掌握递归。除了更多cse :)的实践之外,我将非常感谢能够更好地理解它。

感谢您的帮助!

答案 2 :(得分:0)

感谢你指出我犯的错误(1 == 2),kaarel并感谢答案gusbro。

Gusbro,我想澄清是否确实创建了一个无向图。

这是我写的创建无向图的原因。

弧(1,2)。

弧(2,1)。

弧(1,4)。

弧(4,1)。

弧(2,3)。

弧(3,2)。

弧(3,5)。

弧(5,3)。

弧(5,6)。

弧(6,5)。

因此路径(1,4)应该显示1; 4;没有。其中1是节点1,4和4之间的直接路径是节点1-2-3-5-4的路径。

但它没有发生。相反,我得到

A = 1;

A = 3;

A = 5;

A = 7;

A = 9;

A = 11

不确定为什么?