Logic 约束编程:按照图案规则用颜色填充网格

Logic 约束编程:按照图案规则用颜色填充网格,logic,constraint-programming,minizinc,or-tools,Logic,Constraint Programming,Minizinc,Or Tools,我是约束编程新手(来自c#),我正在尝试解决这个问题。不幸的是,我没有这种拼图的名字,所以我不知道该搜索什么。我能找到的最接近的例子是非图解和断层扫描难题 拼图说明: 玩家会得到一个空的游戏板(大小不一),他们必须用n种颜色填充,使用线索模式填充行和列。每个线索模式都是该行/列中的颜色序列,但删除了连续的重复项 下面是一个简单的小4x4网格示例,有3种颜色: rbg,rbr,grb,bgbg <- (top-to-bottom column constraints)

我是约束编程新手(来自c#),我正在尝试解决这个问题。不幸的是,我没有这种拼图的名字,所以我不知道该搜索什么。我能找到的最接近的例子是非图解和断层扫描难题

拼图说明: 玩家会得到一个空的游戏板(大小不一),他们必须用n种颜色填充,使用线索模式填充行和列。每个线索模式都是该行/列中的颜色序列,但删除了连续的重复项

下面是一个简单的小4x4网格示例,有3种颜色:

rbg,rbr,grb,bgbg       <- (top-to-bottom column constraints)

    _,_,_,_     rgb    <- (row constraints)
    _,_,_,_     brg 
    _,_,_,_     b
    _,_,_,_     grbg
??可以是红色或蓝色,但不能是绿色

模式示例如下。 给出了6个长度序列的示例:

aaaaaa -> a
aabbcc -> abc
abbbbc -> abc
cabbbc -> cabc
bbbaac -> bac
abbaab -> abab
abcabc -> abcabc
潜在解决方案序列的模式示例:

abc -> abc (3 length solution)
abc -> abcc, abbc, aabc (4 length solutions)
abc -> abccc, abbcc, abbbc, aabbc, aaabc (5 length solutions)
我曾尝试用C#或tools和Minizing来解决它,但我遇到的最大问题是构建约束。我可以从序列中生成模式(以c#命令式方式),但如何将其转化为约束

我的想法是:从每个线索模式生成所有潜在序列。然后对相应的行/列进行约束,表示它必须是这些序列之一

上面拼图中最上面一行的示例:rgb到[4-长度序列]->rgbb、rggb、rrgb,然后为该行添加一个约束:必须等于这些序列中的一个

我想的对吗?有更聪明的方法吗

谢谢你的建议

=====================================

在取得某些进展后进行编辑:

此迷你锌正确解决了模式abc的顶行,模式abc有3个4长度的解决方案:aabc、abbc、abcc

include "globals.mzn";

array [1..4, 1..4] of var 1..3: colors;

constraint regular(row(colors, 1), 4, 3, 
[|
  % a, b, c
    2,0,0| % accept 'a'
    2,3,0| % accept 'a' or 'b' ?
    0,3,4| % accept 'b' or 'c' ?
    0,0,4| % accept 'c'
|], 1, {4}); 

% Don't care about rest of grid for now.
constraint forall(i,j in 1..4 where i > 1) (row(colors, i)[j] = 1);

solve satisfy;

output [show(colors)]; 

但是,我不知道如何处理具有许多模式的较大网格,而不是像这样硬编码。我将进行更多的实验。

您所讨论的约束似乎很容易表示为正则表达式。例如,可以使用正则表达式
abc.
捕获长度不同的
abc
示例,该正则表达式需要一个
a
然后一个
b
,然后一个
c
,之后它将接受任何其他内容

在Minizing中,这些类型的约束使用表示。正则谓词模拟具有接受状态的自动机。通过提供允许的状态转换,模型是约束的

示例表达式
abc.*
将由以下约束项强制执行:

% variables considered, nr states, input values
constraint regular(VARS, 4, 1..3, [|
    % a, b, c
    2,0,0| % accept 'a'
    0,3,0| % accept 'b'
    0,0,4| % accept 'c'
    4,4,4| % accept all
|], 1, {4}); % initial state, accepting states
在Prolog(语言)中,我使用
DCG
形式来描述此类问题。它是扩展的
BNF
形式。 因此,我建议在您的环境中找到使用扩展BNF表单的方法

SWI Prolog示例:

color_chunk_list(Encoded,Decoded):-
    phrase(chunk_list(Encoded),Decoded),
    chk_continuity(Encoded).

chunk_list([])-->[].
chunk_list([First|Rest])-->colorrow(First),chunk_list(Rest).

colorrow(Color)-->[Color],colorrow(Color).
colorrow(Color)-->[Color].

chk_continuity([First,Second|Rest]):-First \= Second,chk_continuity([Second|Rest]).
chk_continuity([_]).
在这个程序中,编码和解码是双向的

测试:

?- length(L,4),color_chunk_list([r,g],L).
L = [r, r, r, g] ;
L = [r, r, g, g] ;
L = [r, g, g, g] ;
false.

?- length(L,6),color_chunk_list([a,b,c],L).
L = [a, a, a, a, b, c] ;
L = [a, a, a, b, b, c] ;
L = [a, a, a, b, c, c] ;
L = [a, a, b, b, b, c] ;
L = [a, a, b, b, c, c] ;
L = [a, a, b, c, c, c] ;
L = [a, b, b, b, b, c] ;
L = [a, b, b, b, c, c] ;
L = [a, b, b, c, c, c] ;
L = [a, b, c, c, c, c] ;
false.

?- color_chunk_list(L,[a,a,b,b,c,c]).
L = [a, b, c] ;
false.

?- color_chunk_list(L,[b,r,b,r,r,g,g,b]).
L = [b, r, b, r, g, b] ;
false.
在ECLiPSe中,它是基于prolog的CLP系统(不是IDE系统), 上述谓词(
color\u chunk\u list
)可以转换为clp约束
使用
propia
机制,可以生成clp
传播

,这非常有帮助。常规谓词不太正确,但我能够将其编辑为某种工作方式。我将编辑我的原始问题以包括我的进度。目前没有将正则表达式或自动机转换为
正则
谓词的工具。我们很想提供这样一个工具,但我们受到开发时间的限制。我的Minizing模型为非程序解算器生成规则约束,您可能会从中得到一些启发:这是谓词make_自动机完成的工作。注意:它不漂亮,甚至不小…@hakank哇。。。这是非常密集的代码!但我想我理解了构建这些转换表的总体思路。我还发现了另一个对我帮助很大的例子:谢谢!
?- length(L,4),color_chunk_list([r,g],L).
L = [r, r, r, g] ;
L = [r, r, g, g] ;
L = [r, g, g, g] ;
false.

?- length(L,6),color_chunk_list([a,b,c],L).
L = [a, a, a, a, b, c] ;
L = [a, a, a, b, b, c] ;
L = [a, a, a, b, c, c] ;
L = [a, a, b, b, b, c] ;
L = [a, a, b, b, c, c] ;
L = [a, a, b, c, c, c] ;
L = [a, b, b, b, b, c] ;
L = [a, b, b, b, c, c] ;
L = [a, b, b, c, c, c] ;
L = [a, b, c, c, c, c] ;
false.

?- color_chunk_list(L,[a,a,b,b,c,c]).
L = [a, b, c] ;
false.

?- color_chunk_list(L,[b,r,b,r,r,g,g,b]).
L = [b, r, b, r, g, b] ;
false.