Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Зубенко, Омельчук - Програмування. Поглиблений курс

.pdf
Скачиваний:
52
Добавлен:
07.03.2016
Размер:
4.72 Mб
Скачать

Розділ ІІ. ЕЛЕМЕНТИ ІНФОРМАТИКИ

i

Hi = Σ 1/i , i 1, задаються системою рекурентних співвідношень

k =1

(*) H1 =1,Hi = Hi 1 +1/((i 1) +1);

i − лічильник, i1 =1.

Конструктором першої послідовності є операція f (x,y) = x +1/(y +1) . За означенням H 2 = H1 +1/(i1 +1) =1+1/2 = 3/2 , i2 = 2 тощо ■

2.5.3. РЕКУРЕНТНІ ФУНКЦІЇ

З кожною рекурентною системою послідовностей (*) виміру n по- в'язана певна функція F типу T n ×N T n , яка вектору α = (a0,b0,...)

початкових членів і числу i 0 ставить у відповідність вектор з і-х членів даних послідовностей:

def

F (α,i ) = αi , де αi = (ai ,bi ,...).

Щоб знайти значення функції F (α,m) для довільного m 0 , доста- тньо послідовно побудувати всі попередні значення F (α,i ), i =1,m 1.

Зазвичай для фіксованого початкового вектора α інтерес становлять не всі значення функції F члени послідовності αi ,i 0 , а лише виді-

лені, і найчастіше лише одне. Щоб відокремити потрібне значення, або прямо задають його конкретний номер, або його виділяють неявно за

допомогою умови-фільтра Q типу T n Bool . Щоб такий вибір був од- нозначним, обмежуються, наприклад, першим з αi , що задовольняє (порушує) фільтр. Якщо всі αi порушують (задовольняють) Q , то резуль- тат вибору конкретного значення на даному вході α буде невизначе- ний. Далі вважається, що вибирається перше з αi , на якому порушуєть-

ся умова. Позначимо нову функцію μQ(*) і назвемо її рекурентною, поро- дженою системою (*) і фільтром Q . Вона є частковою й має тип T n T n . Композицію, визначену на конструкторах системи (*) і фільтрі Q , результатом якої є функція μQ(*) , назвемо μ -оператором.

На практиці можуть варіюватися початкові значення тільки окре- мих із n аргументів рекурентної функції, а решта відіграють роль параметрів вони або просто фіксуються, або відразу обчислюються

201

ПРОГРАМУВАННЯ

за допомогою конструкторів. Перші називаються вхідними парамет- рами, або входами, рекурентної функції. Цікавими з погляду резуль- татів можуть бути не всі компоненти в значенні рекурентної функції, а тільки окремі з них вихідні. Послідовності, що відповідають вихід- ним компонентам, називаються опорними в рекурентній системі. По- слідовності, що не належать ні до вхідних, ні до опорних, називають- ся проміжними, або робочими. Нехай m та r кількість відповідно

вхідних і опорних послідовностей. Рекурентні функції μQ(*) : T m T r із

виділеними сукупностями вхідних і опорних послідовностей назива-

ються параметризованими.

Наведемо кілька прикладів параметризованих рекурентних функцій. Приклад 2.24. n -й член арифметичної прогресії.

Нехай a1 ,a2,... – арифметична прогресія з певною фіксованою різ- ницею d і початковим членом a1 = a . Позначимо an n -й член арифме-

тичної прогресії. Розглянемо систему (*) із трьох рекурентних послідов- ностей: арифметичної прогресії ak , послідовності-константи n і лічиль-

ника i з початковим значенням 1.

Візьмемо за фільтр умову

Q (i,n ) = i < n , за вхідні послідовності n

і прогресію ak , за опорну

прогресію ak . Тоді an збігається зі значенням μQ(*)(a,n) . Коректність та-

кого подання an випливає з того, що лічильник із початковим значен-

ням 1 стає перший раз хибним саме на n -му кроці, тобто при k = n Приклад 2.25. Гармонічна функція.

Гармонічна функція задає n -те гармонічне число Hn і є рекурен- тною функцією μQ(*) , породженою фільтром Q (i,n ) = i < n і системою

рекурентних співвідношень (*):

H1 =1,Hi = Hi 1 +1/i;

i − лічильник, i1 =1;n − константа.

Вхідною послідовністю є n , а вихідною Hi

Нехай m − певне фіксоване натуральне число. Послідовності

a1,a2,... Tb1,b2,... T...

202

Розділ ІІ. ЕЛЕМЕНТИ ІНФОРМАТИКИ

називаються m -рекурентними відносно конструкторів f ,g,..., якщо всі їхні члени для i m +1 пов'язані співвідношеннями

(**)ai = f (ai 1,ai 2,...,ai m ,bi 1,bi 2,...,bi m ,...),

bi = g (ai 1,ai 2,...,ai m ,bi 1,bi 2,...,bi m ,...), … .

Щоб повністю задати таку систему послідовностей, достатньо зада- ти перші m членів кожної послідовності a1 ,a2,...,am ,b1,b2,...bm ,.... Ре- шту знаходять за допомогою конструкторів. Наприклад, для 2-рекурентної послідовності a3 = f1 (a1,a2,b1,b2,...), b3 = f2 (a1,a2,b1,b2,...) тощо m -рекурентні послідовності можуть індексуватися і з 0. Відо-

мий приклад 2-рекурентної послідовності числа Фібоначчі ■

 

Приклад 2.26. Числа Фібоначчі.

 

 

За

означенням

f0 = f1 =1, fk = fk 2 + fk 1 ,

k 2 ,

тоді

f2 = f0 + f1 =1+1 = 2 , f3 = f1 + f2 =1+ 2 = 3 , f4 = f2 + f3 = 2 + 3 = 5 тощо ■

Для m -рекурентних

послідовностей

теж вводиться поняття

m -рекурентної функції

μ(*) та μ -оператора. Конструкція аналогічна

 

Q

має тип (T m )n T n .

вищенаведеній, m -рекурентна функція μQ(*)

Теорема 2.5 (про обчислення m -рекурентних функцій). Парамет- ризовані m -рекурентні функції, і тільки вони, обчислюються детермі- нованими стандартними програмами.

Доведення. Обмежимося доведенням тільки для випадку непараме- тризованих функцій і програм. Доведення в загальному випадку сут- тєво не зміниться (див. вправу 12). Нехай на універсумі T задано до- вільну непараметризовану m -рекурентну систему (*) виміру n і

фільтр Q : T n Bool . Покажемо, як за допомогою стандартної про- грами обчислити m -рекурентну функцію μQ(*) .

Розглянемо спочатку для простоти випадок m =1. Для кожної з n рекурентних послідовностей введемо змінну типу T та її дублікат.

Нехай

V ={x,xx,…,z,zz}

сукупність усіх 2n таких змінних, де

xx,…,zz

дублікати відповідних змінних. Тоді стандартна програма

Prog має вигляд:

 

/*Вх: x,…,z;

Вих: x,…,z*/

{x:=a1 ;… z:=b1 ;

 

203

ПРОГРАМУВАННЯ

while (Q(x,...,z)) do

{ /*обчислення нових значень змінних*/ xx:=f(x,...,z);

zz:=g (x,..,z); /*оновлення змінних*/

x:=xx;

z:=zz;

}

}

Присвоювання перед циклом початкових значень змінним назива- ється їх ініціалізацією. Чергові нові члени рекурентних послідовностей спочатку зберігаються в дублікатах xx,…,zz, і тільки після цього пере- силаються в змінні x,…,z. Якщо відразу їх записати в змінні, то будуть втрачені попередні значення, від яких може залежати обчислення но-

вих значень у сусідніх послідовностях. Позначимо Prog векторний аналог програми Prog. У нашому випадку тип Prog збігається з T n T n . Покажемо, що Prog (α ) = μQ(*) (α ) для будь-якого набору по-

чаткових значень α = (a ,b ,...) із T n . Нехай

 

(α) = (a,b,...). Це озна-

Prog

 

 

 

1

1

 

 

 

 

 

чає,

що

існують

таке k 1

і

такі

послідовності значень

 

 

 

 

a1(= a1),a2

,...,ak (= a)

змінної x тощо b1(= b1),b2

,...,bk (= b) змінної z, що

(i) i =1,...,k 1 Q(ai,...,bi) =1; (ii) Q(ak,...,bk) = 0 .

За побудовою для всіх 1 i k

значення вектора αi′ = (ai,bi,...) збі-

гається зі значенням функції F (α,i ), породженої даною системою ре- курентних співвідношень. Однак з умов (і) та (іі) випливає: k є най- меншим індексом таким, що Q(ak,...,bk) = 0 , тобто μQ(*) (α ) = αk =

= Prog (α), що й треба було довести.

Аналогічно будується стандартна програма Prog для m -рекурентних функцій. Тільки в цьому разі необхідно зберігати m останніх членів кожної з n m -рекурентних послідовностей. Для цього необхідно ввести n ×m змінних, а також, як і вище, ще n змінних для обчислення нових членів послідовностей. У тілі циклу після визначен- ня нових членів необхідно поновити значення всіх n ×m змінних.

Нехай тепер маємо певну стандартну непараметризовану детермі- новану програму Prog.

204

Розділ ІІ. ЕЛЕМЕНТИ ІНФОРМАТИКИ

Покажемо: якщо її складові обчислюють рекурентні функції, то й вона робить те саме. Знову припустимо, що m =1. Для m >1 доведен- ня буде аналогічним. Нехай складовими програми Prog є програми Prog1 ,…, Progn з однаковими сукупностями змінних такі, що

 

 

= μ(*k ) ,k =

 

для певних рекурентних систем

Prog

k

1,n

 

Q

 

 

k

( *k ) ai = f (k )(ai 1,bi 1,...), bi = g(k )(ai 1,bi 1,...), ..., i 2

і фільтрів Qk . Потрібно за ними побудувати рекурентну систему (*)

ai

= f (ai 1,bi 1,...), bi = g(ai 1,bi 1,...), ..., i 2 , і

визначити фільтр S

так, щоб

 

= μ(*) .

 

 

Prog

 

 

 

 

 

S

 

 

 

1) Нехай програма Prog складена: {Prog1Prog2 } . Визначимо додатко-

ву

 

рекурентну

послідовність:

r1 = Q1(a1,b1,...) ,

ri = (ri 1 = 0 ri 1 | Q1(ai ,bi ,...), i 2 , для контролю за перебуванням обчи- слення в просторі систем (*1 ) та (*2 ), а саме: ri =1 означає, що викону-

ється Prog1 , у протилежному випадку – Prog 2 . Система (*) складається з

послідовності ri і послідовностей систем (*1 )

 

та (*2 ), об'єднаних в одну

рекурентну систему такими умовними конструкторами:

a

i

= (r

=1 f (1)(a

i 1

,b

,...)| f (2)(a

i 1

,b

 

,...)),i 2

 

i 1

 

i 1

 

 

i 1

 

b = (r

=1 g(1)(a

i 1

,b

,...)|g(2)(a

i 1

,b

,...)),i 2

 

i

i 1

 

i 1

 

 

i 1

 

 

.

Візьмемо за фільтр S = (r =1 Q2 ). За побудовою система (*) і фільтр

Sє шуканими.

2)Нехай програма Prog є розгалуженням if (C ) Prog1 else Prog 2 .

Введемо додаткову контролюючу послідовність r1 = C (a1,b1,...), де C векторний аналог умови С, ri = ri 1 , i 2 , смисл якої той самий, що й у п. 1). Відмінність полягає в тому, що тут ri є константою. Рекурент- ною системою (*) для програми Prog теж буде об'єднання відповідних систем ( *1 ) та ( *2 ) із доданою послідовністю ri . Конструктори при цьому отримують охорону r =1 у системі ( *1 ) та r = 0 у системі ( *2 ) – і стають умовними, а фільтром S буде формула (r =1& Q1 r = 0 & Q2 ).

205

ПРОГРАМУВАННЯ

3) Аналогічно будується рекурентна система послідовностей для ви- падку, коли програма Prog є обходом (частковий випадок розгалужен- ня) і вибором. Зазначимо, що охорони у виборі попарно не перетина- ються (умова детермінованості Prog). Тоді, як і у 2), для кожної з альте- рнатив у систему (*) вводиться своя контролююча послідовність

ri(k ) ,k =1,n , конструктори мають відповідну охорону, а фільтр S це

диз'юнкція всіх формул вигляду (r(k ) =1& Qk ) , k =1,n , що відповідають контролюючим послідовностям і фільтрам складових програми Prog.

4)Нехай тепер програма Prog є ітерацією while (С) do Prog1 . Систе- ма (*) буде збігатися з такою для випадку обходу, а фільтр S це фо- рмула Q1 ¬Q1 & C , де C векторний аналог умови С.

5)Випадок, коли програма Prog є повторенням вигляду do Prog1

while (Q), зводиться до вже розглянутих, оскільки така програма збі-

гається з програмою {Prog1 while (Q) do Prog1 }

Увага! Рекурентні співвідношення (*) та (**) в означенні рекурент- них і m -рекурентних послідовностей задають тільки загальний ви- гляд взаємозв'язку між такими послідовностями. У багатьох випад- ках цей зв'язок виявляється досить простим. Зокрема, члени реку- рентних послідовностей зазвичай залежать не від усіх, а тільки від окремих сусідів. Це дозволяє в програмах для рекурентних функцій шляхом підбору порядку оновлення змінних уникнути дублювання нових членів (усіх чи частини), а отже, і введення змінних-дублікатів (див. прикл. 2.27-2.32). Якщо ж член рекурентної послідовності не залежить від своїх попередників, то немає потреби задавати почат- ковий член для даної послідовності ►

