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 :)
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.
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)].
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