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
构建我们基于布尔逻辑的传播器(以非有效方式) - [
row
和clause
根据我们想要的返回一维索引 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]]
与您的原始任务相比,结果令人惊讶地看起来是正确的;-):>
以上是关于ABC拼图约束满足问题的主要内容,如果未能解决你的问题,请参考以下文章