我有一个列表L
,其中包含range(2,3),
这样的术语,其中第一个元素是具有最低Y的术语,现在我需要对列表L的其他元素进行排序(第一个元素将保持不变),我需要按逆时针顺序按极角对它们进行排序。如果两点的极角相同,那么我需要将最近的项放在第一位。我定义了谓词angle2d / 2:
angle2d(A, B, R) :-
A =.. [_,Ax,Ay],
B =.. [_,Bx,By],
R is atan2((Ay-By),(Ax-Bx)).
给我2点之间的逆时针角度,但是我没有得到如何创建谓词sort_list / 2来排序我的n-1点(列表的第一个元素将保持不变)通过它们与列表的第一个元素(点)的逆时针角度。
答案 0 :(得分:1)
作为按一些奇怪的自定义标准排序的一般方法,首先定义您的compare_custom/3
谓词,然后将其与已知的排序算法一起使用。在SWI中,您可以使用定义如下的predsort/3
谓词:
predsort(+ Pred,+ List,-Sorted)
类似于sort / 2的排序,但是 通过调用Pred(-Delta,+ E1,+ E2)确定两个术语的顺序。 此调用必须将Delta与其中一个统一为<,>或=。如果是内置的 使用谓词compare/3
,结果与sort / 2相同。看到 还有keysort / 2。
您还应该查看预定义的compare/3
:
比较(?订单,@ Term1,@ Term2)
确定或测试订单之间的顺序 标准顺序中的两个术语。订单是<,>之一或=, 具有明显的意义。
答案 1 :(得分:1)
我这样做了:
sort_angle([], _).
sort_angle([_|[]], _).
sort_angle([_,_|[]], _).
sort_angle(List, SortedList) :-
predsort(sort_me,[_|List], SortedList).
sort_me(<, A, B) :- angle2d(H,A,X), angle2d(H,B,Y), X<Y.
sort_me(>, A, B) :- angle2d(H,A,X), angle2d(H,B,Y), X>Y.
sort_me(=, A, B) :- angle2d(H,A,X), angle2d(H,B, Y), X=Y.
但是我不知道,在sort_me谓词中如何判断H是我列表中的第一个元素......我怎么能告诉它?