簡體   English   中英

CLP(FD),地圖着色

[英]CLP(FD), Map Coloring

我試圖在Prolog CLP中編寫地圖着色程序。 這是到目前為止的代碼。 請任何人在這里幫助我。 這里有什么問題。 我想在這里替換maplist函數。 任何幫助表示贊賞。

:- use_module(library(clpfd)).
regions(Rs):-
        Rs = [R1,R2,R3,R4,R5,R6],

        % neighbouring regions have different 
        dif(R1, R2),
        dif(R1, R3),
        dif(R1, R4),
        dif(R1,R6),
        dif(R2, R3),
        dif(R2, R5),
        dif(R3, R4),
        dif(R3,R5),
        dif(R3, R6),
        dif(R4, R5),
        dif(R4, R6),
        maplist(color, Rs).

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

確實是這樣:發布的代碼已經可以在任何提供dif/2 Prolog系統中使用。

但是,將CLP(FD)約束用於此類組合任務時有明顯的優勢。

讓我告訴你我的意思。 首先,這是任務的直接CLP(FD)公式:

regions(Rs):-
        Rs = [A,B,C,D,E,F],
        Rs ins 0..3,
        A #\= B, A #\= C, A #\= D,
        A #\= F, B #\= C, B #\= E,
        C #\= D, C #\= E, C #\= F,
        D #\= E, D #\= F.

我只有:

  • 更改了可讀性變量( R1AR2B等)
  • 用CLP(FD)約束(#\\=)/2替換了dif/2 (#\\=)/2
  • 完全是因為整數 0..3而不是原子,所以CLP(FD)約束完全適用。 請注意,有限域上的任何問題都可以映射為整數 ,因此CLP(FD)約束始終是此類任務的合適選擇。

首先,讓我們嘗試最一般的查詢 ,看看原則上什么樣的答案:

?- regions(Rs).
Rs = [_640, _646, _652, _658, _664, _670],
_640 in 0..3,
_640#\=_670,
_640#\=_658,
_640#\=_652,
_640#\=_646,
etc.

這似乎還可以。 約束求解器以剩余目標作為響應。 另外,我們看到我們的關系終止並且實際上是確定性的 ,這非常令人高興。 標記變量將保留終止行為,因此我們不會在程序的其他部分意外地陷入循環。

我們可以通過標記變量輕松獲得具體的解決方案

?- regions(Rs), label(Rs).
Rs = [0, 1, 2, 1, 0, 3] .

在此,每個整數對應於唯一的顏色。 我將使這些解決方案更易於閱讀,以便更好地閱讀。

現在要說了!

或更確切地說:點!

CLP(FD)約束提供了dif/2 具備的功能,即約束傳播

在這種情況下,我們最初有以下情況:

地圖着色的初始情況

在這里,每個小圓點代表一個顏色,我們可以仍然有可能使用在其所處的區域。 首先,約束求解器沒有排除任何顏色,因此我們在所有區域中找到每個選項。

如果我們僅將一種區域分配為固定顏色,情況將發生巨大變化:

?- regions([A,B,C,D,E,F]), F = 0.
F = 0,
A in 1..3,
A#\=D,
A#\=C,
A#\=B,
D in 1..3,
D#\=E,
C#\=D,
E in 0..3,
C#\=E,
B#\=E,
C in 1..3,
B#\=C,
B in 0..3.

我只添加了一個統一( F = 0 ),這導致約束求解器從所有相鄰區域修剪此選項:

一次分配后剩余的選項

現在,我只再發布一個附加的統一:

?- regions([A,B,C,D,E,F]), F = 0, C = 1.
C = 1,
F = 0,
A in 2..3,
A#\=D,
A#\=B,
D in 2..3,
D#\=E,
E in 0\/2..3,
B#\=E,
B in 0\/2..3.

再次自動執行 (即約束求解器為您完成),刪除了許多其他可能的分配:

在此處輸入圖片說明

僅執行一項戰略任務(我將其作為練習來找出其中一項),就可以得出以下情況:

在此處輸入圖片說明

現在,剩下的唯一選擇就是如何為尚未分配任何固定顏色的單個剩余區域着色。 顯而易見,現在兩種允許的顏色可以解決整個任務。

dif/2也會修剪搜索空間。 但是,CLP(FD)約束對變量的實際執行此功能強大的修剪。 這意味着根本不需要嘗試許多值。 此外,基於此推理,約束求解器可以更智能地選擇接下來標記的變量,從而在許多情況下進一步提高了性能。

您的程序沒有任何問題。 它可以在任何實現dif / 2的Prolog中使用:

?- regions(Rs).
Rs = [red, green, blue, green, red, yellow] ;
Rs = [red, green, blue, green, yellow, yellow] ;
....

您也不需要library(clpfd)。

您還可以使用答案集編程 ,即一些前向鏈接和選擇運算符。 這是一些代碼:

:- use_module(library(basic/lists)).
:- use_module(library(minimal/delta)).

edge(r1, r2).
edge(r1, r3).
edge(r1, r4).
edge(r1, r6).
edge(r2, r3).
edge(r2, r5).
edge(r3, r4).
edge(r3, r5).
edge(r3, r6).
edge(r4, r5).
edge(r4, r6).

:- thread_local color/2, vertex/1.

post(color(X,red)); post(color(X,green));
post(color(X,blue)); post(color(X,yellow)) <= posted(vertex(X)).

fail <= posted(color(X,C)), posted(color(Y,C)), {edge(X,Y)}.

regions(Rs) :-
        post(vertex(r1)),
        post(vertex(r2)),
        post(vertex(r3)),
        post(vertex(r4)),
        post(vertex(r5)),
        post(vertex(r6)),
        maplist(color, [r1,r2,r3,r4,r5,r6], Rs).

上面的代碼是即將發布的1.3.1版的預覽。 以上內容在運行時給出以下結果:

Jekejeke Prolog 3, Runtime Library 1.3.1
(c) 1985-2018, XLOG Technologies GmbH, Switzerland

?- regions(X).
X = [red,green,blue,green,red,yellow] ;
X = [red,green,blue,green,yellow,yellow]
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM