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

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

.pdf
Скачиваний:
58
Добавлен:
07.03.2016
Размер:
5 Мб
Скачать
☆

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

Аналіз.

Вхід: ε R . Вихід: s R .

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

n

де

n

задовольняє

умову

∑ (−1)[lg k ] /k ,

 

k =1

 

 

 

 

1 ≤ k ≤ n |(−1)[lg k ] /k |> ε&|(−1)[lg(n +1)] /(n +1)|≤ ε.

Вимоги: побудувати стандартну програму Prog9.10 для обчислення s . Інші вимоги – ті самі, що й у прикл. 2.29.

Проектування. Початок такий, як і для обчислення сум. Знову ві- зьмемо три послідовності: вхідну послідовність-константу ε , лічиль-

ник k і опорну – із часткових сум s1 ,s2,...,sn ,sn +1,... таку, що sn = s .

Маємо

s =1 та s

= s

−1

+ (−1)[lg k ]

 

1

k

k

 

степінь

(−1)[lg k ] ,

 

розглянемо

a1 = 0,ak = [lgk],

k >1

 

та

sk = sk −1 + (ak %2 = 0 →1|−1)/k , ak = (k < bk −1 → ak −1|ak −1 +1), bk = (k < bk −1 → bk −1|bk −1 ×10) .

/k ,k >1. Щоб рекурентно подати дві допоміжні послідовності:

b

=10,b =10(ak +1)

,

k >1.

Тоді

1

k

 

 

 

Таким чином, маємо потрібну рекурентну систему. Лишилося знайти фільтр Q . Щоб припинити ітерацію, достатньо перевірити на наступно-

му кроці, чи буде модуль нового доданка ( = 1/(k +1)) більшим ніж ε . Як-

що так, то продовжити ітерацію, якщо ні – вийти з неї. Отже, фільтром Q(k,ε) може бути умова 1/(k +1) > ε. Остаточно система (*) має вигляд:

a1 = 0,ak = (k < bk −1 → ak −1|ak −1 +1);b1 =10,bk = (k < bk −1 → bk −1|bk −1 *10);s1 =1,sk = sk −1 + (ak %2 = 0 →1|−1)/k;k1 =1,k = (k −1) +1;

ε − константа.

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

Кодування. Змінні програми Prog9.10: a,b,s,k та ε – без дублі- катів. Сама програма Prog9.10 має вигляд:

/*Вх: x R , n N

Вих: s R */

211

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

{ ε :=!; k:=1;s:=1;a:=0;b:=10; while (1/(k+1)> ε ) {k:=k+1; a:=(k<b →a |a+1);

b:=(k<b →b | b*10); s:=s+(a%2=0 →1 | -1)/k;

}

}

Тут, як і в усіх попередніх програмах, удалося уникнути введення дублікатів змінних за рахунок спеціального порядку їхнього оновлен- ня: спочатку змінився лічильник, потім – змінна a (це принципово, тому що її оновлення залежить від поточного, а не нового значення b), а потім, у довільному порядку, – змінні b та s ■

Приклад 2.31. Швидке піднесення до степеня. Дано n N . Реалі- зувати піднесення до степеня в півгрупі P = (A,o) з кількістю множень

в обчисленні c(n) = О(log2 n) .

Аналіз

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

Залежність: p = xn .

Вимоги: побудувати стандартну програму Prog9.11 для обчислення p із кількістю множень c(n) =О(log2 n) . Базовою Ω -системою є пів-

група P = (A,o) і натуральна арифметика зі стандартними операціями

та предикатами.

Проектування. Якщо вибрати прямий підхід до обчислення степе- ня й покласти p1 = x, pk = pk −1 o x , то отримаємо кількість множень c(n) = n −1.

Щоб підвищити ефективність алгоритму, подамо показник степеня n

у двійковій системі. Нехай

n = b

+b 21

+b 22 +... +b 2k

для

певних

bi {0, 1}, де k = [

 

0

1

 

2

 

k

 

 

 

log2 n ]. Тоді з урахуванням асоціативності півгрупо-

вого множення

степінь

xn

можна

записати

як

добуток

xb0 × xb1×2 × xb2 ×22 ×...× xbk ×2k , в якому міститься вже тільки k

множень.

