示例如何在prolog中使用predsort(:Compare,+ List,-Sorted)

时间:2013-03-15 21:36:54

标签: sorting prolog swi-prolog mergesort

我想订购自定义列表。我想订购的清单将采用这种形式......

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

我写了一个比较器

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

如何在predsort中使用它。我使用冒泡排序编写了一个排序算法,但是我有非常大的列表,所以它非常慢。

可以吗

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

谢谢:)

3 个答案:

答案 0 :(得分:5)

试试这个:

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

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

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

请注意,predsort就像排序一样,没有双打!如果你想保持双打,试试

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

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

答案 1 :(得分:4)

Joel已经展示了基本情况(+1),但为了获得更好的性能,请避免重复测试:

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

修改

现在SWI-Prolog有另一个内置sort / 4,对于简单的情况,它可以避免与用户定义的谓词调用相关的惩罚:

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

答案 2 :(得分:2)

尽量避免使用predsort/3。这是一个SWI特定的谓词,它不是特别有效,因为所有~O(n log n)比较都是通过调用你的定义来执行的。而是尝试使用keysort/2这是一个标准谓词,并且不会产生任何此类调用开销:

首先将列表Ns映射到对KNs对列表,然后排序,然后提取值。

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