- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试理解N-皇后问题的解决方案,如下所示:
:- use_module(library(clpfd)).
n_queens(N, Qs) :-
length(Qs, N),
Qs ins 1..N,
safe_queens(Qs).
safe_queens([]).
safe_queens([Q|Qs]) :-
safe_queens(Qs, Q, 1),
safe_queens(Qs).
safe_queens([], _, _).
safe_queens([Q|Qs], Q0, D0) :-
Q0 #\= Q,
abs(Q0 - Q) #\= D0,
D1 #= D0 + 1,
safe_queens(Qs, Q0, D1).
safe_queens([]).
safe_queens([Q|Qs]) :-
safe_queens(Qs, Q, 1),
safe_queens(Qs).
safe_queens([], _, _).
safe_queens([Q|Qs], Q0, D0) :-
Q0 #\= Q,
abs(Q0 - Q) #\= D0,
D1 #= D0 + 1,
safe_queens(Qs, Q0, D1).
最佳答案
由于您没有提供任何示例查询,因此从一些示例查询开始,以确定参数和输出格式。
通常,要确定未知代码的参数和输出格式,需要查看代码以了解参数的结构,然后尝试执行示例查询。另外请注意,此代码使用Constraint Logic Programming库clpfd;当我读到它时,我实际上停止了思考syntactic unification并开始考虑constraints。我将其视为Prolog中嵌入的独立系统,而不是其他谓词。您会注意到,在此答案中,即使是Prolog,也经常使用constraint
,并且相当缺少predicate
或rule
。
由于N皇后问题是众所周知的逻辑问题,因此Google的快速搜索(clpfd n queens)出现了SWI-Prolog Example: Eight queens puzzle。请注意,添加了关键字clpfd
对于理解代码的这种变化至关重要。其他编程语言中还有many解决方案。
这给出了一个示例查询n_queens(8, Qs), label(Qs)
,其label/1返回系统生成的变量的值。
这也告诉我们第一个参数是一个正整数,第二个参数是第一个参数的长度列表。
同样,通过之前解决此问题,第一个参数是木板的尺寸,因此1
是1x1
木板,8
是8x8
木板,等等,以及板上的皇后数。
接下来的事情是知道什么是有效的解决方案,或者至少对于一组参数而言是有效的解决方案。
Eight queens puzzle的Wikipedia文章在counting solutions部分提供了该内容。
这表明对于1x1的电路板,有一个解决方案,对于2x2或3x3的电路板,没有解决方案,对于4x4的电路板,有两个解决方案,依此类推。
对于1x1电路板,有一种解决方案。
?- n_queens(1,Qs),label(Qs).
Qs = [1].
?- n_queens(2,Qs),label(Qs).
false.
?- n_queens(4,Qs),label(Qs).
Qs = [2, 4, 1, 3] ;
Qs = [3, 1, 4, 2] ;
false.
Qs = [2, 4, 1, 3]
2
),它读取
a queen in row 2, column 1
,对于列表中的第二个值(
4
) )它读取
a queen in row 4, column 2
Qs = [3, 1, 4, 2]
?- n_queens(N,Qs),label(Qs).
N = 0,
Qs = [] ;
N = 1,
Qs = [1] ;
N = 4,
Qs = [2, 4, 1, 3] ;
N = 4,
Qs = [3, 1, 4, 2] ;
N = 5,
Qs = [1, 3, 5, 2, 4] ;
N = 5,
Qs = [1, 4, 2, 5, 3] ;
N = 5,
Qs = [2, 4, 1, 3, 5] ;
N = 5,
Qs = [2, 5, 3, 1, 4] ;
N = 5,
Qs = [3, 1, 4, 2, 5] ;
N = 5,
Qs = [3, 5, 2, 4, 1] ;
N = 5,
Qs = [4, 1, 3, 5, 2]
...
gtrace/0
开头的SWI-Prolog
trace/0或SWI-PRolog
GUI-tracer将是一种选择的工具,但是在clpfd上使用了它之后,我才知道
Constraint Logic Programming不是首选的工具。试试看,您会明白为什么。
?- n_queens(1,Qs).
Qs = [1].
?- n_queens(2,Qs).
Qs = [_1942, _1948],
_1942 in 1..2,
abs(_1942-_1948)#\=1,
_1942#\=_1948,
_1948 in 1..2.
?- n_queens(2,Qs).
Qs = [A, B],
A in 1..2,
abs(A-B)#\=1,
A#\=B,
B in 1..2.
#
的CLP(FD)运算符,通常是约束条件,例如像普通运算符一样读取
#\=和
#=,而不是
#
`A in 1..2` reads the value for `A` must be in the range `1..2`
`abs(A-B)#\=1` reads the difference of the values between `A` and `B` must not equal 1
`A#\=B` reads the value of `A` must not equal the value of `B`
`B in 1..2` reads the value of `B` must be in `1..2`
0,_ invalid by `A in 1..2`
_,0 invalid by `B in 1..2`
3,_ invalid by `A in 1..2`
_,3 invalid by `B in 1..2`
1,1 invalid by `A#\=B`
1,2 invalid by `abs(A-B)#\=1`
2,1 invalid by `abs(A-B)#\=1`
2,2 invalid by `A#\=B`
?- n_queens(4,Qs).
Qs = [_5398, _5404, _5410, _5416],
_5398 in 1..4,
abs(_5398-_5416)#\=3,
_5398#\=_5416,
abs(_5398-_5410)#\=2,
_5398#\=_5410,
abs(_5398-_5404)#\=1,
_5398#\=_5404,
_5416 in 1..4,
abs(_5410-_5416)#\=1,
_5410#\=_5416,
abs(_5404-_5416)#\=2,
_5404#\=_5416,
_5410 in 1..4,
abs(_5404-_5410)#\=1,
_5404#\=_5410,
_5404 in 1..4.
?- n_queens(4,Qs).
Qs = [A, B, C, D],
A in 1..4, reads the value for `A` must be in the range `1..4`
abs(A-D)#\=3, reads the difference of the values between `A` and `D` must not equal 3
A#\=D, reads the value of `A` must not equal the value of `D`
abs(A-C)#\=2, reads the difference of the values between `A` and `C` must not equal 2
A#\=C, reads the value of `A` must not equal the value of `C`
abs(A-B)#\=1, reads the difference of the values between `A` and `B` must not equal 1
A#\=B, reads the value of `A` must not equal the value of `B`
D in 1..4, reads the value for `D` must be in the range `1..4`
abs(C-D)#\=1, reads the difference of the values between `C` and `D` must not equal 1
C#\=D, reads the value of `C` must not equal the value of `D`
abs(B-D)#\=2, reads the difference of the values between `B` and `D` must not equal 2
B#\=D, reads the value of `B` must not equal the value of `D`
C in 1..4, reads the value for `C` must be in the range `1..4`
abs(B-C)#\=1, reads the difference of the values between `B` and `C` must not equal 1
B#\=C, reads the value of `B` must not equal the value of `C`
B in 1..4. reads the value for `B` must be in the range `1..4`
`A in 1..4` reads the value for `A` must be in the range `1..4`
`B in 1..4` reads the value for `B` must be in the range `1..4`
`D in 1..4` reads the value for `D` must be in the range `1..4`
`C in 1..4` reads the value for `C` must be in the range `1..4`
`A#\=B` reads the value of `A` must not equal the value of `B`
`A#\=C` reads the value of `A` must not equal the value of `C`
`A#\=D` reads the value of `A` must not equal the value of `D`
`B#\=C` reads the value of `B` must not equal the value of `C`
`B#\=D` reads the value of `B` must not equal the value of `D`
`C#\=D` reads the value of `C` must not equal the value of `D`
`abs(A-B)#\=1` reads the difference of the values between `A` and `B` must not equal 1
`abs(A-C)#\=2` reads the difference of the values between `A` and `C` must not equal 2
`abs(A-D)#\=3` reads the difference of the values between `A` and `D` must not equal 3
`abs(B-C)#\=1` reads the difference of the values between `B` and `C` must not equal 1
`abs(B-D)#\=2` reads the difference of the values between `B` and `D` must not equal 2
`abs(C-D)#\=1` reads the difference of the values between `C` and `D` must not equal 1
A in 1..4
A
皇后必须放置在4x4板上的位置。在处理约束问题时,您通常会发现我们作为人类所想当然的东西或对常识的思考需要作为特定的约束给出,以防万一。还学习添加常识规则有时是创建AI解决方案时最困难的任务之一。虽然我找不到参考,但是当
Cyc的创建者添加规则时,时间的概念花了很多时间才能正确(没有双关语)。其余约束(如
A in 1..4
)仅确保没有女王放置在板上。
A#\=B
A
是第1行中的白色皇后,而
B
是第1行中的黑色皇后。由于A不能等于B,这表示如果Queen
A
在第1行中,则Queen
B
不能在第1行中。使用该规则如果使用变量,则表示
A
皇后所在的任何行都不能位于
B
皇后所在的行中。其余约束(如
A#\=B
)仅确保没有两个皇后可以在同一行中。
abs(A-B)#\=1
A
1,2,3,4
有四个位置,但是由于该规则是水平对称的(1等于4,而2等于3),所以我只会做两个。
A
为1。
A
为1,因此
B
不能为2。
1-2 = -1
ABS(-1) = 1
1 can not equal 1.
A
为2。
A
为2,因此
B
不能为1。
2 - 1 = 1
ABS(1) = 1
1 can not equal 1.
A
为2,因此
B
不能为3。
2 - 3 = -1
ABS(-1) = 1
1 can not equal 1.
A
和Queen
D
的约束
abs(A-D)#\=3
A
为1。
A
为1,因此
D
不能为4。
1-4 = -3
ABS(-3) = 3
3 can not equal 1.
A
为2。
A
是2,因此
D
可以是
1
。
2-1 = 1
ABS(1) = 1
1 can not equal 3.
A
是2,因此
D
可以是
2
。
2-2 = 0
ABS(0) = 0
0 can not equal 3.
A
是2,因此
D
可以是
3
。
2-3 = -1
ABS(-1) = 1
1 can not equal 3.
A
是2,因此
D
可以是
4
。
2-4 = -2
ABS(-2) = 2
2 can not equal 3.
[A,B,C,D]
)并将
A
皇后限制到第一列,将
B
皇后限制到第二列,依此类推。再次,这是学习AI编码的要点之一,就是我们作为人类的思维方式并不总是直接转化为如何用计算机解决问题的方式。因此,尽管此代码使用约束来解决问题,但它也使用数据结构。
safe_queens/1
以及递归谓词
safe_queens/3
。
safe_queens([], _, _).
safe_queens([Q|Qs], Q0, D0) :-
Q0 #\= Q,
abs(Q0 - Q) #\= D0,
D1 #= D0 + 1,
safe_queens(Qs, Q0, D1).
safe_queens([], _, _).
safe_queens([H|T], _, _) :-
% Process head of list (H)
safe_queens(T, _, _). % Process tail of list (T)
Q0 #\= Q
abs(Q0 - Q) #\= D0
D1 #= D0 + 1
D1
设置为
D0 + 1
permutations([], _, _).
permutations([Q|Qs], Q0, D0) :-
write(Q0),write('#\\='),writeln(Q),
write('abs('),write(Q0),write('-'),write(Q),write(')#\\='),writeln(D0),
D1 is D0 + 1,
permutations(Qs, Q0, D1).
?- permutations(['B','C','D'],'A',1).
A#\=B
abs(A-B)#\=1
A#\=C
abs(A-C)#\=2
A#\=D
abs(A-D)#\=3
true.
?- permutations(['C','D'],'B',1).
B#\=C
abs(B-C)#\=1
B#\=D
abs(B-D)#\=2
true.
?- permutations(['D'],'C',1).
C#\=D
abs(C-D)#\=1
true.
safe_queens([]).
safe_queens([Q|Qs]) :-
safe_queens(Qs, Q, 1),
safe_queens(Qs).
safe_queens([]).
safe_queens([H|T]) :-
% Process head of list (H)
safe_queens(T). % Process tail of list (T)
safe_queens/3
的助手,因为此语句
safe_queens(Qs, Q, 1)
safe_queens/3
的第三个参数初始化为
1
generate_args([]).
generate_args([Q|Qs]) :-
write('Qs: '),write(Qs),write(', Q: '),write(Q),writeln(', 1'),
generate_args(Qs).
safe_queens/3
所需的参数
?- generate_args(['A','B','C','D']).
Qs: [B,C,D], Q: A, 1
Qs: [C,D], Q: B, 1
Qs: [D], Q: C, 1
Qs: [], Q: D, 1
true.
n_queens(N, Qs) :-
length(Qs, N),
Qs ins 1..N,
safe_queens(Qs).
length(Qs,N)
[A,B,C,D]
Qs ins 1..N
A in 1..4
labels(Qs)
n_queens/2
的末尾,您将在调试器中看到约束列表,但没有解决方案
labels/1
才解决约束以生成结果。
关于prolog - 了解N皇后问题的CLP(FD)Prolog代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53406374/
我正在学习序言。 在我看来,prolog 的规则(关系和简单的事实)是“肯定的”——他们说的是或可能是真的。 向 prolog 程序添加新的此类规则只会增加“正面”知识。它不能添加“负面”事实来说明某
希望你一切都好。我是 prolog 的新手,我在编写代码时遇到问题。这段代码的目的很简单。它将列表中的每个元素添加到最后一个。我可以用 Java 做的事情是: static void add(
在closed-world assumption下, what is not currently known to be true, is false Prolog 的语义通常被称为遵循封闭世界假设,
我正在 Prolog (swi-prolog) 中做我的第一步,但无法解决以下问题:如何将存在量化的规则包含在我的事实中;具体来说,我如何包含句子“每个人都是某人的 friend ”\forall x
我知道如何以过程方式(即,在 C++、Java 等中)对 BST 执行范围查询,但我发现很难转换为 Prolog 语言。 程序的方式应该是这样的: http://www.geeksforgeeks.o
Prolog 中是否有(相对)当前最佳实践的引用资料?一本适合没有学习过逻辑编程或“Prolog 的工艺”等高级文本的商业 Prolog 开发人员? 有很多通用教程,但我能找到的关于最佳实践的唯一一个
这是CFG: S -> T | V T -> UU U -> aUb | ab V -> aVb | aWb W -> bWa | ba 所以这将接受某种形式的: {a^n b^n a^m b^m |
我目前有以下问题,我想用 Prolog 解决。这是一个简单的例子,很容易在 Java/C/whatever 中解决。我的问题是,我认为与 Java 的思想联系太紧密,无法以利用 Prolog 逻辑能力
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我无法理解差异列表,尤其是在这个谓词中: palindrome(A, A). palindrome([_|A], A). palindrome([C|A], D) :- palindrome(A
(这不是一个类(class)作业问题。只是我自己的个人学习。) 我正在尝试在 Prolog 中进行练习以从列表中删除元素。这是我的代码: deleteall([],X,[]). deleteall([
我最近试图了解 Prolog,它似乎可以很好地映射到很多领域,但我无法弄清楚它可能不擅长什么。 那么它有什么不好的(除了需要实时/无 gc 性能的东西)? 最佳答案 我同意你的一般评估,即 Prolo
我正在组装一个简单的元解释器,它输出证明的步骤。我无法将证明步骤作为输出参数。我的谓词 explain1 以我想要的详细形式返回证明,但不是作为输出参数。我的谓词 explain2 将证明作为输出参数
hi(g,plus(A,B),int) :- hi(g,A,int),hi(g,B,int),!. 在上面的语句中 '!' 是什么意思?在声明的末尾签名吗? 最佳答案 那是 cut operator
有没有一种简单的方法可以让 prolog 中的查询只返回每个结果一次? 例如我正在尝试类似的东西: deadly(Xn) :- scary(X), Xn is X - 1, Xp is X + 1,
我正在尝试学习 Prolog。这是我使用这种语言的第一步。作为练习,我想编写可以识别一些扑克手牌的程序(同花顺、同花顺、满屋等)。 我正在 Prolog 中寻找良好的卡片表示。我需要有可能检查一张卡片
我刚刚被介绍到 Prolog 并且正在尝试编写一个谓词来查找整数列表的最大值。我需要写一个从头开始比较,另一个从结尾比较。到目前为止,我有: max2([],R). max2([X|Xs], R):-
我试图在Prolog中编写谓词palindrome/1,当且仅当其列表输入包含回文列表时才为true。 例如: ?- palindrome([1,2,3,4,5,4,3,2,1]). 是真的。 有什么
我正在尝试编写一个程序,该程序将两个列表作为输入并检查适当的子集。我开始于: proper([A],[]). proper([],[A]). proper([A|T1],[A|T2]) :- prop
我是 Prolog 的新手,我正在使用 SWI-Prolog v6.6 在 *.pl 中存储断言文件。 :- dynamic fact/2. assert(fact(fact1,fact2)). 使用
我是一名优秀的程序员,十分优秀!