Розглянемо три послідовності: вхідні послідовності-константи

x

та n і

опорну – із часткових добутків p , p ,..., p

, тобто

p

def

i

 

j

=

∏ xbj 2

. Тоді

 

 

0

1

k

 

i

 

j =0

 

 

 

 

 

 

 

 

 

 

 

 

212

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

p

= xb0 ,

p = p , p = p

 

o xbi 2i

= p

o(b =1 → x2i |1) , i ≥1

. Нам зна-

0

 

k

i

i −1

 

i −1

i

 

 

 

 

 

 

 

 

 

 

 

 

def

добляться

ще

три

додаткові

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

ai = x2i ,

qi

= qi −1 /2, bi

= qi %2 . Дві останні необхідні для відшукання двійко-

вих цифр натурального числа n . При цьому q0 = n ,

b0 = n%2 , a0 = x

та ai = ai −1 oai −1 . Дійсно,

якщо розділити ai на ai −1 ,

то отримаємо в

результаті ai −1 . Залишилось визначитись із фільтром обчислення.

Фільтр із лічильником не зовсім влаштовує, оскільки він потребує до- даткового обчислювання значення k . Менш очевидним, але набагато простішим, є фільтр Q(qi ) = (qi > 0). З ним отримуємо систему (*):

a0 = x,ai = ai −1 oai −1;

 

 

 

 

p

0

= (n%2 =1 → x |1), p

= p

o(b

=1 → a

|1);

 

 

i

i −1

i

i

 

(*5 ) q0 = n,qi = qi /2;

 

 

 

 

b0 = n%2,bi = qi %2;

 

 

 

 

x

− константа;

 

 

 

 

 

− константа.

 

 

 

 

n

 

 

 

 

 

 

 

 

 

 

 

 

За побудовою p = μ*

(x,n) .

 

 

 

 

 

 

Q

 

 

 

 

 

Кодування. Змінні програми Prog9.11 a,b,x,n,p,q – без дубліка- тів. Програма Prog9.11:

/*Вх: x A , n N

Вих: p R */

{x:=!;n:=!;a:=x;q:=n;b:=n%2; p:=(n%2=1 →x|1);

while (q>0) {a:=a oa; q:=q/2;

b:=q%2;

p:=p o(b=1 →a|1);

}

}

Її можна дещо удосконалити, усунувши змінну b. Ця змінна віді- грає роль логічного прапорця, який можна замінити його поточним значенням q%2. Новий варіант програми Prog9.11 може бути таким:

/*Вх: x A , n N .

Вих: p R */

213

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

{x:=!;n:=!;a:=x;q:=n; p:=(n%2=1 →x|1);

while (q>0) do {a:=a oa; q:=q/2;

p:=P o(q%2=1 →a|1);

}

}■

Нескладно перевірити, що кількість множень c(n) у обчисленнях за програмою перебуває в межах c(n) ≤ 2[log2 n], що задовольняє

умову задачі.

Приклад 2.32. Дзеркальне обернення кортежів.

Аналіз.

Вхід: f T * , k ≥ 0 . Вихід: g T * .

Залежність: g = f R , де f R – дзеркальне обернення кортежу f . Вимоги: побудувати стандартну програму Prog9.12 для обернення

кортежів. Нехай f = [f1,..., fn ]. Базовими операціями є: взяття голови head (f ) = f1 , взяття хвоста tail (f ) = [f2...fn ] та pre - додавання ком-

поненти в початок кортежу. Базовим предикатом є рівність = . Проектування. Нехай f = [f1,..., fn ] і u1,...,ui ,...,uk – опорна послі-

довність така, що uk = g . Обернення кортежів має важливу власти-

вість: [f1, f2,..., fn ]R = app([f2,..., fn ]R , f1 ). Покладемо

u1 = head (f ) і

 

 

послідовність v1 = f ,

vi

 

def

[fi ,..., fn ], i >1. Тоді

введемо допоміжну

 

=

 

 

def

pre(head (vi ),ui −1 ). Для vi

визначимо кортеж ui рекурентно як ui =

справедливе співвідношення vi = tail(vi −1 ).

За

фільтр

можна взяти

предикат Q (vi )= [],

де [] – порожній кортеж. Отже, побудована реку-

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

 

 

 

 

 

 

