Другим подходом является, во-первых, создание предиката, который идентифицирует допустимый край. Вот простой предикат сделать так, для неориентированных графов:
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
| ?-
Он идентифицирует каждый край с каждым BackTrack. Он использует nth1/3
предиката, который является отношением nth1(N, List, Element)
, что говорит, Element
находится на месте N
в List
, где первый элемент является элемент номер 1
.
Для ориентированных графов, просто удалите условие 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
| ?-
Если вы хотите другой способ, чтобы представить край, а не список [R,C]
в 2-элементный, вам нужно только изменить руководитель пункта от 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
| ?-
Какая вершина '[1,2]' стоит? Может, ты имел в виду края? – VHarisop
Вы правы, исправлено, что –
Вы делали какие-либо попытки? Где вы застряли? Судя по вашему образцу, это неориентированный граф? – lurker