2

所以我有一个硬件问题,我已经解决了几天,我被困在最后一部分。在 Prolog 中,我应该编写一个函数,它接受两个列表 ((x1, x2, ..., xn), (y1, y2, ...yn) ) 并找到两者之间的距离。输出是对列表进行的数学运算的结果。公式:sqrt((x1-y1) (x1-y1) + (x2-y2) (x2-y2) + … + (xn-yn)*(xn-yn)) 这是我目前所拥有的:

distance([],[], 0).
distance([Ha|Ta],[Hb|Tb], Sum) :-
   distance(Ta,Tb, Rest),
   Sum is sqrt( (Ha-Hb)*(Ha-Hb)) + Rest.
4

3 回答 3

2

它很近。在我的脑海中,只需将平方 ( distance_aux) 相加,然后返回累积和的平方根:

distance(L1, L2, D) :-
        distance_aux(L1, L2, SQSUM),
        D is sqrt(SQSUM).

distance_aux([],[],0).
distance_aux([Ha|Ta],[Hb|Tb], Sum) :-
   distance_aux(Ta,Tb, Rest),
   Sum is (Ha-Hb)*(Ha-Hb) + Rest.

您也可以添加简化规则distance([], [], 0).,尽管这不是必需的。

于 2013-04-22T20:20:58.873 回答
2

Prolog 有列表,而不是数组。

您的代码没有实现显示的公式,因为sqrt必须在产品总和之后计算。在下面的代码中,我还引入了一个累加器,使循环尾递归(更高效)。

distance(Xs, Ys, Dist) :-
  distance(Xs, Ys, 0, Dist).

distance([], [], Acc, Dist) :- 
    Dist is sqrt(Acc).
distance([X|Xs], [Y|Ys], Acc, Dist) :-
    Sum is (Y-X)*(Y-X) + Acc,
    distance(Xs, Ys, Sum, Dist).

根据您的 Prolog 库,代码可能更简单:

distance(Xs, Ys, Dist) :-
    foldl(distpoint, Xs, Ys, 0, Sq),
    Dist is sqrt(Sq).
distpoint(X, Y, S, D) :- D is S+(Y-X)*(Y-X).
于 2013-04-22T20:21:40.513 回答
0

您给出的公式对整个总和进行平方,而不是对每对夫妇进行平方 - 这就是您在代码中所做的。使用辅助解决了这个问题:

distance_sum([], [], 0).
distance_sum([Ha|Ta], [Hb|Tb], Sum) :-
   distance_sum(Ta, Tb, Rest),
   Sum is ((Ha-Hb) * (Ha-Hb)) + Rest.

distance(A, B, Sum) :- distance_sum(A, B, DSum), Sum is sqrt(DSum).

所以一个例子是:

distance([1,2,3], [4,5,6], Sum).
Sum = 5.196152422706632.

在职的:

sqrt( (1-4)*(1-4) + (2-5)*(2-5) + (3-6)*(3-6) )
sqrt( 3*3 + 3*3 + 3*3 )
sqrt( 27 )
5.19615
于 2013-04-22T20:21:44.640 回答