【问题标题】:How to find direct path between two nodes in a graph in Prolog?如何在Prolog的图中找到两个节点之间的直接路径?
【发布时间】:2021-12-04 16:19:38
【问题描述】:

我是 Prolog 的新手,我正在尝试编写一个谓词,它将两个节点和一个图形作为它的参数,然后检查图形中这两个节点之间是否存在直接路径。

例如,下图中有一条从n(1)n(4) 的直接路径,即从n(1)n(3) 和从n(3)n(4)

g[n(1), n(4), g([n(1), n(2), n(3), n(4), n(5), n(6), n(7), n(8)],
[e(n(1), n(2)), e(n(1), n(3)), e(n(3), n(4)), e(n(4), n(5)), e(n(5), n(6)), e(n(5), n(7)), e(n(7), n(8))]))

最后

?− dirPath(n(1), n(4), g[n(1), n(4), g([n(1), n(2), n(3), n(4), n(5), n(6), n(7), n(8)],
[e(n(1), n(2)), e(n(1), n(3)), e(n(3), n(4)), e(n(4), n(5)), e(n(5), n(6)), e(n(5), n(7)), e(n(7), n(8))]))

应该返回true.

我的暂定代码如下所示:

edge(n(1),n(2)).
edge(n(1),n(3)).
edge(n(3),n(4)).
edge(n(4),n(5)).
edge(n(5),n(6)).
edge(n(5),n(7)).
edge(n(7),n(8)).

dirPath(A,B, g) :-   % - graph argument still missing.
  move(A,B,[])       % - two nodes are connected,
  .                  % - if one can move from one to the other,

move(A,B,V) :-       % -  and one can move from A to B
  edge(A,X) ,        % - if A is connected to X, and
  not(member(X,V)) , % - one hasn't yet reached X, and
  (                  % - either
    B = X            % - X is the desired destination
  ;                  %   OR
    move(X,B,[A|V])  % - one can get to that destination from X
  )                  
  .                

我的主要问题是我不知道如何让我的 dirPath 谓词接受一个图形,因为它是参数。

【问题讨论】:

    标签: graph prolog


    【解决方案1】:

    首先,这个:

    g[n(1), n(4), g([n(1), n(2), n(3), n(4), n(5), n(6), n(7), n(8)],
    [e(n(1), n(2)), e(n(1), n(3)), e(n(3), n(4)), e(n(4), n(5)), e(n(5), n(6)), e(n(5), n(7)), e(n(7), n(8))]))
    

    不是有效的语法。一个术语不能以g[... 开头。这应该是g([...

    其次,表示并不完全直观。 n(1)n(4)的特殊作用是什么?为什么有一个内部的g(...) 术语?

    尽管如此,哪个部分应该是边缘是很清楚的。让我们定义一个谓词来仅访问边:

    graph_edges(Graph, Edges) :-
        Graph = g(_Something, _SomethingElse, g(_Nodes, Edges)).
    

    然后从图中选择一条边:

    graph_edge(Graph, Edge) :-
        graph_edges(Graph, Edges),
        member(Edge, Edges).
    

    然后您可以像这样将其合并到您的谓词中:

    dirPath(A, B, Graph) :-
        move(A, B, Graph, []).
    
    move(A, B, Graph, Vs) :-
        graph_edge(Graph, e(A, X)),
        ...
    

    请注意,我将您的变量 V 更改为 Vs。单字母变量名通常不是很好(FromTo 在我看来比 AB 更清晰)。 lists 的单字母变量名特别少见;常见的约定是为列表添加s(如英文复数形式,visited nodes)。对于图表,尤其建议这样做,因为简单的V 可以很好地解释为单个“顶点”。

    (未测试解决方案。)

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多