v1 = f ,vi = tail(vi −1 );

 

 

 

 

 

 

u

= head (f ),u = pre(head

(v

i

),u

);

 

 

1

i

 

 

i −1

 

 

 

− константа.

 

 

 

 

 

 

f

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

За побудовою g = μQ* (f ).

214

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

Кодування. Змінними в програмі є v,u,f без дублікатів. Програма Prog9.12 будується стандартно за рекурентною системою (*) :

/*Вх: f T * .

Вих: u T * */

{f:=!;v:=f;u:=head(f); while (v ≠ []) {v:=tail(v);

u:=pre(head(v),u));

}

}

■

Увага! Коректність побудованих у прикл. 2.27–2.32 програм нескладно довести математично. Для цього достатньо перевірити коректість рекурентних функцій, породжених відповідними системами (*), і потім послатися на теорему 2.5 ►

Повернемося до прикл. 2.27. Небхідно довести, що s = μQ* (n,x ). Для

цього достатньо показати, що правильно вибрані конструктори для опорноюї й решти послідовностей, а також фільтр.

Спочатку

перевіримо

 

коректність

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

a1 = x ,

ak = ak −1 * x

та

s1 = sin(x ),

 

sk = sk −1 + sin(ak ).

Необхідно

показати

істинність

твердження

 

P(x):

k ≥1

 

(a

 

 

k

 

 

= xk & s = ∑ sin xi ).

 

 

 

 

 

 

 

 

k

 

k

i =1

Скористаємося математичною індукцією за k .

 

 

 

 

 

База індукції: a1 = x , s1 = sin(x) (за означенням).

 

 

Індуктивний перехід. Припустимо, що a

 

= xk −1 та

s

= k∑−1sin xi

 

 

 

 

 

 

k −1

 

 

k −1

i =1

 

 

k >1.

 

 

 

 

 

 

 

 

для довільного

Тоді

за

рекурентними

співвідношеннями:

ak = ak −1 * x ,

sk = sk −1 + sin(ak )

і, з урахуванням

індуктивного

припущення,

a

= xk ,

s =

k −1

 

 

k

 

Таким чином,

 

∑ sin xi + sin xk

= ∑ sin xi .

 

k

 

k

i =1

 

i =1

 

 

 

 

 

 

 

 

 

 

 

індуктивний перехід має місце і з повноти індукції випливає P (x ).

Щоб довести коректність

вибору

фільтра Q(k,n) = k < n , необхідно

показати

коректність

твердження

1 ≤ k ≤ n −1 (k < n)&(¬n < n).

Оскільки

(n < n) хибне,

то

¬(n < n )

–

істинне, а істинність першого

215

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

коньюнктивного члена випливає з означення лінійного порядку на множині натуральних чисел. Отже, ми довели, що μQ* (n,x ) = sn = s ■

У загальному випадку в подібних доведеннях застосовується метод структурної індукції, що розглядається в підрозд. 1.4.1.

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

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

*Література для CР: СБС і алгоритми – [19, 32, 49, 50]; pекурентні співвідношення й функції – [19, 28, 122].

Контрольні запитання та вправи

1.Дати визначення структурних композицій.

2.Що таке ССП?

3.Як інтерпретуються ССП?

4.Що таке структурний алгоритм і абстрактна структурна програма? Яка між ними різниця?

5.Що таке циклічний структурний алгоритм?

6.Що таке рекурентна послідовність?

7.Що таке конструктор рекурентної послідовності?

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

9.Що таке рекурентна функція?

10.Дати визначення μ -оператора.

11.Як пов'язані рекурентні функції й циклічні блок-схеми?

12.Довести теорему 2.5 для параметризованих функцій і програм.

13.Показати, що теорема 2.5 залишається вірною, якщо у стандартних програмах зафіксуквати базову алгебричну систему, а серед конструкторів у μ -операторах припустити будь-які її похідні операції.

14.Показати, що композиція мінімізації (див. вправу 15 із підрозд. 1.3) є частковим випадком μ -оператора.

Вказівка. У вправах 15-21 необхідно побудувати стандартні

програми з доданими функціями cos (x ), sin(x ) та

.

У вправі 20 мається на увазі стандартний арифметичний базис. Усі числа розглядаються в десятковій системі.

216

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

