我试图使用图表中边缘的信息。我想从图中的边缘创建一个节点列表。例如:
? - 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很新,并希望得到帮助。
答案 0 :(得分:1)
without a knowledge base
是一个奇怪的陈述。如果你有一些edge / 2,你可以使用snippet轻松收集所有节点标识符:
nodes(Ns) :- setof(N, M^(edge(N, M) ; edge(M, N)), Ns).
编辑根据评论中的代码,我建议
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].
答案 1 :(得分: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 :(得分:1)
通过使用member/2
目标的辅助谓词来避免对setof/3
的双重调用的性能损失,可以改进Carlo的解决方案。例如:
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
).
这种替代方案还提高了可读性(但是以增加一个辅助谓词为代价)。