Я хотел бы упомянуть эту проблему является типичным ограничения удовлетворения проблема и может быть эффективно решена с использованием модуля CSP SWI-Prolog.Вот полный алгоритм:
:- use_module(library(clpfd)).
color(red).
color(blue).
color(green).
vertex(a).
vertex(b).
vertex(c).
vertex(d).
vertex(e).
edge(a,b).
edge(a,c).
edge(b,c).
edge(b,d).
edge(c,d).
colorGraph(ColorList) :-
findall((X, Y), edge(X, Y), Edges),
findall(X, vertex(X), Vertexes),
findall(hasColor(X, _), member(X, Vertexes), ColorList),
createConstraint(Edges,ColorList),
colorNodes(ColorList).
createConstraint([],_).
createConstraint([(V1,V2)|RL],ColorList):-
member(hasColor(V1,C1),ColorList),
member(hasColor(V2,C2),ColorList),
dif(C1,C2),
createConstraint(RL,ColorList).
colorNodes([]).
colorNodes([hasColor(_,C)|Nodes]) :-
color(C),
colorNodes(Nodes).
color/1
показывает цвета, доступные, vertex/1
показывает вершины на графике и edge/2
определяет пары между вершинами. Кроме того, colorGraph(?List)
определяет цвет вершин, где List
- это список hasColor(Vertex, Color)
, Vertex
- цветная вершина с использованием Color
.
Давайте рассмотрим каждую часть алгоритма выше, чтобы понять, что происходит.
:- use_module(library(clpfd)).
Это указывает на то, чтобы SWI-Prolog загрузить модуль, содержащий предикаты для задач удовлетворения ограничений.
colorGraph(ColorList) :-
findall((X, Y), edge(X, Y), Edges),
findall(X, vertex(X), Vertexes),
findall(hasColor(X, _), member(X, Vertexes), ColorList),
createConstraint(Edges,ColorList),
colorNodes(ColorList).
предикат colorGraph/1
является точкой входа алгоритма. Он преобразует классы ребер/вершин в списки, ограничивает ColorList
, чтобы иметь список определенных вершин и, наконец, создавать ограничения на цвета и назначать цвета (это две отдельные операции).
createConstraint([],_).
createConstraint([(V1,V2)|RL],ColorList):-
member(hasColor(V1,C1),ColorList),
member(hasColor(V2,C2),ColorList),
dif(C1,C2),
createConstraint(RL,ColorList).
predictate createConstraint/2
просто заявляет, что два связанных Вершины должны иметь другой цвет. Стоит отметить, что dif/2
является предикатом CSP.
colorNodes([]).
colorNodes([hasColor(_,C)|Nodes]) :-
color(C),
colorNodes(Nodes).
Предикат colorNodes/1
присваивает правильный цвет вершин. Prolog собирается позаботиться о назначении правильных цветов на основе ограничений, определенных выше.
Наконец, результаты могут быть найдены с помощью вызова предиката colorGraph/1
, такие как:
?- colorGraph(L).
L = [hasColor(a, red), hasColor(b, blue), hasColor(c, green), hasColor(d, red), hasColor(e, red)] ;
L = [hasColor(a, red), hasColor(b, blue), hasColor(c, green), hasColor(d, red), hasColor(e, blue)] ;
L = [hasColor(a, red), hasColor(b, blue), hasColor(c, green), hasColor(d, red), hasColor(e, green)] ;
L = [hasColor(a, red), hasColor(b, green), hasColor(c, blue), hasColor(d, red), hasColor(e, red)] ;
L = [hasColor(a, red), hasColor(b, green), hasColor(c, blue), hasColor(d, red), hasColor(e, blue)] ;
L = [hasColor(a, red), hasColor(b, green), hasColor(c, blue), hasColor(d, red), hasColor(e, green)] ;
L = [hasColor(a, blue), hasColor(b, red), hasColor(c, green), hasColor(d, blue), hasColor(e, red)] ;
L = [hasColor(a, blue), hasColor(b, red), hasColor(c, green), hasColor(d, blue), hasColor(e, blue)] ;
L = [hasColor(a, blue), hasColor(b, red), hasColor(c, green), hasColor(d, blue), hasColor(e, green)] ;
L = [hasColor(a, blue), hasColor(b, green), hasColor(c, red), hasColor(d, blue), hasColor(e, red)] ;
L = [hasColor(a, blue), hasColor(b, green), hasColor(c, red), hasColor(d, blue), hasColor(e, blue)] ;
L = [hasColor(a, blue), hasColor(b, green), hasColor(c, red), hasColor(d, blue), hasColor(e, green)] ;
L = [hasColor(a, green), hasColor(b, red), hasColor(c, blue), hasColor(d, green), hasColor(e, red)] ;
L = [hasColor(a, green), hasColor(b, red), hasColor(c, blue), hasColor(d, green), hasColor(e, blue)] ;
L = [hasColor(a, green), hasColor(b, red), hasColor(c, blue), hasColor(d, green), hasColor(e, green)] ;
L = [hasColor(a, green), hasColor(b, blue), hasColor(c, red), hasColor(d, green), hasColor(e, red)] ;
L = [hasColor(a, green), hasColor(b, blue), hasColor(c, red), hasColor(d, green), hasColor(e, blue)] ;
L = [hasColor(a, green), hasColor(b, blue), hasColor(c, red), hasColor(d, green), hasColor(e, green)] ;
Вы не хотите идти к неокрашенной вершине, а затем выбрать цвет, который не используется какой-либо соседней вершины ? –
Я начинаю не с цветных вершин, хотя, конечно, лучше назначить цвет для первого и сделать то, что вы говорите. – Tino
Можете ли вы уточнить, что у вас есть? –