Пролог перечисляет fd_all_different и is_set, что быстрее? - PullRequest
1 голос
/ 03 июня 2011

я просто хочу знать, знает ли кто-нибудь из вас, что быстрее,

L=[1,2,3,4,5], all_different(L). % needs use_module(library(clpfd)).

или

L=[1,2,3,4,5], is_set(L).

кто-нибудь знает?нужно более быстрое решение для моего решения судоку.спасибо!

Ответы [ 2 ]

2 голосов
/ 04 июня 2011

Различие между all_different / 1 и is_set / 1 состоит в том, что первый использует «логику ограничения» и может наложить предполагаемое ограничение до того, как элементы списка будут полностью созданы,такой, что сбой происходит, когда движок Prolog вынужден объединять или присваивать равные значения двум записям аргумента списка.

Мы можем проиллюстрировать «логику ограничения» all_different следующей паройзапросов:

?- length(L,5), all_different(L), L=[1,2,3,4,5].
L = [1, 2, 3, 4, 5].

?- length(L,5), all_different(L), L=[1,2,3,4,1].
false.

Необходимо предоставить правильный список для all_different , но не иметь одну из полностью связанных или "наземных" записей.Выше показано, что all_different может перспективно налагать ограничения на записи списка.

Сравните результаты с is_set вместо:

?- length(L,5), is_set(L), L=[1,2,3,4,5].
L = [1, 2, 3, 4, 5].

?- length(L,5), is_set(L), L=[1,2,3,4,1].
L = [1, 2, 3, 4, 1].

Один раз is_set успешно, он не может предотвратить будущие привязки, которые создали равные записи.

Таким образом, предикат all_different полагается на дополнительное оборудование в библиотеке логики ограничений, чтобы делать то, что is_set не может, и в большинстве случаев это дополнительное оборудование будет увеличивать накладные расходы.Однако простым способом, который использовался в вопросе Виктора, дополнительное оборудование используется не очень часто.Проверки выполняются на полностью связанных условиях, а не на предполагаемой основе, и эффективность сопоставима.

2 голосов
/ 03 июня 2011

Используйте предикат time / 1, чтобы измерить количество выводов и фактическое время, затраченное на вычисление. В вашем примере вы бы сделали что-то вроде

time((L=[1,2,3,4,5], all_different(L))) vs. time((L=[1,2,3,4,5], is_set(L)))

Обратите внимание, что измеренное время до первого успеха.

...