我试图生成一个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,
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没有传统意义上的循环,但是我不太清楚如何找到有效的案例(我也知道这里使用的暴力方法可以需要一段时间)。
任何有关解决此问题的见解将不胜感激!
答案 0 :(得分:2)
你的程序正在呼唤另一种方法!
看看目标:
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个!解决方案。换句话说:20 922 789 888 000.所以,如果你有一台快速的电脑,......
为了改善这种情况,我们必须减少解决方案或答案的数量。但是,怎么样? Prolog有一些非常好的东西:逻辑变量。也就是说,我们可以使用约束在单一答案中包含许多解决方案。在这种情况下,library(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.
一个答案现在包含所有二十亿个解决方案!有了进一步的限制,我们现在可以写:
:- 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
?- 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]] ...
正如你所看到的,Prolog现在可以快速地找到所有那些魔方!