Example how to use predsort(:Compare, +List, -Sorted) in prolog

不打扰是莪最后的温柔 提交于 2019-12-06 04:24:45

问题


I want to order a custom list. The list I want to order will be in this form...

[n(_,2,_),n(_,1,_),n(_,3,_)]  

I have wrote a comparator

cheaper(n(_,C1,_),n(_,C2,_)) :-
        C1>C2.  

How do I use this with predsort. I wrote a sorting algorithm using bubble sort, but I have very large lists so it very slow.

Is it possible to do

predsort(cheaper, [n(_,2,_),n(_,1,_),n(_,3,_)] , X).

Thank you :)


回答1:


Try this :

cheaper(>, n(_,C1,_),n(_,C2,_)) :-
        C1>C2.

cheaper(<, n(_,C1,_),n(_,C2,_)) :-
        C1<C2.

cheaper(=, n(_,C1,_),n(_,C2,_)) :-
        C1=C2.

Be aware that predsort works like sort, there are no doubles ! If you want to keep doubles, try

cheaper(>, n(_,C1,_),n(_,C2,_)) :-
        C1>C2.

cheaper(<, n(_,C1,_),n(_,C2,_)) :-
        C1=<C2.



回答2:


Joel has shown the basic case (+1), but to get better performance, avoid repeating the test:

cheaper(R, n(_,C1,_),n(_,C2,_)) :-
        C1>C2 -> R = > ; R = < .

edit

Now SWI-Prolog has another builtin sort/4, that for simple cases avoids the penalties related to calls of user defined predicates:

?- sort(2,@=<,[n(_,2,_),n(_,1,_),n(_,3,_)],S).
S = [n(_2578, 1, _2582), n(_2564, 2, _2568), n(_2592, 3, _2596)].



回答3:


Try to avoid using predsort/3. This is an SWI-specific predicate that is not particularly efficient, because all ~ O(n log n) comparisons are executed by calling your definition. Rather try to use keysort/2 which is a standard predicate and which does not incur any such call overhead:

So first map your list Ns to a list of pairs KNs, then sort, and then extract the values.

n_pricep(N, C-N) :-
   N = n(_,C,_).

pair_value(_-V,V).

   ...,
   maplist(n_pricep, Ns, KNs),
   keysort(KNs, KNsS),
   maplist(pair_value, KNsS, NsS).


来源:https://stackoverflow.com/questions/15442499/example-how-to-use-predsortcompare-list-sorted-in-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!