Опубликован: 16.09.2005 | Уровень: для всех | Доступ: платный | ВУЗ: Московский государственный университет имени М.В.Ломоносова
Лекция 4:

Вычисление функций на последовательностях

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

Индуктивные функции на последовательностях и индуктивные расширения

В рассмотренных выше примерах при добавлении к последовательности еще одного элемента новое значение функции на последовательности можно было вычислить, зная только старое значение функции и добавленный элемент. Обозначим через Sn последовательность

Sn = {a0, a1, ..., an-1}

длины n. С помощью знака & обозначим операцию приписывания нового элемента справа к последовательности (ее называют также конкатенацией):

Sn+1 = Sn&an = {a0, a1, ..., an-1, an}

Пусть f(S) - некоторая функция на множестве последовательностей, например, сумма элементов последовательности. Функция называется индуктивной, если при добавлении нового элемента к последовательности новое значение функции можно вычислить, зная только старое значение функции и добавленный элемент. На математическом языке функция

f:W -> Y

где W - множество всех последовательностей, составленных из элементов некоторого множества X, индуктивна, если существует функция G от двух аргументов

G:Y*X -> Y

такая, что для любой последовательности S из W и любого элемента a из X значение функции f на последовательности S, к которой добавлен элемент a, вычисляется с помощью функции G:

f(S&a) = G(f(S), a).

Функция G по паре (y, a), где y - старое значение функции f на последовательности S и a - элемент, добавленный к последовательности, вычисляет новое значение y, равное значению функции f на новой последовательности.

В примере с суммой элементов последовательности функция G равна сумме элементов y и a:

G(y, a) = y+a.

В примере с максимальным элементом последовательности функция G равна максимуму:

G(y, a) = max(y,a).

В примере со схемой Горнера вычисления значения многочлена в точке t, где коэффициенты многочлена заданы в последовательности по убыванию степеней, функция G равна

G(y, a) = yt+a.

Во всех трех случаях рассматриваемая функция на последовательности индуктивна.

Общая схема вычисления значения индуктивной функции на последовательности выглядит следующим образом:.

алгоритм значение индуктивной функции(
  вх: последовательность S
)
| дано: последовательность S
| надо: вычислить функцию y = f(S)
начало алгоритма
| y := значение функции f на пустой последовательности;
| встать в начало последовательности S;
| цикл пока в последовательности S есть
| |           непрочитанные элементы
| | прочесть очередной элемент
| |     последовательности S в (вых:x);
| | y := G(y, x);
| конец цикла
| ответ := y;
конец алгоритма

Таким образом, для каждой конкретной индуктивной функции надо лишь правильно задать ее значение на пустой последовательности (инициализация) и определить, как новое значение функции вычисляется через старое при добавлении к последовательности очередного элемента, т.е. задать функцию G(y,x). Схема вычисления для всех индуктивных функций одна и та же.

Однако не все функции на последовательностях являются индуктивными. Рассмотрим следующий пример. Пусть коэффициенты многочлена заданы в последовательности по убыванию степеней. Надо вычислить значение производной многочлена в точке x = 2. Обозначим через

S = {a0, a1, ..., an}

последовательность коэффициентов многочлена

p(x) = a0xn+a1xn-1+...+an

и через f(S) значение производной многочлена p'(x) в точке x =2:

f(S) = p'(2)

Покажем, что функция f не индуктивна. Достаточно указать две последовательности S1 и S2, такие, что значения функции f на них совпадают, но при добавлении к последовательностям S1 и S2 одного и того же элемента a новые значения функции уже не равны:

f(S1) = f(S2),
f(S1&a) ≠ f(S2&a)

Возьмем последовательности

S1 = {1},
S2 = {1, -4,1}.

Им соответствуют многочлены

p1(x) = 1,
p2(x) = x2-4x+1

Производные многочленов равны

p'1(x) = 0,
p'2(x)= 2x-4

Значения обеих производных в точке x=2 равны нулю, т.е.

f(S1) = p'1(2) = 0,
f(S2) = p'2(2) = 2*2-4 = 0

Припишем теперь к обеим последовательностям элемент a = 1:

S1&1 = {1,1},
S2&1 = {1, -4,1,1}.

Новым последовательностям соответствуют многочлены

g1(x) = x+1,
g2(x) = x3-4x2+x+1

Их производные равны

g'1(x) = 1,
g'2(x) = 3x2-8x+1

Значения производных в точке x=2 равны соответственно

f(S1&1) = g'1(2) = 1
f(S2&1) = g'2(2) = 12-16+1 = -3

Мы видим, что значения f(S1) и f(S2) совпадают, но значения f(S1&1) и f(S2&1) не совпадают. Следовательно, функция f не индуктивна.

