是一个很好的语言来解决数独或类似扫雷的难题

问题描述 投票:0回答:1

我意识到我写的这个就像一个家庭作业问题,但那是因为这是我理解并试图传达问题的最简单方法。这是我想要为个人项目解决的问题。


我有一个网格布局,我从一个2x2网格的简单情况开始,但希望能够最终推断到更大的n×n网格。

卡片都朝下,打印在卡片的面上是:

  1. 正非零整数,代表卡片的“得分”
  2. 或黑点。

我获得了每行得分总和,每行黑点数,每列得分总和以及每列黑点数的信息。

enter image description here

所以最上面一行的总分必须为1,而且其中一张牌就是黑点。

最右边的列必须具有2的总分,并且恰好其中一个卡是黑点。

等等。

当然我们可以看到上面的网格将“解决”到

enter image description here


现在我想创建一个输入给定信息的函数,并生成满足这些约束的卡片网格。

我想我可以使用类似元组的参数。

enter image description here

然后网格中的每个“单元格”或卡片本身就是一个元组,元组的第一个元素将是那里的卡片的分数(如果是黑点则为0),如果是黑色,则第二个元素将为1卡是黑点,否则为0。

enter image description here

所以网格必须类似于^^

通过求解这个方程组,我可以找出所有ab变量是什么:

enter image description here

(也知道所有这些数字都是≥0的整数)。


我想把这个问题用作prolog的学习练习,我认为这似乎是一个问题Prolog会优雅地解决。

我做出了一个好的决定还是Prolog不是一个好的选择?

我想知道如何在Prolog中实现这一点。

prolog sudoku
1个回答
0
投票

Prolog非常适合这类问题。看看clp(fd),即有限域中的约束逻辑编程。

这个片段显示了如何解决SWI Prolog中的初始2x2示例的原始方法:

:- use_module(library(clpfd)).

 test(Vars) :-
    Vars = [TopLeft, TopRight, BottomLeft, BottomRight],
    global_cardinality([TopLeft, TopRight],       [0-1,1-_,2-_]), TopLeft + TopRight #= 1,
    global_cardinality([TopLeft, BottomLeft],     [0-1,1-_,2-_]), TopLeft + BottomLeft #= 1,
    global_cardinality([BottomLeft, BottomRight], [0-1,1-_,2-_]), BottomLeft + BottomRight #= 2,
    global_cardinality([TopRight, BottomRight],   [0-1,1-_,2-_]), TopRight + BottomRight #= 2,
    label(Vars).

查询:

?- test(Vars).
Vars = [1, 0, 0, 2].

您可以将此作为起点并进行概括。请注意,黑点表示为0,因为clp(fd)仅处理整数。

这是文档:http://www.swi-prolog.org/man/clpfd.html

© www.soinside.com 2019 - 2024. All rights reserved.