Скалярное произведение векторов (списков)

      Комментарии к записи Скалярное произведение векторов (списков) отключены

Главная Форумы Программирование Помощь с решением задач на Prolog Задачи на списки Скалярное произведение векторов (списков)

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 2 года/лет назад.

  • Автор
    Сообщения
  • #2046

    questioner
    Участник

    Помогите решить задачу — от меня требуется написать функцию, выполняющую скалярное умножение векторов, которые представлены в виде списков на Prolog.

    Скалярное произведение может выполниться лишь если вектора имеют одинаковую размерность (в противном случае вычисление цели на прологе должно провалиться).

    В результате должно быть вычислено значение a0*b0 + a1*b1 + ... + an*bn

    Вложения:
  • #2049

    Если оба вектора пусты — то произведение равно нулю. В противном случае от список отделяются первый элементы, а хвосты — обрабатываются рекурсивно. К результату, полученному при обработке хвостов добавляется выражение HeadA*HeadB.

    scalar_multiplication([], [], 0):-!.
    scalar_multiplication([HeadA|TailA], [HeadB|TailB], Multiplication):-
      scalar_multiplication(TailA, TailB, TailMultiplication),
      Multiplication is TailMultiplication + HeadA * HeadB.

    Это простой вариант, однако он не очень эффективный — лучше использовать хвостовую рекурсию. При хвостовой рекурсии вызов функции идет последним, поэтому может быть заменен безусловным переходом (фактически циклом). Для оптимизации функции используется метод накапливающего параметра — результат накапливается в одном из аргументов функции. Начальное значение суммы, равное нулю, должно передаваться в качестве накопителя при первом вызове — сделать это можно во вспомогательной функции:

    scalar_multiplication(ListA, ListB, Multiplication):-
      scalar_multiplication(ListA, ListB, 0, Multiplication).
      
    scalar_multiplication([], [], Multiplication, Multiplication):-!.
    scalar_multiplication([HeadA|TailA], [HeadB|TailB], Buffer, Multiplication):-
      NewBuffer is Buffer + HeadA * HeadB,
      scalar_multiplication(TailA, TailB, NewBuffer, Multiplication).

    На каждой итерации функции вычисляет новое значение буфера-накопителя (частичный результат) и передает его для рекурсивной обработки. Когда оба вектора закончились — накопленный результат переписывается в выходной буфер.

Для ответа в этой теме необходимо авторизоваться.