2.5.4. ТЕХНІКА ПОБУДОВИ СТАНДАРТНИХ ПРОГРАМ

Теорема 2.1 відкриває універсальний шлях до побудови стандарт- ної програми, яка обчислює задану залежність між величинами, а са- ме: спочатку необхідно специфікувати дану залежність як m -рекурентну за допомогою відповідного μ -оператора, а потім за

нею побудувати стандартну програму. При цьому теорему можна уза- гальнити й використовувати як конструктори будь-які похідні опера- ції та предикати базової алгебри. На практиці найчастіше це скла- дені й умовні операції.

206

Розділ ІІ. ЕЛЕМЕНТИ ІНФОРМАТИКИ

Проілюструємо дану техніку на прикладах із різних предметних областей.

Приклад 2.27. Для даних x R , n N обчислити суму sin x + sin x2 + ... + sin xn .

Аналіз.

Вхід: x R , n N . Вихід: s R .

Залежність: s = n sin xi .

i =1

Вимоги: побудувати стандартну програму (Prog9.7) для обчислення s . Базовою Ω -системою є дійсна й натуральна арифметики з операціями та предикатами + , –, *, /, %, =, <, до яких додано функцію sin.

Проектування. Побудувати стандартну програму для обчислення s означає побудувати таку програму, параметризований векторний аналог якої буде повертати як результат s . Побудуємо

1-рекурентну функцію μQ(*) для обчислення s , конструктори якої є по-

хідними операціями базової Ω -системи, і застосуємо до неї теоре- му 2.5. Ураховуючи, що сума s залежить від входів x та n , додамо до системи (*) вхідні послідовності-константи n та x і опорну послі-

довність s1 ,s2,...,sn ,sn +1,.... Спробуємо побудувати систему так, щоб

s = s . Оскільки s

n

k

, тобто

= sin xi , то покладемо s

= sin xi , k 1

n

n

k

i =1

 

 

 

i =1

 

за члени sk

виберемо часткові суми перших k

доданків суми s . Для

рекурентності послідовності sk необхідно знайти залежність суми sk

від

попередньої

суми sk 1.

Ця залежність має

вигляд

s

= s

+ sin(xk ). Оскільки операція додавання й функція sin

є при-

k

k 1

 

 

 

 

 

 

 

пустимими,

то псує дану рекурентну залежність тільки степінь xk .

Уведемо

в

систему

допоміжну

рекурентну послідовність

a

k

= xk ,

 

 

 

 

 

 

 

 

a1 = x , ak = ak 1 * x . Тоді sk = sk 1 + sin(ak ) і конструктор праворуч уже є припустимим. Щоб вибрати саме n -й член опорної послідовності, додамо до системи лічильник k,k =1. Тоді за фільтр Q можна взяти

умову Q(k,n) = k < n . Дійсно, для 1 k n 1 Q(k,n) =1 та Q(n,n) = 0 . Таким чином, побудована система (*) має вигляд

207

ПРОГРАМУВАННЯ

a1 = x,ak = ak 1 * x;

s1 = sin(x),sk = sk 1 +ak ;

k − лiчильник,k1 =1;n − константа;

x константа.

За побудовою s = μQ* (n,x) .

Кодування. Нехай ініціалізація вигляду v:=! означає присвоювання змінній v довільного припустимого значення. Для послідовностей систе- ми виберемо змінні з найменуваннями відповідно a,s,k,n,x. Серед них n, x вхідні, s вихідна, а a, k робочі змінні. Програма Prog9.7:

Лістинг.

/*Вх: x,n Вих: s */

{x:=!; n:=!;s:=sin(x); k:=1; a:=x; while (i<n) {a:=a*x;

s:=s+sin(a);

k:=k+1;

}

}

Структура програми Prog9.7 вимагає пояснення, оскільки відрізня- ється від стандартної, застосованої в доведенні теореми 2.5. Як бачимо, член sk залежить від sk 1 та ak (ak = ak 1 * x ) і не залежить від лічиль-

ника k , а член ak і лічильник k залежать тільки від своїх попередників ak та k 1 і не залежать від інших послідовностей. Вибраний порядок

зміни значень змінних забезпечує коректне їхнє оновлення й дозволяє не вводити в програмі Prog9.7 відповідні дублікати-змінні ■

