【问题标题】:Create a list of nodes from a graph in Prolog?从 Prolog 中的图表创建节点列表?
【发布时间】:2014-05-08 05:17:33
【问题描述】:

我正在尝试使用图表中边缘的信息。我想从给定图中的边缘创建一个节点列表。例如:

? - graph([edge(1,2),edge(2,3),edge(3,4)],List).
List = [1,2,3,4]

这是一个基本情况:

graph([edge(X,Y)],[X,Y]).

没有知识库,我不知道该怎么做。为什么这不能单独工作?还是这样的?

graph([edge(X,Y)], List) :- append(X,Y,List).

我是 Prolog 的新手,非常感谢您的帮助。

【问题讨论】:

    标签: list recursion prolog graph-theory


    【解决方案1】:

    这是一个仅使用基本 Prolog 的解决方案: 我认为基本情况应该是空图,而不是只有一个元素的图。它没有节点:

    nodes([],[]).
    

    对于每个非空图,收集第一条边的两个节点,然后继续图的其余部分:

    nodes([edge(X,Y)|RestGraph],[X,Y|RestNodes]) :-
      nodes(RestGraph,RestNodes).
    

    此解决方案的问题是您可能在结果中多次出现一个节点。您可以使用 sort/2 消除此类重复:

    nodes2(Graph,Nodes) :- nodes(Graph,Unsorted), sort(Unsorted,Nodes).
    

    CapelliC 的解决方案更加优雅简洁,但对于初学者来说可能更难理解。

    【讨论】:

      【解决方案2】:

      without a knowledge base 是一个奇怪的声明。如果你有一些 edge/2,你可以使用 sn-p 轻松收集所有节点标识符:

      nodes(Ns) :- setof(N, M^(edge(N, M) ; edge(M, N)), Ns).
      

      edit 鉴于评论中的代码,我会建议

      nodes_of_graph(graph(Edges), Ns) :-
        setof(N, M^(member(edge(N, M), Edges) ; member(edge(M, N), Edges)), Ns).
      

      产量

      1 ?- nodes_of_graph(graph([edge(1,2),edge(1,3)]),L).
      L = [1, 2, 3].
      

      【讨论】:

      • 通过知识库,我的意思是我没有一组边缘规则(例如 edge(a,b)、edge(a,c) 等)。也许我使用了错误的术语。如果我说 ?- graph([edge(1,2),edge(1,3)]) 我想创建 [1,2,3]。
      【解决方案3】:

      Carlo 的解决方案可以通过使用setof/3 目标的辅助谓词避免双重调用member/2 的性能损失来改进。例如:

      nodes_of_graph(graph(Edges), Nodes) :-
          setof(Node, edge_node(Edges, Node), Nodes).
      
      edge_node(Edges, Node) :-
          member(edge(Begin, End), Edges),
          (   Node = Begin
          ;   Node = End
          ).
      

      这种替代方法还提高了可读性(但代价是增加了一个辅助谓词)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-01
        • 1970-01-01
        • 2019-03-19
        • 2021-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多