首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无clpfd prolog中的sudoku求解器

无clpfd prolog中的sudoku求解器
EN

Stack Overflow用户
提问于 2017-01-30 14:13:12
回答 1查看 2.6K关注 0票数 1

我有一个AI项目,在这个项目中,我应该在Prolog中制作一个sudoku解算器,但不使用clpfd包。我应该如何编写代码,并且在变量获得值时是否有任何方法进行打印?

EN

回答 1

Stack Overflow用户

发布于 2017-01-30 17:13:15

没有clpfd,您必须编写一个经典的生成和测试搜索。clpfd的好处是约束限制了搜索空间。不过,您可以在不使用clpfd的情况下进行仿真。让我们简化一下任务,这样我就可以说明了。如何找到解这两个方程的X和Y值:X+Y= 10,2*X +Y-1= 15?

首先,对两个方程进行编码:

代码语言:javascript
运行
复制
eq1(X,Y) :- 10 is X + Y.
eq2(X,Y) :- 15 is 2*X + Y - 1.

现在,在求解器谓词中创建搜索空间:

代码语言:javascript
运行
复制
solution(X, Y) :- 
  between(1, 10, X), between(1, 10, Y),
  eq1(X,Y),
  eq2(X,Y).

现在您可以运行它并看到:

代码语言:javascript
运行
复制
?- solution(X,Y).
X = 6,
Y = 4 ;
false.

这比clpfd的效率要低,因为clpfd会注意到一些有助于约束搜索空间的方程:

代码语言:javascript
运行
复制
?- [library(clpfd)].
true.

?- X + Y #= 10, 2*X + Y - 1 #= 15.
2*X+Y#=16,
X+Y#=10.

?- X + Y #= 10, 2*X + Y - 1 #= 15, X in 1..10.
X = 6,
Y = 4.

你看,它已经知道只有一个解决方案,我根本不需要约束Y。太令人印象深刻了!但是您仍然可以不使用clpfd使用Prolog,更糟糕的是。)在本例中,我们可能尝试了所有10x10=100可能的组合来找到这个解决方案。效率不高。但也不是不可能。

那么,对于sudoku,你需要找出哪些约束条件呢?可能是这样的:

代码语言:javascript
运行
复制
unique(Row) :- sort(Row, Sorted), length(Row, Length), length(Sorted, Length).
all_digits(Row) :- forall(between(1,9,X), memberchk(X, Row)).

以此类推。

编辑:组合复杂度估计

假设我们做了一个完全没有原则的搜索:也就是说,我们甚至尝试明显错误的情况,就像所有9的网格一样。我们有9x9=81细胞和9个可能的值(1-9)。这将产生9^81 =一个非常大的数字,在您的一生中不太可能被检查。而这些网格中的大部分都将是无效的排列。

假设限制搜索,使每一行都是1-9的排列。一共有9个!1-9的排列;有了其中的9,你可以将结果乘以9,所以应该有9!^9。这仍然很可怕!通过组合3x3网格约束,clpfd可能会进一步降低效率;我不确定我将如何手动完成这一工作,除非采用半过程的方式,选择3x3网格排列,然后将其中的每一行传递给下一个3x3网格选择。

值得注意的是,经典Prolog程序中的大多数优化都可以归结为要么让生成步骤生成更好的合格候选人,要么使测试步骤更便宜。更明显的实现对于检查更复杂的实现仍然是有用的。

感谢@mat检查我的数学和推荐这篇关于数独组合问题的优秀文章

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41938013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档