我正在尝试在Prolog中制作一个回溯程序,以确定所有共线点的子集。 问题:在计划中给出n个点(使用其坐标表示)。 写一个谓词来确定所有共线点的子集。
示例:
输入:[[1,1],[2,2],[3,3],[0,0],[4,8],[1,2],[6,7],[8 ,9],[10,11]]
输出:[[[1,1],[2,2],[3,3]],[[1,1],[2,2],[0,0]],[[2, 2],[3,3],[0,0]],[[1,1],[3,3],[0,0]],...]
到目前为止,我通过检查这个公式来检查3点是否共线:
(Xc - Xa)/ (Xb - Xa) = (Yc - Ya)/ (Yb - Ya).
但是,我认为这不会起作用,因为我需要使用回溯来解决问题。我应该在每个函数调用中选择一个候选者,看它是否与其余函数匹配。
你能否建议我检查3点是否共线?
答案 0 :(得分:1)
我假设您的程序查询类似于:
?- findColinears([[1,1],[2,2],[3,3],[0,0],[4,8],[1,2],[6,7],[8,9],[10,11]], Out).
显然我不会提供代码来解决整个问题,但一般来说,自上而下的方法可能涉及如下谓词:
colinear( P1, P2, P3 ) :- slope( P1, P2, S ), slope( P1, P3, S ).
colinear( P1, P2, P3 ) :- slope( P1, P2, S ), slope( P2, P3, S ).
colinear( P1, P2, P3 ) :- slope( P1, P3, S ), slope( P2, P3, S ).
slope( P1, P2, S ) :-
P1 = p( X1, Y1 ),
P2 = p( X2, Y2 ),
S is ((Y2-Y1)/(X2-X1)).
findColinearTriplet( ListOfPoints, Triplet ) :-
member( P1, ListOfPoints ),
member( P2, ListOfPoints ), dif(P1, P2),
member( P3, ListOfPoints ), dif(P1, P3), dif(P2, P3),
colinear(P1, P2, P3),
Triplet = [P1, P2, P3].
然后,您可以使用这些来查找所有可能的Triplet
个统一信息
当然,一些三元组是等价的(例如[p(1,1), p(2,2), p(3,3)]
和[p(3,3), p(1,1), p(2,2)]
)。此外,一些将重复。如果您需要独特的三元组,则必须从收集的所有非唯一三元组中手动构建此类唯一列表。
例如,您的最终findColinears
谓词可能类似于:
findColinears( ListOfPairs, Out ) :-
convertToPoints( ListOfPairs, ListOfPts ),
findall( Triplet, findColinearTriplet(ListOfPts, Triplet), ListOfTriplets),
discardDuplicates( ListOfTriplets, Out ).
用于适当定义的convertToPoints
和discardDuplicates
谓词。