Как поступать в случае, когда функция f не индуктивна? Общий рецепт следующий: надо придумать индуктивную функцию F, такую, что, зная значение F, легко можно вычислить исходную функцию f. Функция F называется индуктивным расширением функции f.

Приведем формальные определения. Пусть исходная функция на множестве W всех последовательностей

f:W -> Y

не индуктивна. Индуктивная функция

F:W -> Z

называется индуктивным расширением функции f, если существует отображение

P:Z -> Y

такое, что для всякой последовательности S, принадлежащей W, выполняется равенство

f(S) = P(F(S))

(т.е. функция f равна композиции отображений F и P, f = P*F.) Отображение P обычно называют проекцией множества Z на Y.

Как построить индуктивное расширение функции f? Это творческий момент, готового рецепта на все случаи не существует. Неформальный рецепт следующий: надо понять, какой информации не хватает для того, чтобы уметь вычислять новое значение функции на последовательности при добавлении к последовательности нового элемента. Эту информацию надо хранить дополнительно к значению функции. Отсюда и появился термин расширение: вычисляется более сложная, расширенная, функция, чтобы по ней затем восстановить исходную. Как правило, значением индуктивного расширения F является пара (y, h), где y - значение исходной функции f, а h - некоторая дополнительная информация, позволяющая перевычислять значение y при добавлении нового элемента к последовательности. Таким образом, множество Z значений индуктивного расширения

F:W -> Z

чаще всего является множеством пар (y, h), т.е. декартовым произведением:

Z = Y*H

Отображение P на практике должно легко вычисляться. Так оно и есть в случае декартова произведения - это просто проекция на первый аргумент.

P(y, h) = y

Рассмотрим пример с вычислением производной многочлена в точке; коэффициенты многочлена заданы в последовательности по убыванию степеней. При добавлении к последовательности

Sk = {a0, a1, ...,ak}

нового коэффициента ak+1 получаем последовательность

Sk+1 = S&ak+1 = {a0, a1, ...,ak, ak+1}

Пусть этим двум последовательностям соответствуют многочлены pk(x) и pk+1(x). Тогда

pk+1(x) = pk(x)*x + ak+1.

Дифференцируя это равенство, получим:

p'k+1(x) = p'k(x)*x + pk(x).

Мы видим, что для вычисления нового значения производной нужно знать старое значение производной, а также старое значение многочлена. Следовательно, дополнительно к значению производной многочлена надо хранить еще значение самого многочлена. Таким образом, индуктивным расширением функции, равной производной многочлена в точке t, является пара (значение производной, значение многочлена):

F:S -> (p'(t), p(t))

Новое значение производной вычисляется по приведенной выше формуле через старое значение производной и старое значение многочлена. После этого вычисляется новое значение многочлена по схеме Горнера.

Выпишем алгоритм вычисления производной многочлена.

вещ алг. значение производной(вх: цел n, вещ a[n+1], вещ t)
| дано: n      -- степень многочлена
|       a[n+1] -- массив коэффициентов многочлена по
|                 возрастанию степеней
| надо: найти значение производной многочлена в точке t
начало алгоритма
| вещ p, dp; цел i;
| p := 0.0;     // Инициализация значения многочлена
| dp := 0.0;    // Инициализация значения производной
| цикл для i от 0 до n
| | dp := dp * t + p;  // Новое значение производной
| | p := p * t + a[i]; // Новое значение многочлена
| конец цикла
| ответ := dp;
конец алгоритма

Другой пример неиндуктивной функции - это среднее арифметическое значение элементов последовательности. Индуктивным расширением является пара (сумма элементов последовательности, длина последовательности):

F(S) = (сумма(S), длина(S)).

Легко видеть, что функция F индуктивна. При известном значении функции F не составляет труда вычислить исходную функцию:

среднее арифметическое(S) = сумма(S)/длина(S).

В данном случае отображение P не является в чистом виде проекцией, т.к. в процессе вычислений удобнее хранить сумму элементов прочитанного отрезка последовательности, а не среднее арифметическое. Вычисления проще и, кроме того, сумма определена на пустой последовательности в отличие от среднего арифметического.

Итак, в каждом конкретном случае при вычислении неиндуктивной функции f надо придумать ее индуктивное расширение F и в программе вычислять сначала индуктивное расширение F, а затем по значению F вычислять требуемое значение исходной функции f.

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
Натела Кузнецова
Натела Кузнецова

Уважаемые сообучающиеся, скиньте, пожалуйста,ссылку на корректные фалы для установки Traffic. Заранее благодарна

Дарья Федотова
Дарья Федотова
Денис Шестериков
Денис Шестериков
Россия
Сергей Мамойленко
Сергей Мамойленко
Россия, Московский государственный институт стали и сплавов (Технологический университет), 2000