Prolog循环,直到返回true
我正在尝试生成一个4x4魔方拼图,一旦找到一个有效的解决方案,列表就会打印出来。我有规则来打印一个给定的解决方案,生成一个随机的电路板以及解决它,但我不知道如何调用生成事实,直到它返回true,然后打印它。这是我的密码:Prolog循环,直到返回true,prolog,Prolog,我正在尝试生成一个4x4魔方拼图,一旦找到一个有效的解决方案,列表就会打印出来。我有规则来打印一个给定的解决方案,生成一个随机的电路板以及解决它,但我不知道如何调用生成事实,直到它返回true,然后打印它。这是我的密码: check([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]]) :- A+B+C+D=:=34, E+F+G+H=:=34, I+J+K+L=:=34, M+N+O+P=:=34, A+E+I+M=:=34,
check([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]]) :-
A+B+C+D=:=34,
E+F+G+H=:=34,
I+J+K+L=:=34,
M+N+O+P=:=34,
A+E+I+M=:=34,
B+F+J+N=:=34,
C+G+K+O=:=34,
D+H+L+P=:=34,
A+F+K+P=:=34,
D+G+J+M=:=34.
solve([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]]) :-
permutation(
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],
[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]),
check([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]]).
generate :-
random_permutation(
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],
[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]),
solve([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]]),
printlist([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]]).
printlist([X|List]) :-
write(X),nl,
printlist(List).
我知道Prolog没有传统意义上的循环,但我不太明白在找到有效案例之前如何运行(我也知道这里使用的暴力方法可能需要相当长的时间)
任何关于解决这一问题的见解都将不胜感激 您的程序需要另一种方法 只要看看目标:
permutation(
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],
[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]),
这个目标将产生16个!解决。换言之:2092789888000。所以,如果你有一台快速的电脑在你的支配下
为了改善这种情况,我们必须减少解决方案或答案的数量。但是,如何?Prolog有一些非常好的功能:逻辑变量。也就是说,我们可以使用约束将许多解决方案包含在单个答案中。在这种情况下,库(clpfd)
将有助于:
?- Xs = [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P], Xs ins 1..16, all_different(Xs).
Xs = [A, B, C, D, E, F, G, H, I|...],
A in 1..16,
all_different([A, B, C, D, E, F, G, H|...]),
B in 1..16,
C in 1..16,
D in 1..16,
E in 1..16,
F in 1..16,
G in 1..16,
H in 1..16,
I in 1..16,
J in 1..16,
K in 1..16,
L in 1..16,
M in 1..16,
N in 1..16,
O in 1..16,
P in 1..16.
一个答案现在包含了所有20万亿个解决方案!通过进一步的限制,我们现在可以写:
:- use_module(library(clpfd)).
magquad_([[A,B,C,D],[E,F,G,H],[I,J,K,L],[M,N,O,P]], Zs) :-
Xs = [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P],
Xs ins 1..16,
all_different(Xs),
Zs = [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P],
A+B+C+D#=34,
E+F+G+H#=34,
I+J+K+L#=34,
M+N+O+P#=34,
A+E+I+M#=34,
B+F+J+N#=34,
C+G+K+O#=34,
D+H+L+P#=34,
A+F+K+P#=34,
D+G+J+M#=34.
magquad(Xss) :-
magquad_(Xss, Zs), % use of core-relation or model
labeling([], Zs). % separate labeling
让打印由顶级完成!
正如您所看到的,Prolog现在可以不可思议地快速找到所有这些魔法方块 “我不太明白在找到一个有效的案例之前如何运行”只要调用谓词,这正是Prolog将要做的。但你的方法似乎效率很低,这就是为什么它似乎不起作用的原因。
?- time(magquad(Xss)).
% 106,412 inferences, 0.052 CPU in 0.053 seconds (99% CPU, 2049006 Lips)
Xss = [[1, 2, 15, 16], [12, 14, 3, 5], [13, 7, 10, 4], [8, 11, 6, 9]] ;
% 36,910 inferences, 0.027 CPU in 0.027 seconds (99% CPU, 1384976 Lips)
Xss = [[1, 2, 15, 16], [13, 14, 3, 4], [12, 7, 10, 5], [8, 11, 6, 9]] ;
% 209,488 inferences, 0.089 CPU in 0.089 seconds (100% CPU, 2348606 Lips)
Xss = [[1, 2, 16, 15], [13, 14, 4, 3], [12, 7, 9, 6], [8, 11, 5, 10]] ...