Duyệt qua tuyệt vờiOn-Line Encyclopedia of Integer Sequences (x en.wikipedia.org), tôi stumbled khi dãy số nguyên sau:Prolog: tính OEIS A031877 ("số đảo ngược không tầm thường") sử dụng CLP (FD)
A031877: Số đảo ngược không đặc biệt (số là bội số nguyên của số lần đảo ngược của chúng), không bao gồm số palindromic và bội số của 10.
Bằng cách tái sử dụng một số mã tôi đã viết cho câu trả lời của tôi cho th e câu hỏi liên quan "Faster implementation of verbal arithmetic in Prolog" Tôi có thể viết ra một giải pháp khá dễ dàng - nhờ clpfd!
:- use_module(library(clpfd)).
Chúng ta định nghĩa mối quan hệ lõia031877_ndigits_/3
dựa trên digits_number/2
(được định nghĩa trước đó):
a031877_ndigits_(Z_big,N_digits,[K,Z_small,Z_big]) :-
K #> 1,
length(D_big,N_digits),
reverse(D_small,D_big),
digits_number(D_big,Z_big),
digits_number(D_small,Z_small),
Z_big #= Z_small * K.
Mối quan hệ cốt lõi được xác định và chấm dứt phổ bất cứ khi nào N_digit
là một số nguyên bê tông . Tự mình xem 100 giá trị đầu tiên của N_digit
!
?- time((N in 0..99,indomain(N),a031877_ndigits_(Z,N,Zs),false)).
% 3,888,222 inferences, 0.563 CPU in 0.563 seconds (100% CPU, 6903708 Lips)
false
Hãy chạy một số truy vấn!
?- a031877_ndigits_(87912000000087912,17,_). true % succeeds, as expected ; false. ?- a031877_ndigits_(87912000000987912,17,_). false. % fails, as expected
Tiếp theo, hãy tìm một số con số đảo ngược không tầm thường bao gồm chính xác bốn thập phân-chữ số:
?- a031877_ndigits_(Z,4,Zs), labeling([],Zs).
Z = 8712, Zs = [4,2178,8712]
; Z = 9801, Zs = [9,1089,9801]
; false.
OK! Hãy đo thời gian chạy cần thiết để chứng minh việc chấm dứt toàn bộ truy vấn trên!
?- time((a031877_ndigits_(Z,4,Zs),labeling([],Zs),false)).
% 11,611,502 inferences, 3.642 CPU in 3.641 seconds (100% CPU, 3188193 Lips)
false. % terminates universally
Bây giờ, đó là cách quá dài!
Tôi có thể làm gì để tăng tốc độ? Sử dụng các ràng buộc khác và/hoặc các ràng buộc khác? Có lẽ ngay cả những người thừa? Hoặc có thể xác định và loại bỏ các đối xứng làm giảm kích thước không gian tìm kiếm? Điều gì về các lĩnh vực clp (*) khác nhau (b, q, r, set)? Hoặc các kỹ thuật thống nhất/tuyên truyền khác nhau? Hay đúng hơn là Prolog phong cách coroutining?
Bạn có ý tưởng? Tôi muốn tất cả! Cảm ơn trước.