Prolog中的图形着色问题:程序未终止

问题描述 投票:0回答:1
vertex(1).
vertex(2).
vertex(3).
vertex(4).

color(1).
color(2).
color(3).

edge(1,2).
edge(1,3).
edge(1,4).
edge(2,4).
edge(3,4).
edge(X,Y):-edge(Y,X).

getelement(1,[Z|_],Z).
getelement(X,[Z|Zs],M):-K is X-1,getelement(K,Zs,M).

check(Z):-edge(X,Y),getelement(X,Z,M),getelement(Y,Z,N),M=:=N,!,fail.


getcolor(1,red).
getcolor(2,blue).
getcolor(3,green).


colorit([A,B,C,D]):-color(A),color(B),color(C),color(D),write([A,B,C,D]),check([A,B,C,D]),write([A,B,C,D]).

这是我的代码。它没有被终止的问题。但是代码中的逻辑很明确,如果您发现问题所在,请帮助我纠正。

输入:-colorit(Z)。

output:- [1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 1, 3]
[1, 1, 2, 1]
[1, 1, 2, 2]
[1, 1, 2, 3]
[1, 1, 3, 1]
[1, 1, 3, 2]
[1, 1, 3, 3]
[1, 2, 1, 1]
[1, 2, 1, 2]
[1, 2, 1, 3]
[1, 2, 2, 1]
[1, 2, 2, 2]
[1, 2, 2, 3]

直到这里[1,2,2,3]才是真正的解决方案,它处于循环中,不会因返回true而终止。只需要进行一些小的更正。请帮帮我。

graph prolog swi-prolog state-space graph-coloring
1个回答
0
投票

关于代码的一些说明:

  • 规则edge(X,Y):-edge(Y,X).创建无限搜索树。

    代替使用hasEdge(X,Y) :- edge(X,Y) ; edge(Y,X).

    这表示当hasEdge(X,Y)edge(X,Y)为真时,edge(Y,X)为真。然后用edge替换check谓词中hasEdge的用法。

  • 您的支票定义不提供肯定的理由。您说:当顶点XY之间有一条边使得着色列表X的第Y和第Z个元素相等时,则失败。但是,如果不满足此条件,则无法提供check为真的方式,因此此路径也会失败。为此,在您的check(Z).规则中添加check声明after(类似于您如何定义not谓词,请参见here)。甚至更短,您可以完全删除失败路径,而在not的定义中仅使用colorize

基于这些观察,可以将您的程序重写为(我跳过了事实):

hasEdge(X,Y):-edge(X,Y) ; edge(Y,X).

getelement(1,[Z|_],Z).
getelement(X,[Z|Zs],M):-K is X-1,getelement(K,Zs,M).

check(Z):-hasEdge(X,Y),getelement(X,Z,M),getelement(Y,Z,N),M=:=N,!,fail.
check(Z).

colorit([A,B,C,D]):-color(A),color(B),color(C),color(D),check([A,B,C,D]).

或使用not

hasEdge(X,Y):-edge(X,Y) ; edge(Y,X).

getelement(1,[Z|_],Z).
getelement(X,[Z|Zs],M):-K is X-1,getelement(K,Zs,M).

check(Z):-hasEdge(X,Y),getelement(X,Z,M),getelement(Y,Z,N),M=:=N.

colorit([A,B,C,D]):-color(A),color(B),color(C),color(D),not(check([A,B,C,D])).
© www.soinside.com 2019 - 2024. All rights reserved.