2013-04-22 71 views
2

所以我有一個硬件問題,我一直在努力了幾天,我被困在最後一部分。在Prolog中,我應該編寫一個函數,它包含兩個列表 ((x1,x2,...,xn),(y1,y2,... yn)) ,並找出兩者之間的距離。輸出結果是在列表中完成的數學運算。 (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. 

回答

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). 
+0

+1對於摺疊。 – Orbling 2013-04-22 20:22:32

+0

確實!用於Erlang時,我有時會忘記你必須使用兩個累加器,在Erlang中,你只用一個。 – 2013-04-22 20:25:56

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).,雖然這是沒有必要的。

+0

啊好吧,我明白髮生了什麼事情錯了。我添加了一個輔助功能,它完美地工作。謝謝你的快速解決方案:-) – workinMan 2013-04-22 20:33:06

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