So I have a HW problem I've been working on for a couple days and I'm stuck on the last part. In Prolog, I'm supposed to write a function that takes in two lists ((x1, x2, …, xn), (y1, y2, …yn) ) and finds the distance between both. The output is the result of the math done on the list. Formula: sqrt((x1-y1) (x1-y1) + (x2-y2) (x2-y2) + … + (xn-yn)*(xn-yn)) Here's what I have so far:
distance([],[], 0).
distance([Ha|Ta],[Hb|Tb], Sum) :-
distance(Ta,Tb, Rest),
Sum is sqrt( (Ha-Hb)*(Ha-Hb)) + Rest.
It is quite near. Off the top of my head, just sum the squares ( distance_aux
) and then return the square root of the accumulated sum:
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.
You can also add the simplified rule distance([], [], 0).
, although it is not necessary.
Prolog has lists , not arrays.
Your code doesn't implement the formula shown, because sqrt
must be computed after the sum of products. In the code below, I introduce also an accumulator, making the loop tail recursive (more efficient).
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).
Depending on your Prolog library, the code could be simpler:
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).
The formula you have given squares the entire summation, rather than squaring each individual couple - which is what you are doing in your code. Using an auxiliary solves that issue:
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).
So an example would be:
distance([1,2,3], [4,5,6], Sum).
Sum = 5.196152422706632.
Working:
sqrt( (1-4)*(1-4) + (2-5)*(2-5) + (3-6)*(3-6) )
sqrt( 3*3 + 3*3 + 3*3 )
sqrt( 27 )
5.19615
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.