15.Дано n N.

а) З'ясувати, чи містить десяткове подання числа n вхо- дження цифри 7, і підрахувати кількість таких входжень.

б) Поміняти місцями першу й останню цифри в числі. в) Приписати одиницю ліворуч і праворуч до числа n.

16.Дано a,b,c,d N. Знайти найбільший спільний дільник цих

чисел. Використати алгоритм Евкліда для відшукання НСД двох натуральних чисел за допомогою віднімання.

17. Дано n N. Обчислити:

 

 

 

 

 

 

 

 

 

1

 

 

1

 

 

1

 

 

а) 1

+

 

 

 

+ 1

+

 

 

+.... + 1

+

 

 

 

 

;

 

2

2

n

2

 

 

1

 

 

 

2

 

 

 

 

 

 

б)

2 +

 

2 +... +

2 ;

 

 

 

144424443

 

 

 

 

 

 

 

n

 

 

 

в)

cos1

× cos1+ cos 2

×...× cos1+... + cosn

;

 

sin1

 

 

sin1+ sin2

sin1 +... + sinn

 

 

n

 

 

 

sin(k x)

 

 

г)

∏

1+

 

 

.

 

 

 

k !

 

 

 

i =1

 

 

 

 

 

 

18.Дано a R ,n N . Обчислити:

а) sin x + sin2 x +... + sinn x; б) sin x + sin2x +... + sinnx;

б) sin x + sinsin x +... + sin...sin x .

144444424444443

n

19. Дано n N. Обчислити:

 

 

 

 

 

 

 

 

 

 

 

1×

3 ×...×n, якщо n − непарне

;

 

 

 

 

 

 

 

 

 

а) n !! =

× 4 ×...×n, якщо n − парне

 

 

 

 

 

 

 

 

 

 

2

 

 

 

 

 

 

 

 

 

 

 

б) добуток перших n співмножників 2

×

2

×

4

×

4

×

6

×

6

×...

 

1

 

3

 

3

 

5

 

5

 

7

 

20. Дано x R,n N. Обчислити, уникнувши вкладених циклів:

n

(−1)i(i +1)/2

; б) *

n

(−1)[ k ]

xk ; в) *

n

c(k)

 

 

 

 

а) ∑

 

∑

 

∑

 

 

 

 

,

c(k)

 

– кіль-

i !

k

 

 

k2

 

i =1

 

k =1

 

n

k =1

 

n

 

 

кість десяткових цифр у числі k ; г) *

 

3

; д) *

4

.

∑ xi

 

 

∑ xi

 

 

 

 

 

 

 

i =1

 

 

 

 

 

i =1

 

 

21.Даноx R,n N . Реалізувати швидке множення n ×m із кількістю додавань O([log2 n]).

22.Довести коректність стандартних програм із прикл. 2.28-2.32.

217

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

2.6. Індуктивні означення

¾Індуктивні означення множин та їхніх систем

¾Індуктивні означення функцій

¾Рекурсивні специфікації

Ключові слова: індуктивне означення множини й систем множин, конструктор, повнота, повнота слабка, фільтр, правило виведення, висновок, гіпотеза, аксіома, теорема, індуктивне означення функції й систем функцій,

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

Індуктивні означення множин і функцій відіграють надзвичайно важливу роль у математичній логіці, теорії алгоритмів і програмуванні. Вони лежать в основі рекурсивних методів програмування.

2.6.1. ІНДУКТИВНІ ОЗНАЧЕННЯ МНОЖИН ТА ЇХНІХ СИСТЕМ

Індуктивні означення базуються на понятті алгебричного замикання (див. підрозд. 1.4.1). Тому повернемося до нього й розглянемо детальніше.

Нехай

B* – замикання довільної

підмножини

B A

в

алгебрі

A = (A;ΩF ).

 

 

∞

 

 

Лема 2.1. Для замикання B* має місце рівність

B*

 

 

= U Bi

(*), де

 

 

 

 

i =0

 

B0 = B ,

Bi +1 = Bi B%i , а сукупність

B%i складають

усі

можливі

значення операцій алгебри A на аргументах із Bi , i

≥ 0 .

 

∞

 

Доведення. За побудовою Bi Bi +1 ,

i ≥ 0 . Позначимо B% =

Bi . Не-

