Prolog中非定向平面图的着色

时间:2016-01-10 16:20:23

标签: graph prolog graph-coloring

我有一个用3种颜色着色图的程序,相邻的节点需要有不同的颜色。

我的问题是,它只适用于有向图,当我使用非有向图时,它在堆栈溢出时失败。我知道有一些错误,你能帮忙吗? 我让它适用于非有向图?

最后findall/3也存在问题。我需要将其更改为查找所有节点,而不仅仅是edge(V,_)的节点,但我不确切知道如何做到这一点。 我是初学者,我需要解决方案很简单。感谢。

edge(1,2).
edge(2,3).
edge(2,4).
edge(3,4).

%for making the non-oriented graph I tried to use nonedge(X, Y) :- edge(X, Y).
%                                                 nonedge(X, Y) :- edge(Y, X).

color(blue).                                
color(red).
color(green).

coloring([V-C]) :-
   color(C),
   \+ edge(V,_).
coloring([V-C,V1-C1|Coloring]) :-
   color(C),
   edge(V, V1),
   V \== V1,
   coloring([V1-C1|Coloring]),
   C1 \== C.

colors(X) :-                      
   coloring(X),
   findall(V, edge(V,_), List),
   length(List, Len),
   length(X, Len).

2 个答案:

答案 0 :(得分:2)

在这个答案中,我们表示的图形数据与OP描述的方式不同。

相反,图表是成对列表Id-Neibs,其中Neibs是相邻节点Id的列表,由类型检查谓词{{1}定义(在答案的最后显示)。

要为图表着色,我们使用

is_graph/1

使用SWI-Prolog 8.0.0的示例查询:

:- use_module(library(clpfd)).

graph_coloring(G0, Zs) :-
   (  is_graph(G0)
   -> maplist(node_augmented_color, G0, G, Zs),
      maplist(agraph_coloring_outer(G), G)
   ;  throw(error(domain_error(graph,G0),_))
   ).

node_augmented_color(ID-Neibs, t(ID,Color,Neibs), Color).

agraph_coloring_outer(G, t(_,Color_v,Neibs_v)) :-
   maplist(agraph_coloring_inner(G,Color_v), Neibs_v).

agraph_coloring_inner(G, Color_x, Id_y) :-
   member(t(Id_y,Color_y,_), G),
   Color_x #\= Color_y.

要定义类型检查?- graph_coloring([1-[2],2-[1,3,4],3-[2,4],4-[2,3]], Zs), Zs ins 1..3, labeling([], Zs). Zs = [1,2,1,3] ; Zs = [1,2,3,1] ; Zs = [1,3,1,2] ; Zs = [1,3,2,1] ; Zs = [2,1,2,3] ; Zs = [2,1,3,2] ; Zs = [2,3,1,2] ; Zs = [2,3,2,1] ; Zs = [3,1,2,3] ; Zs = [3,1,3,2] ; Zs = [3,2,1,3] ; Zs = [3,2,3,1] ; false. (基于iwhen/2distinct/1),请写:

is_graph/1

答案 1 :(得分:0)

代码也不适用于循环。它只检查前一个是不一样的。但在你的例子中,2 -> 3 -> 4 -> 2 -> ..永远不会结束。

此外,如果图表断开连接,它将永远不会返回整个图表。

出于这两个原因,我建议采用完全不同的方法,首先找到所有独特的顶点。然后为它们指定一种颜色,并检查先前设置的颜色是否与设定的颜色冲突。

colors(Colored) :-
        findall(U,edge(U,_),Vertices), 
        list_to_set(Vertices, UniqueVertices), %% find all unique vertices
        coloring(UniqueVertices,[], Colored). %% color them

着色谓词看起来像:

coloring([],Acc,Acc). %% base case for empty list
coloring([H|T],Acc,AccRes) :-
    color(C), %% pick a valid color
    not((edge(H, V), member(V-C,Acc))), %% No linked vertex should have the same color
    coloring(T,[H-C|Acc],AccRes). %% Color the rest of the vertices

此代码使用accumulator来保存先前设置的顶点颜色组合。