【问题标题】:Graph Coloring Problem in Prolog : Program not terminatingProlog中的图形着色问题:程序未终止
【发布时间】:2020-03-17 08:18:33
【问题描述】:
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 来终止。只需要进行一个小的更正。请帮帮我。

【问题讨论】:

    标签: prolog graph-coloring


    【解决方案1】:

    关于您的代码的一些注释:

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

      改为使用hasEdge(X,Y) :- edge(X,Y) ; edge(Y,X).

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

    • 您对检查的定义没有提供肯定的情况。你说:当顶点XY之间有一条边使得着色列表ZXth和Yth元素相等时,则失败。但是当这个条件不成立时,你没有办法让check 为真,所以这条路径也会失败。为此,在check 规则之后添加check(Z). 声明(类似于你如何定义not 谓词,请参阅here)。甚至更短,您可以完全删除失败路径,只需在 colorize 的定义中使用 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,!,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])).
    

    【讨论】:

    • 谢谢!刚刚想通了,即使我们删除了边缘(X,Y):-edge(Y,X)。完美地工作。是的,原因是正确的,它正在经历无限循环。如果可能,请对问题进行投票,以便许多人得到正确的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多