4

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

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

我写了一个比较器

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

如何将它与 predsort 一起使用。我使用冒泡排序编写了一个排序算法,但我的列表非常大,所以速度很慢。

有没有可能做

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

谢谢 :)

4

3 回答 3

5

尝试这个 :

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

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

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

请注意 predsort 的工作方式与 sort 类似,没有双打!如果你想保持双打,试试

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

cheaper(<, n(_,C1,_),n(_,C2,_)) :-
        C1=<C2.
于 2013-03-15T21:52:57.130 回答
4

Joel 展示了基本情况 (+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)].
于 2013-03-15T22:44:52.310 回答
3

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

因此,首先将您的列表映射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).
于 2013-03-15T23:08:48.263 回答