Приклад 2.28. Знайти n -те число Фібоначчі, n 0 (див. прикл. 2.26).

Аналіз.

Вхід: n N . Вихід: f N .

Залежність: f = fn , де f0 = f1 =1, fi = fi 1 + fi =2 , i >1.

Вимоги: побудувати стандартну програму Prog9.8 для обчислення f . Базовою Ω -системою є натуральна арифметика зі стандартними

операціями та предикатами: + , –, *, /, %, =, <.

Проектування. Маємо послідовності: опорну fi та gi = fi 1 і послі- довність-константу n . Щоб вибрати саме n -й член опорної послідов-

208

Розділ ІІ. ЕЛЕМЕНТИ ІНФОРМАТИКИ

ності, введемо до системи лічильник i з початковим значенням 2. То- ді за фільтр Q можна взяти умову i < n . Таким чином, побудована

система (*) має вигляд:

f0 = f1 =1, fi = fi 1 + gi 1,i 2;

g1 =1,gi = fi 1,i 2;i1 = 2,i = (i 1) +1;

n − константа. За побудовою fn = μQ(*) (n).

Кодування. Виберемо змінні програми Prog9.8: f,ff,g,i та n. Се- ред них: n вхідна, f вихідна, а ff, g та i робочі змінні. Програ- ма Prog9.8 будується стандартно:

/*Вх: n N

Вих: f N */

{f:=1; g:=1;

 

i:=2; n:=!;

 

if (n 2)

 

while (i<n)

 

{i:=i+1;

 

ff:=f+g;

 

g:=f;

 

f:=ff;

 

}

 

}

 

У програмі використано змінну-дублікат ff для змінної f. Якщо

цього не зробити, то після присвоювання ff:=f+g зникне значення fi 1 , необхідне для оновлення g

Приклад 2.29.

 

Для даних x R , n N обчислити суму

x + x4 + x9 + + xn2 , уникнувши вкладених циклів.

Аналіз.

 

 

 

 

Вхід: x R , n N .

 

 

 

Вихід: s R .

n

 

 

 

Залежність: s =

 

2

.

xi

 

i =1

Вимоги: побудувати стандартну програму Prog9.9 для обчислення s . Базовою Ω-системою є дійсна й натуральна арифметики зі стандарт-

209

ПРОГРАМУВАННЯ

ними операціями та предикатами. Програма не має містити вкладені цикли, тобто цикли, які є в тілі іншого циклу.

 

Проектування. Як і у прикл. 2.27, шукана рекурентна система (*)

включає три послідовності: вхідні послідовності константи n та x

і послідовність часткових сум s1 ,s2,...,sn ,sn +1,...

таку,

що sn = s . Для

останньої маємо співвідношення s

= s

+ xk2 .

Уведемо в систему

 

 

 

k

k 1

 

 

 

 

 

 

 

 

допоміжну послідовність

a = xk2 .

Тоді

s

= s

 

+a

k

і

a = x

та

 

 

 

k

 

k

k 1

 

 

1

 

a

= a

* x2k 1 , k >1. Дійсно, якщо поділити a

на a

1

, то отримає-

k

k 1

 

 

 

 

k

 

k

 

 

 

мо саме x2k 1 . Знову конструктор містить піднесення до степеня та є неприпустимим у базовій алгебрі. Тому необхідно ввести ще одну до-

даткову

послідовність b = x2k 1

,

k 1. Маємо a = a

k 1

* b ,

 

 

k

 

k

k

b

= b

× x2,b = x. Як бачимо, остання послідовність рекурентна з

k

k 1

1

 

 

 

 

конструкторами похідними операціями базової алгебри. Отже, по- будована система (*) має вигляд:

a1 = x,ak = ak 1 * bk ;

b = x,b = b

* x2;

 

1

k

k 1

 

 

 

= x,s = s

+a ;

s

 

1

k

k 1

k

k − лічильник,k1 =1;

n − константа;

 

 

 

− константа.

 

x

 

 

 

 

 

 

За побудовою s = μQ* (n,x) .

Кодування. Змінні програми Prog9.9: a,b,s,k,n та x без дублікатів.

{n:=!; x:=!;k:=1;s:=a:=b:=x; while (i<n) {B:=B*X*X; A:=A*B;

S:=S+A;

K:=K+1;

}

}

Приклад 2.30. Наближено обчислити суму (1)[lg k ] /k . До кінце-

k =1

вої часткової суми додаються тільки члени, які за модулем строго бі- льші заданого ε > 0 . При цьому слід уникати вкладених циклів.

210

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]