ABC拼图约束满足问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABC拼图约束满足问题相关的知识,希望对你有一定的参考价值。

ABC是在5x5的木板上的逻辑难题。在每一行和每一列中,必须正好有3个字母(A,B,C)和2个空单元格。此外,对于每一行和每一列,都有关于哪个是该行/列中的第一个字母的信息。这并不意味着这是第一个单元格中的字母,而是行中的第一个字母(第一个字母之前可以有空格)。 This是带有其信息的板。

我需要帮助找出每行和每列中第一个字母的约束。

我已经对每一行和每一列都有约束,但是只是无法弄清楚如何找到行或列中第一个字母的确切位置。这是我到目前为止所拥有的。

*注意,我将1,2,3用于A,B,C,并且我将“ _”(单个空格)和“ __”(双倍空格)用于空单元格,以便仍保留在'AllDifferentConstraint'中。

from constraint import *

if __name__ == "__main__":

problem = Problem(BacktrackingSolver())

variables = []
for i in range(0, 25):
    variables.append(i)
domain= []
for i in range(1,4):
    domain.append(i)

domain.append("_")
domain.append("__")

problem.addVariables(variables, domain)

for row in range(5):
    problem.addConstraint(AllDifferentConstraint(), [row * 5 + i for i in range(5)])

for col in range(5):
    problem.addConstraint(AllDifferentConstraint(), [col * 5 + i for i in range(5)])


solution = problem.getSolution()
print(solution)
答案

免责声明:

  • 我的代码可能看起来有点过分设计
  • 对于最近正在处理大量CP东西的人,该库的可用约束集看起来很奇怪和/或不完整(与工业强度Gecode相比)
    • 我认为此解决方案是骇客(但足以解决这个玩具问题)
  • 我保留了您的大部分代码,但将空格更改为数字(8,9)以实现更好的可视化

基本思路假设维度是先验固定的,那么从slice of front] ::进行查找时,正好有5种有效约束条件

0: _  __ TARGET ...dontcare
1: __ _  TARGET ...dontcare
2: _  TARGET    ...dontcare
3: __ TARGET    ...dontcare
4: TARGET       ...dontcare

作为从SAT解算(在CP之前)来的人,我觉得子句

的推理很自然。上面的内容很容易用布尔逻辑表示(与上面的顺序不同):
   (  pos0 = F                  )
OR ( (pos0 = _ )  and (pos1 = F) )
OR ( (pos0 = __)  and (pos1 = F) )
OR ( (pos0 = __) and (pos1 = _  ) and (pos2 = F)
OR ( (pos0 = _ )  and (pos1 = __ ) and (pos2 = F)

通常,人们会使用一个实施良好的约束/传播器(使用SAT技术,但该库缺少通常的东西。

但是为了拯救我们:FunctionConstraint

允许我们构建一个简单的传播器。这实际上是一个不错的设计(针对较小且相对容易解决的问题)!

一些说明:

  • [clause构建我们基于布尔逻辑的传播器(以非有效方式)
  • [rowclause根据我们想要的返回一维索引
  • reverse让我们在约束需要从头开始(而不是从头开始)操作时重用逻辑。
  • 我们使用部分函数应用程序
  • 使调用紧凑
  • numpy只是用作快速的可视化工具(没有什么比从dict
  • 推断矩阵解更糟糕了]

    代码

""" ORIGINAL CODE """

from constraint import *

problem = Problem(BacktrackingSolver())

variables = []
for i in range(0, 25):
    variables.append(i)
domain= []
for i in range(1,4):
    domain.append(i)

domain.append(8)
domain.append(9)

problem.addVariables(variables, domain)

for row in range(5):
    problem.addConstraint(AllDifferentConstraint(), [row * 5 + i for i in range(5)])

for col in range(5):
    problem.addConstraint(AllDifferentConstraint(), [col * 5 + i for i in range(5)])

""" ADDITIONS """

from functools import partial  

def clause(target, p0, p1, p2, p3, p4):
  wildcards = [8, 9]
  return (p0 == target) or                                              
        ( (p0 in wildcards) and (p1 == target) ) or                    
        ( (p0 in wildcards) and (p1 in wildcards) and p2 == target ) 


row = lambda x: [x * 5 + i for i in range(5)]
col = lambda x: [x + i * 5 for i in range(5)]
reverse = lambda x: list(reversed(x))

problem.addConstraint(partial(clause, 3), reverse(row(0))) # C
problem.addConstraint(partial(clause, 2), reverse(row(1))) # B
problem.addConstraint(partial(clause, 3), reverse(row(2))) # C
problem.addConstraint(partial(clause, 1), row(2))          # A
problem.addConstraint(partial(clause, 2), row(3))          # B
problem.addConstraint(partial(clause, 1), col(0))          # A
problem.addConstraint(partial(clause, 2), col(1))          # B
problem.addConstraint(partial(clause, 1), col(3))          # A
problem.addConstraint(partial(clause, 3), reverse(col(0))) # C
problem.addConstraint(partial(clause, 3), reverse(col(2))) # C
problem.addConstraint(partial(clause, 3), reverse(col(3))) # C

""" SOLVE """

solution = problem.getSolution()
print(solution)

""" VISUALIZE """

import numpy as np
matrix = np.zeros((5, 5), dtype=int)
matrix[np.unravel_index(range(5*5), (5,5))] = [solution[i] for i in range(5*5)]
print(matrix)

输出

λ python C:Tmpconstr.py
{10: 9, 13: 3, 11: 1, 12: 2, 0: 9, 3: 1, 5: 1, 8: 2, 15: 9, 18: 8, 14: 8, 20: 3, 23: 9, 1: 2, 2: 8, 6: 9, 7: 3, 16: 2, 17: 3, 4: 3, 9: 8, 19: 1, 22: 8, 21: 2, 24: 1}

[[9 2 8 1 3]
 [1 9 3 2 8]
 [9 1 2 3 8]
 [9 2 3 8 1]
 [3 2 8 9 1]]

与您的原始任务相比,结果令人惊讶地看起来是正确的;-):>

enter image description here

以上是关于ABC拼图约束满足问题的主要内容,如果未能解决你的问题,请参考以下文章

使用代码创建约束 - 出现错误“无法同时满足约束”[重复]

自动刷新android片段,直到满足条件

活动中 TabLayout 内的片段的约束问题

[linux][c/c++]代码片段01

无法同时满足约束 - LayoutConstraints

罗森格兰茨夫人的杰西查询(斑马拼图)在 Prolog 中表达