2013-04-22 3 views
2

Итак, у меня проблема с HW, над которой я работаю пару дней, и я застрял на последней части. В 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. 

ответ

2

Пролог имеет , а не массивы.

Ваш код не показывает формулу, потому что 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). 

В зависимости от вашей библиотеки Пролога, код может быть проще:

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

+0

Действительно! Используемый для Erlang, я иногда забываю, что вы должны использовать два аккумулятора, в которых в Erlang вы используете только один. –

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

Ах хорошо, я вижу, что происходит неправильно. Я добавил функцию aux и работает отлично. Спасибо за быстрый resposne :-) – workinMan

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 
Смежные вопросы