另一种方法是,首先,创建一个标识有效边的谓词。对于无向图,这里有一个简单的谓词:
edge(M, [R,C]) :-
nth1(R, M, Row),
nth1(C, Row, 1),
R =< C. % Remove this for directed graphs
这是一个示例查询:
| ?- edge([[0,1,0,0],[1,0,1,1],[0,1,0,0],[0,1,0,0]],Edge).
Edge = [1,2] ? a
Edge = [2,3]
Edge = [2,4]
(1 ms) no
| ?-
它用每个回溯标识每个边。它使用了nth1/3 谓词,即关系nth1(N, List, Element),表示Element 位于List 中的N 位置,其中第一个元素是元素编号@987654328 @。
对于有向图,只需去掉R =< C 条件,即可得到:
| ?- edge([[0,1,0,0],[1,0,1,1],[0,1,0,0],[0,1,0,0]],Edge).
Edge = [1,2] ? a
Edge = [2,1]
Edge = [2,3]
Edge = [2,4]
Edge = [3,2]
Edge = [4,2]
(1 ms) no
| ?-
如果您想用另一种方式来表示一条边而不是 2 元素列表 [R,C],您只需将子句的头部从 edge(M, [R,C]) 更改为,例如,edge(M, R-C):
| ?- edge([[0,1,0,0],[1,0,1,1],[0,1,0,0],[0,1,0,0]],Edge).
Edge = 1-2 ? a
Edge = 2-3
Edge = 2-4
(1 ms) no
| ?-
如果您想将所有边收集到一个列表中,可以使用setof/3:
all_edges(M, Edges) :-
setof(E, edge(M, E), Edges).
| ?- all_edges([[0,1,0,0],[1,0,1,1],[0,1,0,0],[0,1,0,0]],E), Edges).
Edges = [1-2,2-3,2-4]
yes
| ?-