Мы определяем my_perm/2
на основе same_length/2
, list_permuted/2
, dif и mapadj/2
:
my_perm(Xs,Ys) :-
same_length(Xs,Ys),
mapadj(dif,Ys),
list_permuted(Xs,Ys).
Универсальный мета-предикат mapadj/2
можно определить следующим образом:
:- meta_predicate mapadj(2,?), list_mapadj(?,2), list_prev_mapadj(?,?,2).
mapadj(P_2,Xs) :-
list_mapadj(Xs,P_2).
list_mapadj([],_).
list_mapadj([A|As],P_2) :-
list_prev_mapadj(As,A,P_2).
list_prev_mapadj([],_,_).
list_prev_mapadj([A1|As],A0,P_2) :-
call(P_2,A0,A1),
list_prev_mapadj(As,A1,P_2).
Вот пример запроса 1,2 , заданногоОП.
Мы используем call_time/2
для измерения времени выполнения в миллисекундах T_ms
.
?- call_time(my_perm([1,1,1,1,1,2,2,3,3,4,4,5,5],[1,2,1,5,1,3,1,4,1,2,3,5,4]),T_ms).
T_ms = 0.
Сколько времени нам нужно, чтобы найтипервые несколько решений?
?- call_time(my_perm([1,2,1,5,1,3,1,4,1,2,3,5,4],Xs),T_ms).
T_ms = 0, Xs = [1,2,1,5,1,3,1,4,1,2,3,5,4]
; T_ms = 0, Xs = [1,2,1,5,1,3,1,4,1,2,3,4,5]
; T_ms = 10, Xs = [1,2,1,5,1,3,1,4,1,2,5,3,4]
; T_ms = 10, Xs = [1,2,1,5,1,3,1,4,1,2,4,3,5]
; T_ms = 10, Xs = [1,2,1,5,1,3,1,4,1,2,5,4,3]
; T_ms = 10, Xs = [1,2,1,5,1,3,1,4,1,2,4,5,3]
; T_ms = 10, Xs = [1,2,1,5,1,3,1,4,1,3,2,5,4]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,3,2,4,5]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,5,2,3,4]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,4,2,3,5]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,5,2,4,3]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,4,2,5,3]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,3,5,2,4]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,3,4,2,5]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,5,3,2,4]
; T_ms = 20, Xs = [1,2,1,5,1,3,1,4,1,4,3,2,5]
; T_ms = 30, Xs = [1,2,1,5,1,3,1,4,1,5,4,2,3]
; T_ms = 30, Xs = [1,2,1,5,1,3,1,4,1,4,5,2,3]
...
Обратите внимание, что T_ms
растет монотонно: он измеряет время, потраченное с момента первого вызова данной цели.
Сколько времени занимает перечисление все решения?
?- call_time(\+((my_perm([1,1,1,1,1,2,2,3,3,4,4,5,5],_),false)),T_ms).
T_ms = 4030.
Сколько существует решений?
?- use_module(library(aggregate)),
aggregate(count,Xs,my_perm([1,2,1,5,1,3,1,4,1,2,3,5,4],Xs),N).
N = 197664.
Сноска 1: Использование SICStus Prolog версии 4.3.2 (x86_64-linux-glibc2.12).Сноска 2: Последовательности ответов, данные процессором Prolog, были адаптированы для удобства чтения.