Московский государственный университет имени М.В.Ломоносова
Опубликован: 16.09.2005 | Доступ: свободный | Студентов: 15527 / 1104 | Оценка: 4.26 / 4.03 | Длительность: 15:06:00
ISBN: 978-5-9556-0039-0
Специальности: Программист
Лекция 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 >
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Ирина Калашникова
Ирина Калашникова

Добрый день, подскажите на тест после каждой лекции сколько дается попыток?