示例如何使用predsort:在序言(比较,+列表,-Sorted)(Example how to

2019-08-17 15:59发布

我想订一个自定义列表。 我想订货会这种形式的列表...

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

我已经写了一个比较

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

我怎样predsort使用。 我写了使用冒泡排序排序算法,但我有非常大的列表,这样很慢。

是否有可能做

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

谢谢 :)

Answer 1:

试试这个 :

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.


Answer 2:

乔尔所表现出来的基本情况(+1),但要获得更好的性能,避免重复测试:

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

编辑

现在SWI-Prolog有另一种内置的排序 / 4,对于简单的情况下,避免了与用户定义的谓词的调用处罚:

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


Answer 3:

尽量避免使用predsort/3 。 这是一个特定SWI谓不是特别有效,因为所有的〜O(N日志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).


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