U

 

 

 

 

 

i =0

 

складно перевірити, що B% є замкненою надмножиною B

і для всіх

i ≥ 0 Bi B* (математична індукція по i ), отже, B* = B%i ■

 

 

Як випливає з рівності (*), кожний елемент b системи B*

належить

усім множинам Bi , i ≥ k, для деякого k N . Тоді за означенням або

218

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

b Bk −1 , або b побудований з елементів сукупності Bk −1 за допомогою

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

Лема 2.2. Кожний з елементів замикання B* є значенням певного Ω -терму.

Доведення. Зафіксуємо певну сигнатуру констант Ωc для елементів

множини

B = B0

і

сигнатуру

функціональних

символів

Ωf = {f1n1 , f2n2 ,K} –

для операцій алгебри. Тоді за (*) елементам із B1

відповідають константи з Ωc і терми вигляду fini (c1′,...,cn′ i

), побудо-

вані з термів-констант, елементам із B2 – терми елементів із B1 і тер-

ми вигляду

fini (t1,...,tn i ), де t1,...,tn i –

терми елементів із B1 ; узагалі,

елементам із Bi , i N , відповідають терми елементів із Bi −1 і побудо- вані з них терми вигляду fini (t1,...,tn i ) ■

Нехай U – певний універсум елементів. Структура індуктивного означення (ІО) довільної підмножини M елементів універсума має такий вигляд:

(Б) База індукції. Фіксується певна підмножина M0 U апріорі виділених базових об'єктів.

(І) Індуктивний перехід. Вибирається певна сукупність {Fi }

конструкторів – операцій на універсумі U . Конструктори за базови- ми й уже побудованими елементами універсума дозволяють отри- мувати його нові елементи.

(ПС) Повнота cлабка. Вибирається певний предикат-фільтр P (x ), визначений на універсумі U , який здійснює відбір елементів

def

замикання U0* до означуваної множиниM : M = P(U 0* ).

Фільтри, подібні P (x ), називаються термінаторами, а елементи, які вони пропускають – термінальними. Наприклад, добре відома роль термінатора P (x )= "x Σ* " у КВ-граматиках, який з усіх слів, що виводяться з аксіоми, відбирає слова в основному алфавіті.

219

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

Отже, індуктивно означену множину складають термінальні елеме- нти алгебричного замикання.

Увага! Якщо всі базові й усі нові побудовані за ними елементи на- лежать означуваній множині, то M =U0* і фільтр стає непотрібним. У

цьому випадку (ПС) замінюється на повноту (П). Якщо в означенні взагалі відсутня згадка про повноту, то це означатиме, що йдеться про повноту (П) ►

Індуктивно означені множини будемо називати також просто інду- ктивними й позначати M = M (M0,{F i },P ). У математичній логіці

конструктори

Fi називають

правилами виведення.

Рівність

x = c (x1,...,xn ),

c {Fi }, позначають x1,...,xn x . При цьому елементи

 

 

c

 

x1,...,xn називають гіпотезами,

x – висновком правила c ,

а базові

елементи з M0 – аксіомами. Виведенням елемента a з аксіом назива- ється послідовність елементів a1,...,am = a така, що для всіх 0 ≤ i ≤ m ai є або аксіомою, або висновком певного правила виведення з гіпо- тез, що належать a1,...,ai −1 . Індуктивно означену множину M (M0,{F i },P ) складають теореми – ті елементи, що можуть бути ви-

ведені з аксіом і є термінальними.

Наведемо кілька важливих прикладів індуктивних множин. Увага! На практиці при введенні індуктивних означень фіксують

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

Приклад 2.33. Натуральні числа (ІО1 ). (Б1 ) 0 – натуральне число.

(І1 ) Конструктор s : N → N породжує наступне за порядком число, тобто s (n )= n +1.

Дійсно, 0 s (0)(=1) s (s (0))(= 2) тощо ■

Приклад 2.34. Слова (ІО2 ).

Нехай Σ = {a1,a2,...,an } – довільний алфавіт.

(Б2 ) ε Σ* – порожнє слово й літери алфавіту Σ є базовими. (І2 ) Конструктор pre : Σ× Σ* → Σ* визначимо так:

pre(a,b1b2...bm ) = ab1b2...bm .

220