2.5.2. Системи рекурентних послідовностей
Нехай
– довільний універсум елементів,
– певні часткові операції
на
,
які будемо
називати конструкторами
рекурентних
послідовностей.
Система послідовностей
називається рекурентною відносно конструкторів , якщо всі її члени, за винятком, можливо, перших, пов’язані співвідношеннями
(*)
,
,
...,
.
Кількість
послідовностей у системі називається
її виміром,
а самі послідовності – рекурентними.
Ми будемо розглядати тільки рекурентні
системи певного фіксованого скінченного
виміру. Щоб
повністю визначити таку систему,
достатньо задати нульові члени
і конструктори.
Решта членів знаходиться за допомогою
конструкторів. Дійсно,
,
тощо.
Іноді зручно нумерувати члени рекурентних послідовностей, розпочинаючи з 1. Члени рекурентних послідовностей можуть залежати від членів не всіх сусідніх послідовностей, а тільки деяких, тому на практиці конструктори можуть мати (і зазвичай мають!) різну арність. У деяких випадках у системі співвідношень (*) наступні члени послідовностей можуть обчислюватись не тільки за попередніми, а й за поточними членами сусідніх послідовностей, а також за своїм індексом. В останньому випадку це означає, що в системі неявно присутній лічильник (див. Прикл.2.24).
Розглянемо кілька відомих прикладів рекурентних послідовностей.
Приклад 2.24. Рекурентні послідовності:
1)
Послідовність-константа:
(*)
.
Конструктор
– тотожна операція
2) Арифметична прогресія з різницею d:
(*)
,
.
Конструктор
– операція
.
3)
Лічильник
:
арифметична
прогресія з початковим членом 0 або 1 та
різницею
1.
Значення лічильника
на к-му
кроці збігається з к.
4)
Геометрична
прогресія зі знаменником
:
(*)
,
Конструктор
– операція
.
5) Гармонічні числа:
,
,
задаються системою рекурентних
співвідношень (*)
Конструктором
першої послідовності є операція
.
За означенням
,
тощо.
■
2.5.3. Рекурентні функції
З
кожною рекурентною системою послідовностей
(*) виміру
пов’язана певна функція
типу
,
яка вектору
початкових членів і числу
ставить у відповідність вектор з і-х
членів даних послідовностей:
,
де
.
Щоб
знайти значення функції
для довільного
,
достатньо послідовно побудувати всі
попередні значення
,
.
Зазвичай
для фіксованого початкового вектора
цікавлять не всі значення
функції
–
члени послідовності
,
,
а тільки виділені, а найчастіше – лише
одне. Щоб
відокремити потрібне значення, або
прямо задають його конкретний номер,
або його виділяють
неявно за допомогою умови-фільтру
типу
.
Щоб такий вибір був
однозначним,
обмежуються,
наприклад, першим з
,
що задовольняє або порушує фільтр. Якщо
всі
порушують (задовольняють)
,
то результат вибору конкретного значення
на даному вході
буде невизначений. Далі вважається, що
вибирається перше з
,
на якому порушується умова. Будемо
позначати нову функцію
і
називати
рекурентною
функцією, породженою системою (*) і
фільтром
.
Вона є частковою й має тип
. Композицію,
визначену на конструкторах системи (*)
і фільтрі
,
результатом якої є функція
,
назвемо -
-оператором.
На
практиці можуть варіюватися початкові
значення тільки окремих з
аргументів рекурентної функції, а решта
відіграють роль параметрів – вони або
просто фіксуються, або відразу обчислюються
за допомогою конструкторів. Перші
називаються вхідними
параметрами,
або входами,
рекурентної функції. Цікавими з
погляду результатів
можуть бути не всі компоненти в значенні
рекурентної функції, а тільки окремі з
них – вихідні.
Послідовності, які відповідають вихідним
компонентам, називаються опорними
в рекурентній системі. Послідовності,
що не належать ні до вхідних, ні до
опорних, називаються проміжними,
або робочими.
Нехай
та
– кількість відповідно вхідних і опорних
послідовностей. Рекурентні функції
із виділеними сукупностями вхідних і
опорних послідовностей називаються
параметризованими.
Наведемо кілька прикладів параметризованих рекурентних функцій.
Приклад 2.25. -й член арифметичної прогресії.
Нехай
–
арифметична прогресія з певною фіксованою
різницею
і початковим членом
.
Позначимо
–
-й
член арифметичної прогресії. Розглянемо
систему (*) із трьох рекурентних
послідовностей: арифметичної прогресії
,
послідовності-константи
і лічильника
з початковим значенням 1. Візьмемо за
фільтр умову
,
за вхідні послідовності –
та прогресію
,
за опорну – прогресію
.
Тоді
збігається зі значенням
.
Коректність такого подання
випливає з того, що лічильник з початковим
значенням 1 стає перший раз хибним саме
на
-му
кроці, тобто при
■
Приклад 2.26. Гармонічна функція.
Гармонічна
функція задає
-те
гармонічне число
і є рекурентною функцією
,
породженою фільтром
і системою рекурентних співвідношень
(*):
Вхідною
послідовністю є
,
а вихідною –
■
Нехай
певне
фіксоване натуральне число. Послідовності
називаються
-рекурентними
відносно
конструкторів
,
якщо всі їхні члени для
пов’язані співвідношеннями
(**)
,
,
… .
Щоб
повністю задати таку систему послідовностей,
достатньо задати перші
членів кожної послідовності
.
Решта знаходиться за допомогою
конструкторів. Наприклад, для
2-рекурентної
послідовності
,
тощо.
-рекурентні
послідовності можуть індексуватися і
з 0. Відомий приклад 2-рекурентної
послідовності – числа Фібоначчі ■
Приклад 2.27. Числа Фібоначчі:
за
означенням,
,
.
Тоді
,
,
і так далі. ■
Для
-рекурентних
послідовностей теж вводиться поняття
-рекурентної
функції
та
-оператора.
Конструкція аналогічна вищенаведеній,
-рекурентна
функція
має
тип
.
Теорема 2.1 (про обчислення -рекурентних функцій). Параметризовані -рекурентні функції, і тільки вони, обчислюються детермінованими стандартними програмами.
Доведення.
Ми
обмежимося доведенням тільки для випадку
непараметризованих функцій та програм.
Доведення у загальному випадку
суттєво
не зміниться (див. Вправу 8.)
Нехай на універсумі
задано довільну непараметризована
-рекурентну
систему (*) виміру
і фільтр
.
Покажемо, як за допомогою стандартної
програми обчислити
-рекурентну
функцію
.
Розглянемо
спочатку для простоти випадок
.
Для кожної з
рекурентних послідовностей введемо
змінну типу
та її дублікат. Нехай
{x,xx,…,z,zz}
–
сукупність усіх
таких змінних, де xx,…,zz
–
дублікати відповідних змінних. Тоді
потрібна стандартна програма Prog
має
вигляд:
/*Вх: x,…,z; Вих: x,…,z*/
{x:=
;…
z:=
;
while (Q(x,...,z)) do
{ /* обчислення нових значень змінних */
xx:=f(x,...,z);
…
zz:=g (x,..,z);
/* оновлення змінних */
x:=xx;
…
z:=zz;
}
}
Присвоювання
перед циклом початкових значень змінним
називається їх ініціалізацією.
Чергові нові члени рекурентних
послідовностей спочатку зберігаються
в дублікатах xx,…,zz
і тільки після цього пересилаються в
змінні x,…,z.
Якщо
відразу їх записати в змінні, то будуть
втрачені попередні значення, від яких
може залежати обчислення нових значень
в сусідніх послідовностях. Позначимо
векторний аналог програми Prog. У нашому
випадку тип
збігається з
.
Покажемо, що
для будь-якого набору початкових значень
із
.
Нехай
.
Це означає, що існують таке
і такі послідовності значень
змінної x
і
так далі
змінної
z,
що
(i)
;
(ii)
.
За
побудовою для всіх
значення вектора
збігається зі значенням функції
,
породженої даною системою рекурентних
співвідношень. Однак з умов (і)
та
(іі)
випливає:
є найменшим індексом таким, що
,
тобто
,
що й треба було довести.
Аналогічно
будується стандартна програма Prog для
-рекурентних
функцій. Тільки в цьому разі необхідно
зберігати
останніх членів кожної з
-рекурентних
послідовностей. Для цього необхідно
ввести
змінних, а також, як і вище, ще
змінних для обчислення нових членів
послідовностей. У тілі циклу після
визначення нових членів необхідно
поновити значення всіх
змінних (див.
прикл. 10.9.)
Нехай тепер маємо певну стандартну непараметризовану детерміновану програму Prog.
Покажемо:
якщо її складові обчислюють рекурентні
функції, то й вона робить те саме. Знову
припустимо, що
.
Для
доведення буде аналогічним. Нехай
складовими програми Prog є програми
Prog
,…,
Prog
з однаковими сукупностями змінних такі,
що
,
для певних рекурентних систем
(
)
,
,
...,
і
фільтрів
.
Потрібно за ними побудувати рекурентну
систему (*)
,
,
...,
і
визначити фільтр
так, щоб
.
1)
Нехай програма Prog є складеною
.
Визначимо додаткову рекурентну
послідовність:
,
,
,
для контролю за перебуванням обчислення
в просторі систем (
)
та (
),
а саме:
означає, що виконується Prog
,
у протилежному випадку – Prog
.
Система (*) складається з послідовності
і послідовностей системи (
)
та (
),
об’єднаних в одну рекурентну систему
такими умовними конструкторами:
,
,
…
.
Візьмемо
за фільтр
.
За побудовою система (*) та фільтр
є шуканими.
2)
Нехай програма Prog є розгалуженням
Prog
else
Prog
.
Введемо додаткову контролюючу
послідовність
,
де
– векторний аналог умови С,
,
,
смисл якої той самий, що й у п. 1).
Відмінність полягає в тому, тут
є константою. Рекурентною системою (*)
для програми Prog теж буде об’єднання
відповідних систем (
)
та (
)
з долученою послідовністю
. Конструктори при цьому отримують
охорону:
в системі (
)
і
в системі (
)
і стають умовними, а фільтром
буде формула
.
3)
Аналогічно будується рекурентна система
послідовностей для випадку, коли програма
Prog є обходом (частковий випадок
розгалуження) і вибором програм.
Зазначимо, що охорони у виборі попарно
не перетинаються (умова детермінованості
Prog). Тоді, як і в 2), для кожної з альтернатив
в систему (*) вводиться своя контролююча
послідовність
,
, конструктори мають відповідну охорону,
а фільтр
– це диз’юнкція всіх формул вигляду
,
,
що відповідають конролюючим послідовностям
і фільтрам складових програми Prog.
4)
Нехай тепер програма Prog є ітерацією
while
(С)
do
Prog
. Система (*) буде збігатися з такою для
випадку обходу, а фільтр
–
це формула
,
де
– векторний аналог умови С.
5) Випадок, коли програма Prog є повторенням вигляду do Prog while (Q), зводиться до вже розглянутих, оскільки така програма збігається з програмою {Prog while (Q) do Prog } . ■
Увага! Рекурентні співвідношення (*) та (**) у визначенні рекурентних і -рекурентних послідовностей задають тільки загальний вигляд взаємозв’язку між такими послідовностями. У багатьох випадках цей зв'язок виявляється досить простим. Зокрема, члени рекурентних послідовностей зазвичай залежать не від усіх, а тільки від окремих сусідів. Це дозволяє в програмах для рекурентних функцій шляхом підбору порядку оновлення змінних уникнути дублювання нових членів (усіх чи частини), а отже, і введення змінних-дублікатів (див. прикл. 2.28-2.33). Якщо ж член рекурентної послідовності не залежить від своїх попередників, то немає потреби задавати початковий член для даної послідовності.
