1.1. Вступ. Висловлювання. Логічні операції Логіка – це набір правил для отримання обгрунтованих висновків. Вона лежить в основі безспірних міркувань та доведень. Математична логіка – розділ дискретної математики, в якому вивчають методи і закономірності логічних обгрунтувань. Основним предметом її розгляду є твердження (висловлювання), прийоми та методи утворення нових тверджень з тих, що вже існують, опис їхніх властивостей. Перші думки про можливість формалізації логіки подано ще в працях Арістотеля. У сучасному розумінні логіка як наука сформувалася у XIX столітті завдяки працям Дж. Буля, А. де Моргана, Г. Фреге, Е. Шредера. Істотний внесок у подальший розвиток математичної логіки зробили А. Уайтхед, Б.Рассел, Д. Гільберт, К. Гедель, А. Тарський, А. Черг, А. Мальцев, П. Новіков та інші. Математичну логіку, яка виникла зі спроби формалізувати людські міркування, використиовують у всіх галузях математики та суміжних науках: кібернетиці, теорії алгоритмів, програмуванні, лінгвістиці тощо. Спочатку ми вивчимо логіку висловлювань, яка має справу з істинністю (чи хибністю) простих описових тверджень (висловлювань). Її можна розглядати як короткий вступ до логіки предикатів (предикатами називають твердження, які містять змінні величини). В цьому розділі вивчимо різні методи доведень (пряме та обернене міркування, метод «від протилежного», метод математичної індукції), проілюструємо їх використання прикладами перевірки фактів про парні та непарні числа, а також прикладними задачами перевірки коректності алгоритмів у галузі інформатики. Означення 1.1.1. Просте висловлювання (атомарна формула, атом) – це розповідне речення, про яке можна сказати, що воно істинне (T або 1) або хибне (F або 0), але не те й інше водночас. Ми будемо позначати їх великими латинськими буквами з індексами або без (пропозиційними буквами). Істиннісне значення – це істина або хибність, приписана деякому висловлюванню. Істинність чи хибність простого висловлювання визначається міркуваннями, які залишаються поза математичною логікою (з емпіричного досвіду, даних науки чи наших відчуттів). Приклад 1.1.1 Земля – плоска; Київ – столиця України; 29 – просте число; Сиди спокійно! Котра година? Розв’язання Перші три речення є висловлюваннями, останні два – ні, бо вони не розповідні. При цьому перше з них є хибним, а друге та третє – істинними простими висловлюваннями. ▲ Приклад 1.1.2. Визначимо, які з висловлювань є атомами: Падає дощ. Я отримав добру оцінку. Я забув вивчити логіку і отримав «двійку». Розв’язання Перші два висловлювання є атомами, а третє – ні, бо воно містить два висловлювання: «я забув вивчити логіку» і «я отримав «двійку»». ▲ Математична логіка встановлює істинність складних всловлювань, якщо істинність простих висловлювань уважати відомою. Як в математичній логіці з простих висловлювань будують складне? Це робиться за допомогою логічних операцій. Методи отримання нових висловлювань із тих, що вже маємо, запропонував англійський математик Дж. Буль у 1851 р. у книзі «Закони мислення» («Дослідження законів мислення, на яких засновані математичні теорії логіки й імовірності»). Означення 1.1.2. Складне висловлювання – це висловлювання, побудоване з простих за допомогою логічних операцій (логічних зв’язок). Найчастіше вживаними операціями є 6: заперечення (читають «не», позначають , –), кон’юнкція (читають «і», позначають ), диз’юнкція (читають «або», позначають ), імплікація (читають «якщо ..., то», позначають ), альтернативне «або» (читають «додавання за модулем 2», позначають ), еквівалентність (читають «тоді і лише тоді», позначають ). Інші логічні операції розглянемо в розділі 7. Означення 1.1.3. Запереченням довільного висловлювання Р називають таке висловлювання P , істиннісне значення якого строго протилежне значенню Р. Кон’юнкцією або логічним множенням двох висловлювань P та Q називають складне висловлювання P Q, яке набуває істинного значення тільки в тому випадку, коли істинні обидві його складові. Диз’юнкцією або логічним додаванням двох висловлювань P та Q називають складне висловлювання P Q, яке набуває істинного значення в тому випадку, коли істинною є хоча б одна його складова. Імплікацією двох висловлювань P та Q називають умовне висловлювання «якщо P, то Q» (P Q), яке прийнято вважати хибним тільки в тому випадку, коли передумова (антецедент) P істинна, а висновок (консеквент) Q хибний. У будь-якому іншому випадку його вважають істинним. Альтернативним “або” двох висловлювань P та Q називають складне висловлювання P Q, яке набуває істинного значення тоді і лише тоді, коли P та Q мають різні логічні значення, і є хибним в протилежному випадку. Еквіваленцією двох висловлювань P та Q називають складне висловлювання P Q, яке набуває істинного значення тоді і лише тоді, коли P та Q мають однакові логічні значення, і є хибним в протилежному випадку, тобто логічно еквівалентні складні висловлювання – це висловлювання, які набувають однакових значень істинності на будь-якому наборі істиннісних значень своїх складових. Перша введена логічна операція є унарною (операцією над однією пропозиційною змінною), наступні п’ять – бінарними (пов’язують дві пропозиційні змінні). Зауважимо, що в повсякденному житті слово “або” вживають в розумінні “хоча б одне з двох” і в розумінні “лише одне з двох” (альтернативне або). Ми до цього звикли, і це не шкодить розумінню. Проте латинська мова щодо цих випадків досконаліша: слово “vel” означає перший (його перша буква й стала символом диз’юнкції), а слово “aut” – другий. Звернемо також увагу, що конструкція типу «if P then S», яку використовують у багатьох мовах програмування, принципово відрізняється від введеної вище операції імплікації. У цій конструкції лише Р висловлювання (зокрема, й складне), а S – програмний сегмент. Щоб визначити значення істинності складних висловлювань, нам необхідно вияснити зміст логічних операцій, тобто визначити, як вони впливають на істиннісне значення простих висловлювань. Це можна зробити за допомогою так званої таблиці істинності логічних операцій (табл. 1.1). В її останньому стовпці містяться значення істинності формули залежно від значень істинності її складових частин. Таблиця 1.1 P T T F F Q T F T F P F F T T P Q T F F F P Q T T T F P Q T F T T P Q F T T F P Q T F F T Правила побудови формули визначають так: 1. Атомарна формула є формулою. 2. Якщо Р формула, то і ( P ) теж формула. 3. Якщо P та Q формули, то і (P Q), (P Q), (P Q), (P Q), (P Q) теж формули. 4. Формули отримують лише скінченною кількістю застосувань правил 1-3. Якщо не виникає непорозуміння, то зовнішні дужки у формулах можна опускати. Логічні операції над висловлюваннями здійснюють у визначеній послідовності, яку називають пріоритетом логічних операцій, а саме: , , , , , , і зайві дужки часто опускають. Приклад 1.1.3. Використовуючи логічні операції, побудуємо складні висловлювання і виразимо їх в символьній формі: а) Земля не плоска; б) Земля плоска або Іван Петрович – лікар; в) Земля плоска і Іван Петрович – лікар. Розв’язання Позначимо через Р висловлювання «земля плоска», Q – «Іван Петрович – лікар». Тоді а) P ; б) P Q; в) P Q. ▲ Означення 1.1.4. Символьна форма (формула) – це атомарна формула або складне висловлювання; п-місна формула – це формула, що містить п атомів. Інтерпретація формули – це набір значень істинності (Т або F) всіх атомів у заданій формулі. Для того, щоб знайти значення істинності складного висловлювання у певній інтерпретації, треба підставити відповідні значення істинності для всіх атомів цієї інтерпретації та спростити її. Зрозуміло, що п-місна формула має 2п інтерпретацій, тобто існує 2п способів надати значення істинності її атомам. Якщо атомарними формулами є два висловлювання, то двомісна формула має 22=4 інтерпретації. У випадку чотирьох атомарних формул маємо 24=16 інтерпретацій для чотиримісної формули. Означення 1.1.5. Тавтологія – формула, що виконується у всіх інтерпретаціях (тотожно істинна формула). Протиріччя – формула, що не виконується у жодній інтерпретації (тотожно хибна формула). Формулу називають нейтральною, якщо вона не є ні тавтологією, ні протиріччям (для неї існує принаймні один набір пропозиційних змінних, на якому вона приймає значення Т, і принаймні один набір, на якому вона приймає значення F). Виконана формула – це формула, що не є протиріччям (інакше кажучи, вона принаймні на одному наборі пропозиційних змінних набуває значення Т). Приклад 1.1.4. Показати, що висловлювання твердженню ( ( P ( Q ))) логічно еквівалентне (( P ) Q ) . Розв’язання. Атомарними формулами тут є P та Q, тому формула має 22=4 інтерпретації. Заповнимо спільну таблицю істинності (табл. 1.2) для складних висловлювань R= ( ( P ( Q ))) та S= (( P ) Q ) : Таблиця 1.2 P T T F F Q T F T F P F F T T Q F T F T P ( Q ) F T F F R T F T T S T F T T Два останні стовпці таблиці ідентичні. Це означає, що висловлювання R логічно еквівалентне висловлюванню S. ▲ Приклад 1.1.5. Показати, що висловлювання (( Q ) ( P )) логічно еквівалентне твердженню (P Q). Цю логічну еквівалентність називають правилом контрапозиції, а висловлювання (( Q ) ( P )) називають протилежним або контрапозитивним до висловлювання (P Q). Розв’язання. Заповнимо спільну таблицю істинності (табл. 1.3): P Q P Q P Q Таблиця 1.3 ( Q ) P T T F F T F T F F F T T F T F T T F T T T F T T Оскільки два останні стовпці цієї таблиці співпадають, то і висловлювання, про які йде мова, логічно еквівалентні. ▲ Приклад 1.1.6. Показати, що висловлювання твердженню PQ логічно еквівалентне P Q. Розв’язання. Заповнимо таблицю істинності (табл. 1.4): Таблиця 1.4 P T T F F Q T F T F P F F T T P Q T F T T P Q T F T T Оскільки два останні стовпці цієї таблиці співпадають, то і висловлювання, про які йде мова, логічно еквівалентні. ▲ Приклад 1.1.7. Показати, що формула (( P ) ( P Q )) є тавтологією. Розв’язання. Заповнимо таблицю істинності (табл. 1.5): Таблиця 1.5 P T T F F Q T F T F P F F T T P Q T F T T (( P ) ( P Q )) T Т T T Формула істинна у всіх інтерпретаціях, тому це тавтологія. ▲ Приклад 1.1.8. Показати, що формула ( P ( ( Q P ))) є протиріччям. Розв’язання. Заповнимо таблицю істинності (табл. 1.6): Таблиця 1.6 P Q Q Р (Q P ) ( P ( ( Q P ))) T T F F T F T F T Т T F F F F T F F F F Формула хибна у всіх інтерпретаціях, тому це протиріччя. ▲ Означення 1.1.6. Атом називають фіктивним, якщо значення формули не залежить від його значення, тобто атом Хі формули F(X1,..., Xі-1, Xі, Xі+1, ..., Xп) є фіктивним, якщо F(Х1,..., Хі-1, 0, Хі+1, ..., Хп)=F(Х1,..., Хі-1, 1, Хі+1, ..., Хп) для довільних Х1,..., Хп. Якщо атом не є фіктивним, то його називають значущим. Приклад 1.1.9. Вказати, які атоми у формулі (( P Q ) ( R R)) є фіктивними, а які – ні. Розв’язання. Атомарних формул тут є 3, тому формула має 23=8 інтерпретацій. Складемо таблицю істинності (табл. 1.7): Таблиця 1.7 P Q R (Р Q) ( R R) (( P Q ) ( R R)) R T T Т Т F F F F T T F F T T F F T F T F T F T F T T T T T T F F F T F T F T F T F F F F F F F F T T T T T T F F Як бачимо з таблиці, значення висловлювання R не впливає на значення формули (4-й та 7-й стовпці однакові), тому воно є фіктивним, а висловлювання Р та Q значущі. ▲ 1.2. Закони логіки висловлювань Означення 1.2.1. Еквівалентні формули, що визначають правила перетворень, називають законами логіки висловлювань. Основні закони логіки висловлювань: закон асоціативності означає, що під час використання однакових знаків (лише кон’юнкції або лише диз’юнкції) дужки можна ставити в будь-якому порядку або взагалі опускати; закон комутативності означає, що під час множення (кон’юнкції) та додавання (диз’юнкції) результат не залежить від порядку змінних; закон ідемпотентності означає, що добуток (кон’юнкція) двох однакових висловлювань чи їхня сума (диз’юнкція) еквівалентні самому висловлюванню; закон дистрибутивності виражає правило винесення спільного висловлювання за дужки; закон протиріччя означає неможливість набуття значень істинності суперечливих (протилежних за значенням) висловлювань; закон виключення третього стверджує, що із двох протилежних висловлювань на однакову тему одне завжди істинне, а друге – хибне, третього не буває; закон подвійного заперечення стверджує, що подвійне заперечення виключає заперечення; закони де Моргана пов’язують заперечення з операціями кон’юнкції та диз’юнкції. Основні закони логіки висловлювань наведено в табл. 1.8. Таблиця 1.8 Закони логіки висловлювань А В Закони асоціативності ( P Q ) R P (Q R ) ( P Q ) R P (Q R ) Закони комутативності PQ QP PQ QP Закони ідемпотентності PPP PPP Закони дистрибутивності P (Q R ) ( P Q ) ( P R ) P (Q R ) ( P Q ) ( P R ) Закони доповнення закон виключення третього: P ( P ) T закон протиріччя: P ( P ) F закон подвійного заперечення: ( P ) P Закони де Моргана (P Q) P Q (P Q) P Q Закони поглинання (P Q) P P (P Q) P P Співвідношення для сталих (закони тотожності та домінування) P T T (домінування) P T P (тотожності) P F P (тотожності) P F F (домінування) Наведені закони можна перевірити побудовою таблиць істинності. 1.3. Способи доведення логічних тверджень Означення 1.3.1. Еквівалентні (тотожні, рівносильні) формули – це формули, значення істинності яких збігаються в усіх інтерпретаціях. Перший спосіб перевірки еквівалентності формул – використання таблиць істинності. Ми використовували цей спосіб при розв’язуванні прикладів 1.1.4 та 1.1.5. Другий спосіб – використання законів логіки висловлювань. Алгоритм доведення: 1. Вилучити імплікації, еквівалентності та альтернативне «або» за правилами: (P Q ) P Q , (1.1) (ми довели це правило, розв’язуючи приклад 1.1.6); P Q ( P Q ) (Q P ) , (1.2) P Q P Q. (1.3) 2. Позбутись знаків заперечень над великими виразами за допомогою законів де Моргана та закону подвійного заперечення. 3. Використати решту законів для спрощення формул. Приклад 1.3.1. Довести, що формула (P Q) , (( P Q ) P ) Q є еквівалентною формулі використовуючи закони та правила логіки висловлювань. Розв’язання. Вилучаємо імплікацію: (( P Q ) P ) Q (( P Q ) P ) Q (( P Q ) P ) Q Використовуємо закони де Моргана: (( P Q ) P ) Q (( P Q ) P ) Q подвійного заперечення: (( P Q ) P ) Q дистрибутивності: (( P P ) ( Q P )) Q виключення третього: ( T ( Q P )) Q тотожності (Q P ) Q асоціативності Q P Q комутативності QQ P ідемпотентності Q P комутативності P Q правило, обернене до вилучення імплікації, тобто правило уведення імплікації: PQ . Ми довели еквівалентність вказаних в умові формул. ▲ Третім спосібом доведення логічних рівностей є комбінований спосіб, що використовує два попередні. Приклад 1.3.2. Використовуючи комбінований спосіб довести, що формула (( P Q ) ( P Q )) є тавтологією. Розв’язання. Позбудемось імплікації: (( P Q ) ( P Q )) ( ( P Q ) ( P Q )) . Складемо таблицю істинності для отриманої формули, беручи до уваги лише можливе значення змінної Р (табл. 1.9): Таблиця 1.9 P Підстановка Р та спрощення за законами логіки Результат (тотожності та домінування) T ( ( T Q ) ( T Q )) ( Q T) Т F ( ( F Q ) ( F Q )) ( F Q ) ( T Q ) Т Отже, вказана формула є тавтологією. ▲ Тавтології відіграють надзвичайно важливу роль у математичній логіці. Встановити, чи певна формула є тавтологією можна, побудувавши для неї таблицю істинності. Це надійний, але надто громіздкий спосіб, особливо, коли формула містить більше трьох змінних. Тому можна скористатись методом відшукання контрприкладу. Припускаємо, що формула не є тавтологією, тобто при якихось значеннях пропозиційних змінних вона набуває значення F. Виходячи з такого припущення пробуємо знайти такі значення. Якщо знаходимо – формула не є тавтологією, якщо приходимо до протиріччя – вона тавтологія. Приклад 1.3.3. Встановити, (( C D ) ( A D )) (( A C ) ( B D )). . чи є тавтологією формула Розв’язання. Припускаємо, що формула не є тавтологією. Оскільки остання операція, яка виконується, є імплікація, то формула є хибною, коли передумова (її ліва частина) є істинною, а висновок (права частина) хибним: (( C D ) ( A D )) T , (1.4) (( A C ) ( B D )) F . (1.5) Рівність (1.5) виконується, якщо одночасно ( A C ) F і ( B D ) F . Тому атоми одночасно набувають таких значень: A T, C F, B T, D F. Підставляємо ці значення у рівність (1.4): (( F F ) ( T F )) T F F. Ми отримали значення F, яке суперечить припущенню (1.4). Отже, задана формула не може набувати значення F ні при яких значеннях атомів, тобто є тавтологією. ▲ Приклад 1.3.4. Встановити, чи є тавтологією формула (( A C ) ( B C )) (( A B ) C ). Розв’язання. Припускаємо, що формула не є тавтологією. Оскільки остання операція, яка виконується, є імплікація, то формула є хибною, коли передумова (її ліва частина) є істинною, а висновок (права частина) хибним: (( A C ) ( B C )) T , (1.6) (( A B ) C )) F . (1.7) Рівність (1.7) виконується, якщо одночасно ( A B ) Т і C F . Припустимо, що A T, B F, підставимо їх у (1.6): (( T F ) ( F F )) F T Т . Отже, ми знайшли значення ( A T, B C F ), при яких задана формула набуває хибного значення, тобто вона не є тавтологією. ▲ 1.4. Логіка першого порядку. Предикати і квантори Логіку висловлювань застосовують до простих декларативних висловлювань, де базові висловлювання є істинними або хибними. Твердження, які містять одну чи більше змінних, можуть бути вірними при деяких значень змінних і невірними при інших. Означення 1.4.1. Предикат – це твердження, яке містить змінні та приймає значення істини чи хибності залежно від значень змінних; п-місний предикат – це предикат, що містить п змінних х1,..., хп. У випадку однієї змінної х його позначають P(x). Наприклад, вираз «х – ціле число, яке задовольняє співвідношення x=x2» є предикатом, оскільки воно істинне при x=0 чи x=1, а при будь-яких інших значеннях х невірне. Сталі називають нульмісними предикатами. Якщо зафіксувати значення всіх змінних, то предикат перетвориться на висловлювання (істинне або хибне). Означення 1.4.2. Предметні змінні – імена аргументів предиката, їх позначають малими буквами. Предикативні символи – імена, якими позначають предикати, – їх записують великими буквами. Предметна область – це область значень аргументів предиката. Приклад 1.4.1. Які з наступних тверджень істинні, а які хибні? 1) Знайдеться ціле число х, яке задовольняє співвідношення x2=2. 2) Існує просте парне число. Розв’язання 1) хибне. 2) істинне. Число 2 є і простим, і парним. ▲ Приклад 1.4.2. Нехай речення « x1 x2 4 » задано предикатом Р(х1, х2). Знайдемо пари значень змінних х1, х2, за яких предикат є істинним або хибним висловлюванням. Розв’язання. Наприклад, Р(1, 2)=F – хибне, а Р(3, 5)=T – істинне висловлювання. ▲ У прикладах 1.4.1 та 1.4.2 ми мали справу з набором об’єктів і твердженнями про те, що деяка властивість притаманна усім розглянутим об’єктам, або що знайдеться (існує) принаймні один об’єкт, що володіє даною властивістю. Означення 1.4.3. Вирази «для всіх», «існує», «існує єдиний» називають кванторами і позначають відповідно , , ! . Переважно логічні зв’язки і квантори впорядковують за пріоритетом так: , , , , , , зайві дужки інколи опускають. Включаючи в предикат квантори, ми перетворюємо його у квантифіковану формулу. Тому предикат з кванторами може бути істинним або хибним. Правила побудови формули, описані у параграфі 1.1.1, доповнюємо таким: якщо Р формула, а х – змінна у формулі, то Означення 1.4.4. Перехід від P(x) до х х P(x), х P(x) теж формули. P(x) або х P(x) називають зв’язуванням предметної змінної х, а саму змінну х – зв’язаною (заквантованою). Незв’язану змінну називають вільною. У виразах х P(x) або х P(x) предикат належить області дії відповідного квантора. Формулу, що не містить вільних змінних, називають замкненою. Наприклад, у формулі xy ( R( x , y ) x1Q ( x, x1 ) х всі P(x,у) змінна х є зв’язаною, а у – вільною. У формулі змінні зв’язані і вона замкнена, а у формулі xR( x , y ) yQ ( x, y ) х є одночасно вільною (у правій частині) й зв’язаною (у лівій) змінною. Приклад 1.4.3. Позначимо через P(x) предикат «х – ціле число і x2=16». Виразіть словами висловлювання: х P(x) і визначте його істиносне значення. Розв’язання. Висловлювання х P(x) означає, що знайдеться ціле число х, яке задовольняє рівняння x2=16. Воно істинне, бо вказане рівняння перетворюється у вірну тотожність при х=4 та х=-4. ▲ Приклад 1.4.4. Нехай P(x) – предикат «х – дійсне число і x2+1=0». Виразіть словами висловлювання: х P(x) і визначте його істиносне значення. Розв’язання. Дане висловлювання можна прочитати так: існує дійсне число х, яке задовольняє рівнянню x2+1=0. Оскільки квадрат будь-якого дійсного числа невід’ємний, тобто x2 0, ми одержуємо, що x2+1 1. Отже, твердження х P(x) хибне. ▲ Заперечення висловлювання з останнього прикладу записують так: хP(x). Це істинне висловлювання, яке означає, що не існує дійсного числа х, яке задовольняє рівнянню x2+1=0. Іншими словами, яке б не було дійсне х, x2+1 0. У символьній формі це можна записати так: х P(x). Якщо D={a1,..., aп} – скінченна предметна область змінної х у предикаті P(x), то можна скористатись логічними еквівалентностями х P(x)= P(a1 ) ... P(an ) та х P(x)= P(a1 ) ... P( an ) . (1.8) У такому разі заперечення квантифікованої формули дає той самий результат, що й застосування відповідного закону де Моргана, бо (xP( x )) ( P( a1 ) ... P( an )) P ( a1 ) ... P ( an ) , а це, своєю чергою, еквівалентне xP ( x ) . Аналогічно, (xP( x )) ( P(a1 ) ... P(an )) P (a1 ) ... P (an ) , що еквівалентно xP ( x ) . Отже, для загального предиката P(x) ми довели такі логічні еквівалентності: (xP( x )) xP ( x ) , (1.9) (x : P( x )) xP ( x ) . (1.10) Приклад 1.4.5. Допустимо, що х та у – дійсні числа, а P(x, у) – предикат «х + у=0». Виразіть словами кожне з висловлювань: х у P(x, у); у х P(x, у); і визначте їх істинність. Розв’язання. Висловлювання х у P(x, у) каже про те, що для будь-якого дійсного числа х знайдеться таке дійсне число у, що х+у=0. Воно є вірним, бо яке б число х ми не взяли, число у= -х перетворює рівність х+у=0 у вірну тотожність. Висловлювання у х P(x, у) читаємо так: існує таке дійсне число у, що для будь- якого дійсного числа х виконується рівність х+у=0. Це не є так, бо не існує дійсного числа у, яке володіє вказаною властивістю. Отже, це висловлювання хибне. ▲ 1.5. Закони логіки першого порядку Обчислення предикатів, у якому квантори можуть зв’язувати лише предметні змінні, але не можуть зв’язувати предикати, називають обчисленням першого порядку. Обчислення, у яких квантори можуть зв’язувати не лише предметні змінні, але й предикати, функціональні символи чи інші множини об’єктів, називають обчисленнями вищих порядків. Основні закони логіки першого порядку (логіки предикатів): 1. (xP( x )) xP ( x ) , xP( x ) xP ( x ) . 2. (xP( x )) xP ( x ) , xP ( x )) xP ( x ) . 3. x( P ( x ) Q ( x)) xP( x ) xQ ( x). 4. x(P(x)Q(x))= xP(x) xQ(x). 5. x(P(x)Q)=xP(x)Q. 6. x(P(x)Q)=xP(x)Q. 7. x(P(x)Q)= xP(x)Q. 8. x(P(x)Q)= xP(x)Q. 9. xyP(x,y)= yxP(x,y). 10. xyP(x,y)= yxP(x,y). 11. xP( x ) tP(t ) , 12. xP P, xP( x ) tP(t ) . xP P. Закони 1 та 2, доведення яких ми отримали в підпункті 1.4 (див. формули (1.9) та (1.10)) дозволяють будувати заперечення формул з кванторами. Наприклад, (x(P(x)Q(x,y)))= x ( P ( x ) Q ( x, y )) . Закони 3 та 4 виражають закони дистрибутивності квантора загальності відносно кон’юнкції та квантора існування відносно диз’юнкції. Для подолання обмеження дистрибутивного закону, слід використовувати заміну зв’язаної змінної: xP( x ) xQ ( x ) xP( x ) yQ ( y ) xy ( P( x ) Q ( y )) , xP( x ) xQ ( x ) xP( x ) yQ ( y ) xy ( P( x ) Q ( y )) . Закони 5-8 та 12 дозволяють виносити за межі дії квантора, що зв’язує змінну х, формулу, яка не містить х. Закони 9 та 10 свідчать про комутативність однойменних кванторів, тобто однойменні квантори можна міняти місцями, а різнойменні – ні. Закони 11 стосуються перейменування зв’язаних змінних. У загальному випадку треба перейменовувати зв’язані змінні, щоб запобігти колізії – ситуації, коли у формулі одна й та ж змінна знаходиться в області дії протилежних кванторів. Наприклад, у формулі xF(x) xQ ( x ) змінна х одночасно знаходиться в області дії кванторів і . P(t) утворена з P(x) заміною кожного вільного входження змінної х на змінну t, яка не зустрічається в P(x). P(x) може містити і зв’язані входження змінної х, тоді при утворенні P(t) вони залишаються без зміни. Наприклад, якщо P( x ) R( x ) xQ ( x, x1 ), то P( y ) R( y ) xQ ( x, x1 ), (1.11) якщо P1 ( x ) R( x , x1 ) yQ ( x, x1 , y ), то P1 ( x2 ) R( x2 , x1 ) yQ ( x2 , x1 , y ). (1.12) Ми замінили х на у у предикатах Р(х) та R(x) в (1.11), бо там вона була вільною, і залишили без змін в Q(x, x1), бо там вона була зв’язаною. Аналогічно, ми замінили х на х2 у предикатах Р(х), R(x, х1), Q(x, x1, у) в (1.12), бо у них вона була вільною. Потрібно зауважити, що у наведених формулах вказані лише зв’язані змінні і не вказані вільні змінні, які можуть набувати довільних значень із предметної області. 1.6. Випереджена нормальна форма Означення 1.6.1. Випереджена нормальна форма – формула, записана у вигляді Q1x1Q2x2...QnxnM, де кожне Qixi (i = 1,2,...,n) – це xi або xi, а формула M не містить кванторів. Вираз Q1x1...Qnxn називають префіксом, а M – матрицею формули, записаної у випередженій нормальній формі. Приклад 1.6.1. Наведемо приклади формул, записаних у випередженій нормальній формі: xy(P(x,y)Q(y)), xy(P(x)Q(y)), xyz(Q(x,y)R(z)), xyzu(P(x,z)P(y,z)Q(x,y,u)). ▲ Теорема 1.1. Для будь-якої формули існує рівносильна їй випереджена нормальна форма. Для того, щоб перевести формулу у випереджену нормальну форму, необхідно виконати такі перетворення: 1. Використати правила усунення імплікації (1.1) та еквівалентності (1.2). 2. Застосувати закон подвійного заперечення та закони де Моргана. 3. Застосувати закони 1 та 2 логіки першого ступеня. 4. Перейменувати зв’язані змінні, якщо це потрібно, за правилом: знайти найлівіше входження предметної змінної таке, що це входження зв’язане деяким квантором, але існує ще одне входження цієї змінної; зробити заміну зв’язаної змінної новою, такою, що не зустрічається у формулі. 5. Винести квантори у префікс, для чого скористатись законами 3-8 логіки першого ступеня. Зауважимо, що пункти 2 та 3 можуть мінятись місцями. Приклад 1.6.2. Зведемо формулу xP(x) уQ(y) до випередженої нормальної форми за умови, що предикати P(x) і Q(y) не містять вільних змінних. Розв’язання. Кроки для побудови випередженої нормальної форми: xP(x) уQ(y)= (xP(x))уQ(y)= вилучення імплікації (1.1), = xP ( x ) уQ(y)= застосування закону 1, =ху( P( x ) Q(y)) винесення квантора існування у префікс за законами 4 та 8. ▲ Приклад 1.6.3. Зведемо формулу xy(z(P(x,z)P(y,z)) uQ(x,y,u)) до випередженої нормальної форми. Розв’язання. Кроки для побудови випередженої нормальної форми: xy(z(P(x,z)P(y,z)) uQ(x,y,u))= xy((z(P(x,z)P(y,z)))uQ(x,y,u)) = вилучення імплікації (1.1), = xy(z( P (x,z) P (y,z))uQ(x,y,u))= застосування закону 1 та закону де Моргана, =xyzu( P (x,z) P (y,z)Q(x,y,u)), використання законів 6, 7 логіки першого ступеня та винесення квантора існування у префікс. ▲ Приклад 1.6.4. Знайдемо випереджені нормальні форми для таких формул: а) xyA( x, y ) (xyB( x, y )) , б) (x( A( x ) y( B( y ) C ( z )))) (y ( D( x, y ) E ( z ))) . Розв’язання. а) xyA( x, y ) (xyB ( x, y )) xyA( x, y ) x(yB( x , y )) = xyA( x, y ) xyB ( x, y )) x (yA( x, y ) yB ( x , y )) перейменовуємо змінну у на z x(zA( x , z ) yB ( x , y )) xzy ( A( x , z ) B ( x, y )) . б) (x( A( x ) y( B( y ) C ( z )))) (y ( D( x, y ) E ( z ))) = (x ( A( x ) y ( B( y ) C ( z )))) (y ( D ( x , y ) E ( z ))) (x ( A( x ) y ( B( y ) C ( z )))) y ( D ( x, y ) E ( z )) (x ( A( x ) y ( B( y ) C ( z )))) y ( D ( x, y ) E ( z )) перейменовуємо змінну х на w (w( A( w) y ( B( y ) C ( z )))) y ( D ( x, y ) E ( z )) перейменовуємо змінну y на v (w( A( w) v ( B(v ) C ( z )))) y ( D( x, y ) E ( z )) виносимо v (wv ( A( w) B(v ) C ( z ))) y ( D ( x, y ) E ( z )) виносимо y wvy ( A( w) B ( v ) C ( z ) ( D ( x, y ) E ( z )) .▲ 1.7. Методи доведень Для доведення теорем застосовують логічну аргументацію. Доведення в інформатиці – невід’ємна частина перевірки коректності алгоритмів. Необхідність доведення виникає, коли нам потрібно встановити істинність висловлювання виду (P Q ). Існує декілька стандартних типів доведень. 1. Пряме міркування. Допускаємо, що висловлювання Р істинне і показуємо справедливість Q. Такий спосіб доведення виключає ситуацію, коли Р істинне, а Q хибне, оскільки саме в цьому і лише в цьому випадку імплікація P Q набуває хибного значення (див. табл. 1.1). 2. Обернене міркування. Допускаємо, що висловлювання Q хибне і показуємо помилковість Р. Фактично прямим способом перевіряємо істинність імплікації ( Q P), що згідно з прикладом 1.1.5 (правилом контрапозиції) логічно еквівалентне істинності вихідного твердження (P Q ). 3. Метод «від протилежного». У допущенні, що висловлювання Р істинне, а Q хибне, використовуючи аргументоване міркування, одержимо протиріччя. Цей спосіб оснований на тому, що імплікація (P Q) набуває хибного значення лише тоді, коли Р істинне, а Q хибне. Приклад 1.7.1. Покажіть прямим міркуванням, що добуток ху двох непарних цілих чисел х та у завжди непарне число. Розв’язання. Перш за все зауважимо, що будь-яке непарне число, і зокрема х, можна записати у вигляді x 2 m 1 , де т – ціле число. Аналогічно, y 2 n 1 , де п – ціле число. Отже, добуток xy ( 2 m 1)( 2 n 1) 4 mn 2 m 2 n 1 2 ( 2 mn m n ) 1 теж є непарним числом. ▲ Приклад 1.7.2. Покажіть оберненим міркуванням: якщо для натурального числа п п2 є непарним числом, то і п є непарним. Розв’язання. Запереченням висловлювання про непарність числа п2 є твердження «п2 парне», а висловлювання про парність п є запереченням твердження «число п непарне». Отже, нам треба показати прямим міркуванням, що з парності числа п випливає парність його квадрата п2. Оскільки п парне, то п=2т для якогось числа т. Тому п2=4т2=2(2т2) – парне число. ▲ Приклад 1.7.3. Покажіть методом «від протилежного», що розв’язок рівняння х2=2 є ірраціональним числом, тобто не може бути записаний у вигляді дробу з цілими чисельником і знаменником. Розв’язання. Тут нам треба допустити, що розв’язок х рівняння х2=2 є раціональним числом, тобто записується у вигляді дробу x m n з цілими т і п, причому n 0 . Допустивши це, нам необхідно отримати протиріччя або з цим допущенням, або з якимось раніше доведеним фактом. Як відомо, раціональне число неоднозначно записується у вигляді дробу. Наприклад, x m 2 m 3m n 2n 3n і т.д. Однак можна вважати, що т і п не мають спільних дільників, тоді неоднозначність запису зникає. Отже, допускаємо додатково, що що дріб x m n нескоротний (т і п не мають спільних дільників). За умовою число х задовольняє рівняння х2=2. Отже, 2 m 2, n звідки т2=2п2. З останньої рівності випливає, що число т2 парне, отже, т теж парне (див. приклад 1.7.2) і може бути зображене як т=2р для якогось цілого числа р. Підставивши останній вираз у рівність т2=2п2, ми одержимо, що 4р2=2п2, тобто п2=2р2. Але тоді п теж є парним числом. Ми показали, що і т, і п – парні числа. Тому вони мають спільний дільник 2. Якщо тепер згадати, що ми допускали відсутність спільного дільника у чисельника і знаменника дробу m n , то побачимо явне протиріччя. Знайдене протиріччя дозволяє зробити однозначний висновок: розв’язок рівняння х2=2 не може бути раціональним числом, тобто він ірраціональний. ▲ Отже, при доведенні прямим міркуванням твердження вигляду (P Q ) з допущення про істинність Р виводять істинність Q. Обернене міркування в доведенні грунтується на логічній еквівалентності висловлювань ( Q P) і (P Q). Метод доведення імплікації (P Q), при якому з допущення про хибність Q та істинність Р приходять до протиріччя, називають методом «від протилежного». 1.8. Математична індукція Математична індукція корисна при доведенні висловлювання, істинного для всіх натуральних чисел. Продемонструємо переваги цього методу, довівши коректність рекурсивного алгоритму, який визначає максимальний елемент з набору а1, а2, ..., ап натуральних чисел. { int i=0; int M=0; while (i<n) { i=i+1; M=max(M,a[i]); } } Прослідкуємо дію алгоритму на наборі даних а1=4, а2=7, а3=3, а4=8 (табл. 1.10), за потреби функції max та min можна підключити з бібліотеки. Таблиця 1.10 i M i<n 0 0 так 1 4 так 2 7 так 3 7 так 4 8 ні Як вихідні дані ми отримали М=8, що безумовно правильно. Зауважимо, що після кожного проходу циклу змінна М рівна найбільшому з чисел набору, проглянутих до цього моменту. Але чи буде алгоритм працювати правильно для будь-якого введеного набору чисел довжиною п? Розглянемо введений набір а1, а2, ..., ап довжини п і позначимо через Мк значення змінної М після к-го проходу цикла. 1. Якщо ми вводимо набір а1 довжиною 1, то цикл зробить лише один прохід і М присвоїться найбільше значення з 0 і а1, яким буде а1. Вивід буде правильним. 2. Якщо після к-го проходу цикла Мk – найбільший елемент з набору а1, а2, ..., ак, то після наступного проходу Мk+1 буде рівне max(Mk,ak+1), тобто максимальному елементу набору а1, а2, ..., аk, аk+1. В пункті 1 ми показали, що алгоритм працює правильно на будь-якому введеному наборі довжини 1. Тому згідно пункту 2 він буде правильно працювати і на будь-якому введеному наборі довжини 2. Знову застосовуючи пункт 2 міркувань, ми переконуємось, що алгоритм працює правильно і на будь-яких наборах довжини 3 і т.д. Отже, він правильно працює на будь-яких наборах довжини п, тобто він коректний. На формальній мові використаний метод доведення виглядає так. Принцип математичної індукції – це така теорема: Теорема 1.2. Нехай Р(п) – предикат, визначений для всіх натуральних п. Допустимо, що 1) Р(1) істинне і 2) k 1 імплікація (P(k) P(k+1)) є вірною. Тоді Р(п) істинне при будь-якому натуральному п. Приклад 1.8.1. Доведіть, використовуючи індукцію, що рівність 1 2 ... n n ( n 1) 2 виконана при всіх натуральних п. Розв’язання. Нехай Р(п) – предикат 1 2 ... n n ( n 1) . 2 У випадку п=1 ліва частина рівності – це 1, а обчислюючи праву частину, одержимо 1(1 1) 1. 2 Отже, Р(1) істинне. Допустимо тепер, що рівність 1 2 ... k k ( k 1) 2 має місце для якогось натурального числа k. Тоді 1 2 ... k ( k 1) Отже, для будь-якого k ( k 1) 1 k 1 ( k 1) k 2 . 2 2 натурального k імплікація P ( k ) P ( k 1) справедлива. Тому згідно принципу математичної індукції предикат Р(п) має істинне значення для всіх натуральних п. ▲ Задача 1.1. Доведіть за індукцією коректність алгоритму Квадрат: // n – натуральне число { sq=0; for(int i=1; i<=n; i++) sq=sq+2*i-1; } // sq=n2 Розв’язання. Нехай Р(п) – предикат «sq=n2 після п-го проходу циклу», а sqk – значення змінної sq після k-го проходу циклу. Покажемо, що 1) sq1=12; 2) якщо sqk=k2, то sqk+1=(k+1)2. Очевидно, що після першого проходу циклу sq1=1 і перший пункт виконано. Допустимо, що після k-го проходу циклу sqk=k2. Тоді після наступного проходу sqk+1= sqk +2(k+1)-1=k2+2k+1=(k+1)2. Отже, другий пункт теж має місце, тобто для будь-якого натурального k імплікація P ( k ) P ( k 1) справедлива. Тому згідно принципу математичної індукції предикат Р(п) має істинне значення для всіх натуральних п. ▲ У цій задачі цикл for обмежений визначеним числом ітерацій (проходів). У тому випадку, коли число ітерацій циклу наперед невизначене, як в циклі while, при доведенні індукцією треба допустити, що число проходів все ж таки обмежене і показати правильність вихідних даних. Після цього необхідно перевірити, що число ітерацій такого циклу дійсно скінченне. Контрольні запитання до теми 1 1. Що називають простим і складним висловлюваннями? Наведіть приклади простих та складних висловлювань. 2. За допомогою яких логічних операцій будують складні висловлювання? 3. Які є правила побудови формул з простих висловлювань? 4. Яка формула є тавтологією? 5. Яка формула є протиріччям? 6. Які є закони логіки висловлювань? 7. Якими способами перевіряють еквівалентність тверджень? 8. Назвіть головну ідею метода відшукання контприкладу. 9. Що називають предикатом і кванторами? Наведіть приклади предикатів і кванторів. 10. Які є правила побудови формул з використанням змінних? 11. Які змінні називають зв’язаними, а які вільними? Наведіть приклади формул з такими змінними. 12. Які закони логіки першого ступеня ви знаєте? 13. Яку формулу називають випередженою нормальною формою? 14. Перелічіть кроки, за допомогою яких переводять формулу у випереджену нормальну форму. 15. Які методи доведень ви знаєте? 16. У чому полягає принцип математичної індукції? 17. Доведіть коректність алгоритму Квадрат. 2.1. Множини Теорія множин – один з наріжних каменів математики, який забезпечує зручну мову для опису багатьох концепцій як в математиці, так і в інформатиці. У цьому розділі ми введемо поняття множини і опишемо способи комбінування множин для отримання нових. Результат операцій об’єднання, перетину, різниці, доповнення і симетричної різниці проілюструємо на діаграмах Ейлера-Венна. Аналогії, які ми побачимо між операціями над множинами і логічними операціями з попереднього розділу, дозволять нам сформулювати визначений набір тотожностей та закони алгебри множин на їх основі. Останні в свою чергу використаємо для виведення складніших співвідношень. Засвоїмо принцип включення і виключення, зімітуємо операції над множинами за допомогою рядків бітів. Значну увагу приділимо поданню множин в програмах, що важливо для програмістів-практиків. Означення 2.1.1. Множина – це сукупність об’єктів, які називають елементами. Наприклад, S={2, 3, 5, 7, 11}; {сир, яйце, молоко, сметана}. Тут елементи кожної множини знаходяться у фігурних дужках, причому порядок, в якому записані елементи множини, значення не має. Щоб забезпечити можливість посилань, ми переважно будемо позначати множини великими латинськими буквами. У загальному випадку запис a S означає, що об’єкт а – елемент множини S, тобто а належить множині S. Якщо а не належить множині S, то пишуть a S . Означення 2.1.2. Множину називають скінченною, якщо вона складається зі скінченного числа елементів (тобто існує таке натуральне число, яке є кількістю її елементів). У протилежному випадку множину називають нескінченною. Порожня множина – це множина, що не містить жодного елемента. Ми не можемо виписати всі елементи дуже великих, особливо нескінченних, множин. У цьому випадку множини визначають за допомогою предикатів. Формально ми описуємо множину, складену з елементів х, для яких предикат P(x) має істинне значення, так S={x: P(x)}. Наприклад, запис S={x: x – непарне натуральне число} описує множину S={1, 3, 5, 7, ...}. Оскільки будь-яке натуральне непарне число може бути записане як 2п-1, де п – будь-яке натуральне число, альтернативне допустиме визначення тієї ж множини задається формулою: S={2п-1: п – будь-яке натуральне число}. Приклад 2.1.1. Знайдіть більш простий опис множин, який перераховує їх елементи: 1) А={x: x – ціле і х2+4х=12}; 2) B={x: x – назва дня тижня, яка не містить букви «е»}; 3) С={п2: п – ціле}. Розв’язання. 1) Знайшовши корені квадратного рівняння х2+4х-12=0, одержимо х1=2, х2=-6. Тому, А={-6, 2}. 2) В={вівторок, п’ятниця, субота} 3) С={0, 1, 4, 9, 16,...}. Деякі множини чисел так часто використовують, що їм дали стандартні назви і позначення: – порожня множина; N {1, 2,3,...} – множина натуральних чисел; часом до неї включають і 0; Z {0 , 1, 2 , 3,...} Q { – множина цілих чисел; p : p , q Z , q 0} q – множина раціональних чисел; ={всі десяткові дроби} – множина дійсних чисел. Сучасні мови програмування вимагають, щоб змінні оголошувались як такі, що належать до визначеного типу даних. Тип даних є множиною об’єктів зі списком стандартних операцій над ними. Визначення типу змінних рівносильне вказанню множини, з якої змінним присвоюють значення. Існує декілька способів конструювання нової множини з двох заданих. Опишемо ці операції над множинами. Перш за все відзначимо, що у прикладі 2.1.1 всі елементи деяких множин належали іншим більшим множинам. Наприклад, всі елементи множини С={0, 1, 4, 9, 16,...} містяться в множині Z {0 , 1, 2 , 3,...} . Означення 2.1.3. Кажуть, що множина А є підмножиною множини S (цей факт позначають A S , де – знак нестрогого включення), якщо кожен її елемент автоматично є елементом множини S. Досить часто при цьому кажуть, що множина А міститься в множині S. Якщо A S і S A , то A називають власною (строгою, істинною) підмножиною S (позначають A S , де – знак строгого включення). Означення 2.1.4. Дві множини А та S називаються рівними, якщо вони складаються з однакових елементів. У цьому випадку пишуть А=S. Множини A і S рівні (A=S), якщо A S і S A . Приклад 2.1.2. Наведемо приклади рівних множин: 1,2,3 3,1,2; 1,2,4 20 ,21 ,2 2 .▲ Означення 2.1.5. Множину, усі можливі підмножини якої доводиться розглядати під час вивчення якогось питання, називають універсальною (універсумом) та позначають літерою U (зауважимо, що універсальна множина існує не у всіх випадках). Множини як об’єкти можуть бути елементами інших множин. Множину, елементами якої є множини, інколи називають сімейством. Отже, універсальна множина – це множина усіх розглядуваних у цій задачі елементів, тобто універсумом U арифметики є множина дійсних чисел, універсумом U соціології – множина людей. Означення 2.1.6. Множину, елементами якої є всі підмножини множини А і тільки вони (включно з порожньою множиною та самою множиною А), називають булеаном або множиною-степенем множини А і позначають P(A) . Означення 2.1.7. Потужністю скінченної множини А називають число її елементів, позначають |А|. У випадку скінченної підмножини A , що складається з п елементів, булеан P(A) n містить 2 елементів: A n P ( A) 2 n . Очевидно, що число елементів булеана P(A) залежить від числа елементів множини A. Наприклад, якщо A 3 , то маємо P ( A) 2 3 8. Приклад 2.1.3. Запишемо булеан множини A {a, b} . Розв’язання. Булеаном даної множини є P ( A) { , {a},{b},{a, b}}. Перша й остання підмножини невласні, інші – власні. ▲ 2.2. Способи задання множин Спосіб 1. Найбільш природним способом є задання множини переліком (або списком) елементів. Наприклад: A 1,2,3,4,5 . Нагадаємо, що порядок елементів у записі множини значення не має: A 1,2,3,4,5 3,5,2,1,4. Вважають, що всі елементи множини різні. Цей спосіб задання застосовується лише для скінчених множин з невеликим числом елементів. Іноді множини задають переліком частини множини, з якого можна зрозуміти, чим є вся множина. Приклади стислого задання множин: A 0,1,...,9 ; A 3,5,...,2n 1,... ; A 3, 5, 9,..., 2n 1,... . Спосіб 2. Універсальним є задання множини за допомогою характерних властивостей її елементів (тобто властивостей, які мають всі елементи даної множини і лише вони). Наприклад: A x | x N , x 16 ; A x | x Z , 10 x 19 ; x A x | Z . 2 Спосіб 3. Аналітичний, за допомогою символів операцій над множинами та дужок. Наприклад, C A B . Спосіб 4. Вербальний (мовний) за допомогою опису характерних властивостей, які повинні мати елементи множини. Наприклад, множина А – це множина, елементами якої є всі назви днів тижня. Спосіб 5. Множини зручно задавати графічно за допомогою діаграм ЕйлераВенна. Діаграми Ейлера-Венна є геометричним зображенням множин. Межу множини зображують замкненою кривою довільної форми (найчастіше – колом). Точки, які лежать всередині замкненої кривої, можна розглядати як елементи відповідної множини (рис. 2.1). Рис. 2.1. Діаграма Ейлера-Венна підмножин A S та B A Універсум U на діаграмах Ейлера-Венна зображують у вигляді прямокутника (рис.2.2): а) б) Рис. 2.2. Діаграми Ейлера-Венна множин А (а) та {a, b, c}, {b, d, e} (б) в універсальних множинах U 2.3. Операції над множинами Розділ дискретної математики, в якому досліджують операції над множинами, називають алгеброю множин (подібно до того, як шкільна алгебра досліджує операції у множини чисел). Означення 2.3.1. Об’єднанням двох множин А і В називають множину A B { x : ( x A) ( x B )} . (2.1) Вона складається з тих елементів, які належать або множині А, або множині В, а можливо і обом відразу. Діаграма Ейлера-Венна об’єднання показана на рис. 2.3, а. Означення 2.3.2. Перетином (перерізом) двох множин А і В називають множину A B { x : ( x A) ( x B )} . (2.2) Вона складається з тих елементів, які належать множині А і множині В. Діаграма Ейлера-Венна перетину показана на рис. 2.4, б. а) б) Рис. 2.3. Діаграми Ейлера-Венна об’єднання та перетину двох множин Операції об’єднання та перетину узагальнюють на довільну кількість множин і використовують позначення: N N Ai A1 A2 ... AN . , Ai A1 A2 ... AN . i 1 i 1 Означення 2.3.3. Різницею множин А та В називають множину A \ B {x : ( x A) ( x B )} . (2.3) Вона складається з усіх елементів множини А, які не належать множині В. Діаграма Ейлера-Венна різниці показана на рис. 2.4, а. Означення 2.3.4. Симетричною різницею множин А та В називають множину A B { x : (( x A ) ( x B )) (( x B ) ( x A ))} . (2.4) Вона складається з усіх тих і тільки тих елементів універсальної множини, які належать множині А і не належать В, або навпаки, належать множині В і не належать А. Симетрична різниця складається з елементів, що належать або А, або В, але не обом множинам одночасно. Діаграма Ейлера-Венна симетричної різниці показана на рис. 2.4, б. а) б) Рис. 2.4. Діаграма Ейлера-Венна різниці та симетричної різниці двох множин В означенні різниці не розглядають випадок B A . Якщо B A , то різницю A \ B називають доповненням множини В до множини А і позначають BA . Для підмножини А універсальної множини U можна розглядати доповнення А до U, тобто U \ A . Означення 2.3.5. Множину U \ A позначають A { x : ( x A )} A { x : x A )} називають доповненням множини А. Діаграма Ейлера-Венна доповнення показана на рис. 2.5. Рис. 2.5. Діаграма Ейлера-Венна доповнення множини Теорема 2.1. A \ B A B. Доведення. A \ B {x | ( x A) ( x B )} {x | ( x A) ( x B )} , тоді A \ B A B. ▲ Теорема 2.2. AB ( A B) ( B A). (2.6) Доведення. AB ( A \ B) ( B \ A) ( A B) ( B A), використовуючи (2.5). ▲ Приклад 2.3.1. Нехай A={1, 3, 5, 7}; B={2, 4, 6, 8}; C={1, 2, 3, 4, 5}. Знайдіть A C , B C , A \ C , B C . Розв’язання. A C {1, 3 , 5 , 7 , 2 , 4 } ; B C { 2 , 4 }; A \ C { 7 }; B C ( B \ C ) ( C \ B ) { 6 ,8 } {1, 3 , 5} { 6 , 8 ,1, 3 , 5}. ▲ Приклад 2.3.2. Нехай A { x : 1 x 12 B { x : 1 x 12 Переконайтесь, що х – парне ціле число}, х – ціле число, кратне 3}. ( A B ) A B. Розв’язання. Перш за все зауважимо, що універсальною множиною тут є U={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}. Крім того, А={2, 4, 6, 8, 10, 12} і В={3, 6, 9, 12}. Тому ( A B ) {6 ,12 } {1, 2 ,3, 4 ,5 , 7 ,8,9 ,10 ,11} і A B {1, 3, 5, 7, 9, 11} {1, 2, 4, 5, 7, 8, 10, 11}={1, 2, 3, 4, 5, 7, 8, 9, 10, 11}. Отже, ( A B ) A B. ▲ Означення 2.3.6. Множини А і В називають диз’юнктними, якщо вони не перетинаються: А В . Об’єднання двох диз’юнктних множин А і В називають диз’юнктним об’єднанням і позначають: Твердження 2.1. Якщо А В С як додавання і віднімання чисел. А В . , то А=С\В, тобто операції « » і «\» поводяться 2.4. Алгебра множин. Закони теорії множин З операцій, про які йшлося в попередньому підрозділі, можна вивести багато властивостей множин, грунтуючись на відповідності між операціями над множинами і логічними операціями над предикатами (табл. 2.1). Таблиця 2.1 Операції над множинами Логічні операції Приклад 2.4.1. Доведемо, що для будь-яких множин А і В справедливе співвідношення ( A B ) A B. Розв’язання. ( A B ) { x : x ( A B )} { x : ( x ( A B ))} { x : (( x A ) ( x B ))}; A B { x : ( x A ) ( x B )} { x : ( ( x A )) ( ( x B ))}. Порівнюючи таблиці істинності, легко встановити логічну еквівалентність складних предикатів: (P Q ) та де Р і Q – прості висловлювання. ( P ) ( Q ) , Спираючись тепер на відповідність між логічними операціями і операціями над множинами (див. табл. 1.8 теми 1), бачимо, що предикати Р= ( x A) і Q= ( x B ) ) відповідають множинам ( A B) та (P Q ) і ( P ) ( Q ) (де A B.▲ Властивість, яку ми тільки що довели, відома як один з законів де Моргана. Фундаментальні властивості, аналогічні законам де Моргана, складають закони алгебри множин (табл. 2.2). Кожен з них може бути доведений за допомогою логічних аргументів, аналогічних тим, які використані в прикладі 2.4.1. Вивчення законів алгебри множин дозволяє зауважити, що кожна з тотожностей правої колонки може бути одержана з відповідної тотожності лівої шляхом заміни на , на U і навпаки. Таку відповідність тотожностей називають законом двоїстості, а відповідні тотожності – двоїстими одна одній. Використовуючи цей закон, можна обгрунтувати двоїсту тотожність, довівши пряму і обернувши операції. Таблиця 2.2 Закони алгебри множин Закони асоціативності A (B C ) (A B) C A (B C ) (A B) C Закони комутативності A B B A A B B A Закони тотожності A A A U A Закони домінування A U U A Закони ідемпотентності A A A A A A Закони дистрибутивності A (B C ) (A B) ( A C ) A (B C ) (A B) (A C ) Закони поглинання ( A B) A A ( A B) A A Закони доповнення A A U A A U U A A A A Закони де Моргана ( A B) A B ( A B) A B Приклад 2.4.2. Спираючись на закони алгебри множин, доведемо, що довільні множини А і В задовольняють властивості AB ( A B ) ( A B ) . Розв’язання. Застосовуючи закони алгебри множин до правої частини рівності, маємо: ( A B) ( A B) (закон де Моргана) ( A B) ( A B) (закон дистрибутивності) (( A B ) A ) (( A B ) B ) (закон дистрибутивності) (( A A ) ( B A )) (( A B ) ( B B )) (закон доповнення) ( ( B A )) (( A B ) ) (закон тотожності) (B A ) ( A B) (закон комутативності) ( A B ) ( B A) . Використовуючи теорему 2.2 (2.6), маємо AB ( A B ) ( A B ) , що і треба було довести. ▲ Використовуючи введені операції можна виражати одні множини через інші. Існує такий пріоритет операцій: ,,,\, . Для зміни цього порядку у виразі використовують дужки. Отже, множину можна задати виразом, в який входять множини, операції і, за потреби, дужки. Такий спосіб задання множини називають аналітичним. Твердження 2.2. Симетрична різниця має такі властивості: 1) AB BA 2) ( A B )С А ( B С ) 3) AА 4) A А ; 5) AU A . ; (комутативність); (асоціативність); 2.5. Доведення рівностей множин Доводити рівності множин можна різними способами. Спосіб 1. Для доведення рівності використовується теорема про те, що дві множини А та В рівні тоді й лише тоді, коли A B та B A . Приклад 2.5.1. Доведемо рівність множин, яка є формулюванням закону де Моргана A B A B . Розв’язання. Припустимо, що x A B , тоді x A B , звідси x A і x B . Тому x A або x B , а це означає, що x A B . Отже, доведено, що A B A B . Навпаки, нехай x A B , тоді x A або x B , звідки x A і x B . Це означає, що x A B , тобто x A B . Отже, A B A B . Cпосіб 2. Доведення рівності множин із використанням таблиць належності. У цих таблицях розглядають усі можливі комбінації належності елементів множинам і позначають 1, якщо елемент належить множині, 0 – якщо елемент їй не належить. Приклад 2.5.2. Доведемо цим способом рівність A B A B . Розв’язання. Доведення подано у табл. 2.3. Таблиця 2.3 А В AB A B A B A B 0 0 0 1 1 1 1 0 1 0 1 1 0 1 1 0 0 1 0 1 1 1 1 1 0 0 0 0 Стовпчики, які в табл. 2.3 відповідають множинам A B та A B , збіглися, отже A B A B . Спосіб 3. Доведення рівності множин з використанням означень операцій над множинами. Приклад 2.5.3. Доведемо попередню рівність A B A B . Розв’язання. Частково розглянуто у прикладі 2.4.1. Доведення полягає в послідовній перевірці наступних рівностей A B x : ( x A B) x : (( x A) ( x B )) x : ( x A) ( x B ) x : ( x A) ( x B ) x : x A B A B . Спосіб 4. Доведення рівності множин із використанням законів алгебри множин (табл. 2.2) розглянуто у прикладі 2.4.2. 2.6. Формули включень і виключень для двох і трьох множин У восьмому розділі ми будемо вивчати комбінаторику, область математики, яка має справу з підрахунком кількості елементів у тих чи інших множинах. Такі питання є особливо важливими у випадку обмеженості ресурсів. Наприклад, скільки користувачів може підтримувати дана комп’ютерна мережа? Або скільки операцій буде виконано при роботі даного алгоритму? За наведеними нижче теоремами виведено прості правила обчислення потужності об’єднання двох і трьох множин. Теорема 2.3. Формула включень і виключень для двох множин: | A B | | A | | B | | A B | . Доведення. Як видно з рис. 2.6, множина A B складається з трьох підмножин: A\B, A B і B \ A , які не мають спільних елементів. Більше того, B (B \ A) ( A B ) . A (A \ B) (A B) і Уведемо позначення: m | A \ B | , n | A B | , p | B \ A | . Тоді | A | m n , | B | n p , | A B | m n p ( m n ) ( n p ) n | A | | B | | A B | . ▲ Рис. 2.6. Діаграма об’єднання двох множин Приклад 2.6.1. Кожен зі 63 студентів першого курсу, які вивчають англійську мову в університеті, може відвідувати і додаткові лекції. Якщо 16 з них слухають ще курс французької мови, 37 – німецької, а 5 вивчають обидві ці дисципліни, то скільки студентів взагалі не відвідують додаткові заняття? Розв’язання. Уведемо позначення: А={студенти, які слухають курс французької мови}; В={студенти, які слухають курс німецької мови}. Тоді | A | 16 , | B | 37 , | A B | 5 . Тому | A B | 16 37 5 48 . Отже, 63-48=15 студентів не відвідують додаткових занять. ▲ Теорема 2.4. Формула включень і виключень для трьох множин: A B C A B C A B B C A C A B C. Доведення Діаграма Ейлера-Венна зображена на рис. 2.7. Позначимо різні області мітками 1, 2,..., 8, як показано на рис. 2.7, і допустимо, що область і містить пі елементів. Тоді | A | | B | | C | ( n1 n2 n4 n5 ) ( n1 n2 n3 n6 ) ( n1 n3 n4 n7 ) 3n1 2n2 2n3 2n4 n5 n6 n7 . З іншого боку, | A B | | B C | | A C | ( n1 n2 ) ( n1 n3 ) ( n1 n4 ) 3n1 n2 n3 n4 . Крім того, | A B C | n1. Отже, | A | | B | | C | | A B | | B C | | A C | | A B C | 3n1 2n2 2n3 2n4 n5 n6 n7 3n1 n2 n3 n4 n1 n1 n2 n3 n4 n5 n6 n7 | A B C |, що і треба було довести. ▲ Рис. 2.7. Діаграма об’єднання трьох множин Використовуючи метод математичної індукції, принцин включення-виключення можна узагальнити на довільне скінченне число множин. Ми доведемо його у восьмій темі. 2.7. Комп’ютерне подання множин Термін «подання» щодо програмування означає таке. Подати в програмі якийсь об’єкт (у даному випадку множину) – це описати в термінах системи програмування структуру даних, яку використовують для зберігання інформації про поданий об’єкт, і алгоритми над вибраними структурами даних, що реалізують притаманні даному об’єкту операції. Отже, стосовно до множин визначення подання підрозуміває опис способу зберігання інформації про належність елементів множині і опис алгоритмів для обчислення об’єднання, перетину та інших уведених операцій. Варто підкреслити, що, як правило, один і той же об’єкт може бути поданий багатьма різними способами, причому не можна вказати спосіб, який є найкращим для всіх можливих випадків. Вибір подання залежить від низки факторів: особливостей об’єкта, складу і відносної частоти використання операцій в конкретній задачі і т.п. Вміння вибрати найкраще для конкретного випадку подання є основою мистецтва практичного програмування. Хороший програміст відрізняється тим, що він знає багато різних способів подання і вміло вибирає той, що найбільш підходить. Подання множин бітовими рядками Одним із найпоширеніших та найпростіших способів є подання множин за допомогою бітових рядків. Нехай універсальна множина U містить п елементів. Упорядкуємо довільним способом елементи універсальної множини. Тоді U a1 , a2 , a3 ,...an1 , an . Множину A U зображають у комп’ютері рядком із 0 та 1 довжини п так: якщо ai A , то і-й біт дорівнює 1, якщо ai A , то і-й біт дорівнює 0. Цю послідовність нулів і одиниць довжиною п називають рядком бітів або бітовим рядком довжиною п. ▲ Покажемо, як рядок бітів застосовують для моделювання операцій на скінченних множинах. Означення 2.7.1. Нехай S={s1, s2, …, sn}. Якщо множина A S , ми поставимо їй у відповідність п-бітний рядок (b1, b2, …, bn), де bі=1, якщо si A , і bі=0 в протилежному випадку. Такий рядок бітів називають характеристичним вектором підмножини А. Приклад Нехай 2.7.1. U a, b, c, d , e, f , m, n, p, q, r , s , A b, m, n, q, r , B a, b, f , m, q . Зобразимо множини А та В бітовими рядками. Розв’язання. Множину A зобразимо рядком а=(010000110110), а множину В – рядком b=(110001100100). Тепер ми можемо імітувати операції над множинами логічними операціями, які застосовують до відповідних характеристичних векторів, домовившись вважати 1 за Т, а 0 за F. Наприклад, перетин множин – це порозрядна кон’юнкція над бітовими рядками, а об’єднання множин – порозрядна диз’юнкція над бітовими рядками. Операції над множинами та відповідні їм логічні операції наведені в табл. 2.4. Таблиця 2.4 Приклад А В A B A B, B, AB , A\ B, аi bi ai bi ai bi bi ai bi a i bi 0 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 0 1 1 1 1 1 1 1 1 0 0 0 2.7.2. Нехай U a, b, c, d , e, f , m, n, p, q, r , s , A b, m, n, q, r , B a, b, f , m, q . Знайдемо комп’ютерне зображення перетину A B та об’єднання A B множин А та В. Розв’язання. Для знаходження перетину та об’єднання множин виконаємо порозрядну кон’юнкцію та диз’юнкцію відповідних рядків, які зображають множини А та В: a= (010000110110), b= (110001100100), ab (010000110110) (110001100100)=(010000100100), ab (010000110110) (110001100100)=(110001110110). Повертаючись до звичайного зображення множин, маємо A B ={b, m, q}, A B ={a, b, f, m, n, q, r}. Приклад 2.7.3. Нехай S={1, 2, 3, 4, 5}, А={1, 3, 5} і В={3, 4}. Випишемо характеристичні вектори А і В, а потім визначимо характеристичні вектори підмножин A B, A B , B , A \ B та AB множин А та В. Розв’язання. Як легко бачити, характеристичні вектори підмножин А і В мають вигляд: а=(10101), b=(00110). Тому a b (10101) (00110)=(10111); a b (10101) (00110)=(00100); b= (00110)=(11001). Оскільки A\ B A B , то її характеристичним вектором буде a b (10101) (11001) (10001) . Характеристичний вектор симетричної різниці знаходимо, додаючи за модулем 2 вхідні вектори, тому ab (10101) (00110)=(10011). Одержані вектори дозволяють нам швидко відновити елементи підмножин A B ={1, 3, 4, 5}, A B ={3}, B ={1, 2, 5}, A \ B {1, 5}, AB =={1, 4, 5}. ▲ Контрольні запитання до теми 2 1. Що називають булеаном множини А? 2. Коли підмножина є власною підмножиною множини? 3. Опишіть способи задання множин. 4. Які операції над множинами ви знаєте? 5. Назвіть закони алгебри множин. 6. Що називають законом двоїстості і як його використовують? 7. Опишіть способи доведення рівностей множин. 8. Сформулюйте і доведіть формулу включень і виключень для двох множин. 9. Сформулюйте і доведіть формулу включень і виключень для трьох множин. 10. Яким є найпоширеніший і найпростіший спосіб комп’ютерного подання множин? 11. Що називають характеристичним вектором підмножини універсальної множини? 12. Наведіть відповідність між операціями над множинами і логічними операціями. 3.1 Термінологія. Операції над графами Графи виникли у 18-му столітті, коли відомий швейцарський математик Леонард Ейлер спробував розв’язати тепер вже класичну задачу про Кенігбергські мости. В той час в місті Кенігсберзі було два острови, з’єднані 7-ма мостами з берегами річки Преголі і один з одним, як показано на рис. 3.1. Рис. 3.1. Схема старого Кенігсберга Задачу сформулював Іммануїл Кант: здійснити прогулянку містом так, щоб, пройшовши лише раз по одному мосту, повернутись в те місце, звідки починалась прогулянка. Розв’язуючи цю задачу, Ейлер зобразив Кенігсберг у вигляді графа, ототожнивши його вершини з частинами міста, а ребра з мостами, які зв’язували ці частини. Як ми покажемо нижче, йому вдалося довести, що шуканого маршруту в місті не існує. У цій темі ми введемо стандартну термінологію, яку використовують в теорії графів, і розглянемо алгоритми обходу графів та декілька конкретних задач, які розв’язують за допомогою графів. Перед розв’язуванням задачі, поставленої Ейлеру, розглянемо термінологію, яку застосовують в теорії графів. Графом називають сукупність двох множин – непорожньої множини V (множини вершин) і множини Е двоелементних підмножин множини V (Е – множина ребер). Ребро можна трактувати як неупорядковану пару вершин. Часто розглядають такі споріднені з графом об’єкти. 1. Якщо елементами множини Е є впорядковані пари, то граф називають орієнтованим (або орграфом). У цьому випадку елементи множини V називають вузлами, а елементи множини Е – дугами. Ми розглянемо такі графи у наступному розділі. 2. Якщо елементом множини Е може бути пара однакових (не різних) елементів V, то такий елемент множини Е називають петлею, а граф – псевдографом. 3. Якщо Е є не множиною, а мультимножиною, яка містить деякі елементи декілька разів, то ці елементи називають кратними ребрами, а граф – мультиграфом. 4. Якщо елементи множини Е є не обов’язково двоелементними, а будь-якими (непорожніми) підмножинами множини V, то такі елементи множини Е називають гіпердугами, а граф – гіперграфом. 5. Якщо вершинам і/або ребрам (дугам) присвоєно мітки, то граф називають поміченим (або зваженим). У ролі міток звичайно використовують букви або цілі числа (їх називають вагами). Якщо різні вершини (ребра) мають різні мітки, то граф називають нумерованим. Означення 3.1.1. Простий граф визначають як пару G=(V, E), де V, Е – скінченні множини вершин і ребер відповідно, причому G не може містити петель (ребер, які починаються і закінчуються в одній вершині) і кратних ребер (кратними називаються ребра, які з’єднують одну і ту саму пару вершин) (рис. 3.2, а). Сім’я – це невпорядкована сукупність елементів, у якій вони можуть повторюватись, зокрема, сім’я ребер означає, що в графі є кратні ребра. Неорієнтований мультиграф – це пара G=(V, E), де V – непорожня скінченна множина вершин, Е – сім’я невпорядкованих пар різних елементів із V, тобто це граф, що містить кратні ребра (рис. 3.2, б). Псевдограф – це пара G=(V, E), де V – непорожня скінченна множина вершин, Е – сім’я невпорядкованих пар не обов’язково різних елементів із V, тобто це граф, що містить петлі (в т.ч. і кратні), а також кратні ребра (рис. 3.2, в). За допомогою графів зображують структурні залежності між елементами. Наприклад, в електричній схемі, у молекулі, складеній з атомів, або у схемі міського транспорту. Для побудови графа, що відповідає транспортній схемі, вершинами можна подати зупинки, а ребрами – ділянки маршрутів між ними. Схему доріг міста можна зобразити як мультиграф, вершини якого відповідають перехрестям, а ребра – вулицям з двостороннім рухом. а) б) в) Рис. 3.2. Приклади неорієнтованих графів: а) простий граф, б) мультиграф, в) псевдограф Означення 3.1.2. Підграфом графа G=(VG, EG) називають граф H (VH , EH ) , в якому VH VG і E H EG ; позначають це так: Н G . Підграф Н графа G називають кістяковим (остовним) підграфом, якщо VH VG . Означення 3.1.3. Дві вершини u і v в простому неорієнтованому графі називають суміжними, якщо вони з’єднані якимось ребром е, про яке кажуть, що воно інцидентне вершині u (і v). Єдине ребро простого графа, яке з’єднує пару вершин u і v, позначають uv (або vи). Два ребра називаються суміжними, якщо вони мають спільну вершину, про яку кажуть, що вона інцидентна цим ребрам. Поняття суміжності є в деякому сенсі визначальним для графів і подібних до них об’єктів. При цьому треба враховувати особливості кожного типу об’єктів. В орграфі вершина v суміжна з вершиною и, якщо існує дуга (u, v), при цьому вершина и може бути несуміжна з вершиною v. У неорієнтованому графі вважають, що вершина суміжна сама з собою. У псевдографі, навпаки, вершину не вважають суміжною з собою, якщо у неї нема петлі. У гіперграфі дві вершини вважають суміжними, якщо вони належать одному гіперребру. У гіперграфі гіпердугу звичайно проводять з одного вузла у множину вузлів (можливо, порожню). Далі вираз «граф G(V, E)» означає неорієнтований непомічений граф без петель і кратних ребер з множиною вершин V і множиною ребер Е. Означення 3.1.4. Граф H ( А, EH ) називають вершинно породженим підграфом графа G (на множині вершин А), якщо А VG і множина EH складається з усіх ребер графа G, які з’єднують вершини з множини А. Граф H (VH , B) називають реберно породженим підграфом графа G (на множині ребер В), якщо В ЕG і множина VH складається з усіх вершин, інцидентних ребрам з В і лише з них. У наступних означеннях простіше вважати, що графи G1={V1, Е1} та G2={V2, Е2} є підграфами деякого «більшого» графа. Означення 3.1.5. Об’єднанням графів G1={V1, Е1} та G2={V2, Е2} називають граф G = G1 G2={V, Е}, де V = V1 V2, Е = Е1 Е2. Перетином графів G1={V1, Е1} та G2={V2, Е2} називають граф G=G1 G2={V, Е}, де V = V1 V2; Е=Е1 Е2. На рис. 3.3-3.5 показано, як об’єднувати та як знаходити перетин графів: Рис. 3.3. Об’єднання графів Якщо V1=V2 та Е1 Е2, тоді G = G1 G2=G2 (рис. 3.4). Рис. 3.4. Об’єднання графів зі спільними вершинами Рис. 3.5. Перетин графів З означення 3.1.5 випливає: якщо V1 V2 = (тобто два графи не мають однаково позначених вершин), то перетин G = G1 G2= (порожній граф, рис. 3.6). Рис. 3.3. Порожній граф як результат перетину графів Якщо V1 V2 , а Е1 Е2= , то G=G1 G2 називають цілком незв’язним графом (нуль-графом, в нього нема жодного ребра) і позначають Nп, множина його вершин дорівнює V1 V2 (рис. 3.7). Рис. 3.7. Нуль-граф як результат перетину графів Нехай граф H (VH , Е Н ) є реберно породженим підграфом на множині ребер ЕН . Означення 3.1.3. Різницею G\Н графів G і Н називають граф з множиною ребер ЕG\ЕH, множина вершин різниці складається з вершин v VG \ VH і з тих вершин v VH , які інцидентні деякому ребру з множини ЕG\ЕH. Симетричною різницею G Н графів G і Н називають граф, реберно породжений на множині ребер ЕG ЕH. З’єднанням G+Н графів G і Н називають граф, який утворюється з об’єднання G H , якщо кожну вершину графа G з’єднати ребром з кожною вершиною графа Н при умові VG VH . Означення 3.1.7. Граф називають зв’язним, якщо його не можна зобразити як об’єднання двох непорожніх графів з множинами вершин, які не перетинаються. Граф називають незв’язним, якщо він не є зв’язним. Довільний незв’язний граф G можна зобразити у вигляді об’єднання скінченної кількості зв’язних графів, кожен з них називають компонентою зв’язності G. Мінімальну кількість зв’язних компонент (підграфів) графа називають зв’язністю графа і позначають с(G). Будь-який граф можна розбити на зв’язні підграфи (компоненти зв’язності). Питання зв’язності мають важливе значення при застосуванні теорії графів до комп’ютерних мереж. Алгоритм визначення зв’язності графа G=(V, E) { V ' =V; c=0; while ( V ' ) { вибрати y V ' ; знайти всі вершини, з’єднані маршрутом з у; забрати вершину у з V ' і відповідні ребра з Е; с=c+1; } } Приклад 3.1.1. Прослідкуємо за роботою алгоритму зв’язності на графі, зображеному на рис. 3.8. Рис. 3.8. Незв’язний граф Розв’язання. Будуємо таблицю (табл. 3.1) Отже, с(G)=3. Відповідні компоненти зв’язності подані на рис. 3.9. Таблиця 3.1 Вихідні значення Вибір y=1 Вибір y=2 Вибір y=7 V' {1, 2, 3, 4, 5, 6, 7, 8} {2, 4, 5, 7} {7} c 0 1 2 3 Рис. 3.9. Зв’язні підграфи графа з рис. 3.8 ▲ Означення 3.1.8. Доповненням до графа G називають граф G , що містить ту ж саму кількість вершин, які з’єднані в ньому ребрами лише тоді, коли вони не з’єднані в графі G (рис. 3.10). Рис. 3.10. Доповнення графу Означення 3.1.9. Степенем (або валентністю) (v) вершини v називають кількість інцидентних їй ребер. Зауважимо, що петлю враховують двічі. Послідовність S: d1, d2,…, dn називають послідовністю степенів простого зв’язного графа, якщо його вершини можна позначити через v1, v2,…, vn так, що (vi ) d i для всіх i {1,..., n} . Через (G ) і (G ) позначимо відповідно найменший і найбільший степені вершин графа G. Означення 3.1.10. Вершину з нульовим степенем називають ізольованою. Вершину зі степенем, рівним 1, називають висячою. На рис. 3.11 вершина 1 є висячою, вершина 7 – ізольованою, степінь вершини 3 дорівнює двом, бо вона інцидентна ребрам {3,4} та {3,6}. Рис. 3.11. Граф з ізольованою і висячою вершинами Очевидно, що реберно породжений граф не містить ізольованих точок. Лема про естафету (лема про рукостискання) твердить, що сума степенів вершин довільного графа дорівнює подвоєному числу його ребер. Якщо декілька людей обмінюються рукостисканнями, то кількість потиснутих рук є парною (кожна рука рахується стільки разів, у скількох рукостисканнях вона брала участь). Теорема 3.1. Неорієнтований простий граф має парну кількість вершин непарного степеня. 3.2. Спеціальні типи простих графів У теорії графів виділяють деякі спеціальні типи графів, які застосовують під час розв’язування багатьох задач. Означення 3.2.1. Граф називають однорідним (регулярним степеня k), якщо степені всіх його вершин рівні k (рис. 3.12). Регулярний граф степеня 3 називають кубічним, відомий приклад такого графа – це граф Петерсена (рис. 3.13). Рис. 3.12. Однорідні графи Рис. 3.13. Граф Петерсена Сума степенів усіх вершин однорідного графу дорівнює (v) n , де n – кількість (v ) n . 2 Означення 3.2.2. Простий граф називають повним, якщо всі його вершини з’єднані між собою лише одним ребром. Його позначають Kn, де n – кількість вершин (рис 3.14). вершин графа, а кількість ребер рівна m а) б) в) Рис. 3.14. Повні графи: а) К1, б) К2, в) К4 Кількість ребер у графі Kn рівна m n ( n 1) . 2 Повний граф Kn є регулярним степеня (п-1), а цілком незв’язний Nп – регулярним нульового степеня. Регулярними є також платонові графи – графи, утворені вершинами і ребрами п’яти платонових тіл (правильних багатогранників). Їх особливістю є те, що всі їхні грані є однаковими правильними багатокутниками. Отже, всі сторони правильного багатогранника рівні, всі плоскі кути при вершинах рівні, всі кути між гранями також рівні. Багатогранники названі відповідно до кількості граней (табл. 3.2): правильний тетраедр (трикутна піраміда, 4 грані, рис. 3.16, а), правильний гексаедр (куб, 6 граней), правильний октаедр (8 граней), правильний додекаедр (12 граней, рис. 3.29) і правильний ікосаедр (20 граней). Таблиця 3.2 Символ Шлефлі Тетраедр (3,3) Куб (гектаедр) (4,3) Октаедр (3,4) Додекаедр (5,3) Ікосаедр (3,5) Кількість вершин 4 8 6 20 12 Кількість ребер 6 12 12 30 30 Кількість граней 4 6 8 12 20 Символ Шлефлі (р, q) означає, що многогранник складається з правильних ркутників, які утворюють при вершині q-гранний кут. Використовуючи поняття повного графу можна інакше сформулювати означення 3.1.8 про доповнення до графа. Означення 3.2.3. Граф G є доповненням до графа G, якщо їхнє об’єднання утворює повний граф, тобто K n G G , а перетин множин ребер графів G та G утворює порожню множину. Кількість ребер у доповнювальному графі G рівна m n ( n 1) / 2 E , де n – кількість вершин графа G, а E – кількість ребер графа G. Кількість вершин доповнювального графа G дорівнює кількості вершин графа G. Означення 3.2.4. Зв’язний простий граф з п вершинами називають простим ланцюгом, якщо рівно дві його вершини мають степінь 1, а всі інші – степінь 2, позначають Рп. Зв’язний простий регулярний граф степеня 2 називають циклічним графом або графом-циклом (його перша і остання вершини співпадають, тобто з’єднані у замкнуте кільце, рис. 3.15) і позначають Сn, де n – кількість вершин (n≥3). а) б) в) Рис. 3.15. Графи-цикли: а) С3; б) С4; в) C6 Кількість ребер т у графі Cn рівна n. Означення 3.2.5. З’єднання графів N1 та Сn називають графом-колесом (він отриманий з’єднанням однієї єдиної вершини з усіма вершинами графу Cn, рис. 3.16) і позначають Wn, де n – кількість вершин у графі циклі Cn (n≥3). а) б) в) Рис. 3.13. Графи-колеса: а) W3; б) W4; в) W6 Кількість ребер т у графі Wn рівна 2n , а кількість вершин дорівнює n+1. Означення 3.2.3. Простий граф називаються n-вимірним кубом, якщо він зображає усі бітові рядки довжиною 2n (рис. 3.17). Його позначають Qn. Зауважимо, що дві вершини в графі Qn з’єднані ребром тоді, коли бітові рядки, які вони зображають, не відрізняються більше, ніж на біт. а) б) в) Рис. 3.17. n-вимірні куби: а) Q1; б) Q2; в) Q3 Означення 3.2.7. Простий граф називають двочастковим, якщо множину його вершин V можна розбити на дві підмножини ( V V1 V2 ,V1 V2 ), що не перетинаються, так, що кожне ребро з’єднує вершину з множини V1 із вершиною з множини V2. Двочастковий граф називають повним, якщо кожна вершина з V1 з’єднана з усіма вершинами V2. Його позначають Kk,p, де k V1 , p V2 , Vi – це потужність підмножини Vі. Граф K1,p називають зіркою. Приклад двочасткових графів наведено на рис. 3.18. Кількість ребер у графі Kk,p рівна m k p , а кількість вершин n = k+p. а) б) в) Рис. 3.18. Двочасткові графи: а) неповний двочастковий граф; б) зірка К1,5; в) повний двочастковий граф К2,3 Означення 3.2.8. Маршрутом довжини k в графі G називають таку послідовність вершин v1, v2,…, vk+1, що для кожного і {1,…,k} пара vіvі+1 утворює ребро графа (ребра можуть повторюватися). Позначають такий маршрут v1-v2…-vk+1. Цикл – це маршрут, який з’єднує вершину саму з собою. Маршрут або цикл називають простим, якщо він не містить ребер, що повторюються. Граф, в якому нема циклів, називають ациклічним. Структури дерев, які виникають в обчисленнях, є частковим випадком ациклічних графів. Ними ми займемося у п’ятій темі. Приклад 3.2.1. Знайдемо маршрут довжиною 4 та цикли в графі (рис. 3.19). Розв’язання. Наприклад, 1-4-3-2-5 – це маршрут довжиною 4. У цьому графі є 2 різних цикли довжиною 5: 1-3-2-5-4-1 і 1-2-5-4-3-1. 2 1 3 4 5 Рис. 3.19. Граф Ми можемо пройти ці цикли як в одному напрямі, так і в іншому, починаючи з довільної вершини циклу. Крім того, в графі є 3 різні цикли довжиною 4: 1-2-5-4-1, 1-2-3-4-1 і 2-5-4-3-2, і 2 цикли довжиною 3: 1-2-3-1 і 1-3-4-1. ▲ Теорема 3.2 (критерій двочастковості простого графа, теорема Кеніга). Для того, щоб граф був двочастковим, необхідно і достатньо, щоб він не містив простих циклів із непарною довжиною. Ця теорема дає простий спосіб розпізнавання двочастковості графа, який називають пошуком вшир. Означення 3.2.9. Множину вершин, суміжних із вершиною и, називають її оточенням. Алгоритм працює так. Починаючи з довільної вершини, приписують їй номер 0. Кожній вершині з оточення вершини 0 приписують номер 1. Далі розглядають почергово оточення всіх вершин з номером 1, і всім вершинам, що їм належать і ще не мають номера, приписують номер 2 (рис. 3.20). Процес присвоювання номерів продовжують, доки це можливо. Якщо граф зв’язний, то пошук ушир занумерує всі його вершини. Далі розіб’ємо множину вершин на дві підмножини, до однієї долучимо всі вершини з парними номерами та 0, до іншої – з непарними. Розглянемо породжені два підграфи. Якщо обидва вони порожні (достатньо перевірити, що всі пари вершин з однієї підмножини не суміжні), то початковий граф є двочастковим, в протилежному випадку – не двочастковий. Зазначимо, що існує й інший, більш розповсюджений варіант пошуку вшир, коли всі вершини отримують різні номери (його розглянемо в цьому розділі пізніше). 0 2 1 1 2 1 Рис. 3.20. Розпізнавання двочастковості графа (повний двочастковий граф К3,3) Очевидно, що кількість ребер у зв’язному простому графі з п вершинами не перевищує кількості ребер у повному графі Кп, тобто п(п-1)/2. А скільки може бути ребер у простому графі з п вершинами й фіксованою кількістю k компонент? Теорема 3.3. Якщо простий граф має п вершин і k компонент, то кількість його ребер т задовольняє нерівність n k m (n k )(n k 1) / 2. 3.3. Способи подання графів Найзрозумілішим і найпростішим для людини є графічний спосіб подання графу, коли його зображають на рисунку як сукупність точок, з’єднаних між собою лініями. Але цей спосіб не придатний для опрацювання графів на комп’ютері. Тому розглянемо інші способи подання неорієнтованого графа. Означення 3.3.1. Матриця інцидентності (МІ) – матриця, у якій для кожного ребра вказані інцидентні йому вершини (рядкам матриці відповідають номери вершин, стовпцям – ребра графа), тобто МІ – це прямокутна матриця розміром n×т, де n – кількість його вершин, т – кількість ребер. Для неорієнтованого простого графа елементи МІ знаходять так: 1, якщо вершина vi та ребро e j інцидентні, mij 0, інакше. Зауважимо, що МІ простого графа є булевою (тобто складеною лише з 0 та 1), в кожному стовпці містить точно дві одиниці і не має однакових стовпців, МІ мультиграфа є булевою і має однакові стовпці, які відповідають кратним ребрам, МІ псевдографа не булева, бо у відповідних позиціях матриці ставимо 2 (у ньому є петлі). Приклад 3.3.1. Побудуємо МІ для псевдографа, зображеного на рис. 3.21. Розв’язання. Граф має 5 вершин і 10 ребер (для зручності кожне з них позначене малою латинською літерою), отже, МІ має п’ять рядків та 10 стовпців (табл. 3.3). Оскільки ребро а з’єднує вершини 1 та 2, то в першому стовпці записуємо елементи т11=1 та т21=1, вершина 3 має 2 петлі e та d, тому т34=2, т35=2 і т. д. ▲ Для комп’ютера подання графа матрицею інцидентності є незручним, бо, поперше, для неї потрібно n×m комірок пам’яті, більшість із яких зайняті нулями, подруге, знаходження інформації є тривалим, зокрема, щоб отримати відповідь на питання, чи існує ребро vivj, у найгіршому випадку потрібно перебрати всі стовпці матриці, тобто виконати m кроків. Таблиця 3.3 Рис. 3.21. Псевдограф a b c d e f k l m n 1 1 0 1 0 0 0 0 0 0 0 2 1 1 0 0 0 0 0 0 0 0 3 0 0 1 2 2 1 1 0 0 0 4 0 1 0 0 0 0 1 1 1 0 5 0 0 0 0 1 0 1 1 2 Означення 3.3.2. Матрицю, побудовану на множині вершин графа з урахуванням ребер, називають матрицею суміжності (МС), тобто МС – це квадратна матриця розміром n×n, де n – кількість його вершин. Рядки і стовпці матриці відповідають вершинам графа, а на їх перетинах записують числа, які показують, скільки ребер з’єднують відповідні вершини. Матриця суміжності М симетрична відносно головної діагоналі. Для неорієнтованого графа елементи МС знаходять так: kij , vi v j E , mij 0, інакше, де vivj – ребро графа, kij – кількість ребер, що виходять з вершини vi та входять у вершину vj. Зауважимо, що МС простого графу є булевою та на її головній діагоналі знаходиться цифра 0. Матриці суміжності мультиграфа та псевдографа не будуть булевими: елемент aij дорівнюватиме кратності ребер, що з’єднують відповідні вершини vi та vj, при цьому МС мультиграфа матиме всі нулі на головній діагоналі, а псевдографа – ні, бо петлю у вершині vi записують mii=1. Приклад 3.3.2. Побудуємо матрицю суміжності для псевдографа, наведеного на рис. 3.22. Розв’язання. У графі шість вершин, отже, МС має 6 рядків і 6 стовпців (табл. 3.4). Оскільки вершина 1 не має петлі, то елемент т11=0, вершини 1 і 2 з’єднані трьома кратними ребрами, тому т12=3 і т. д. ▲ Таблиця 3.4 1 2 3 4 5 6 1 0 3 1 0 0 2 2 3 0 1 1 0 0 3 1 1 0 0 1 0 4 0 1 0 2 2 1 5 0 0 1 2 1 1 6 2 0 0 1 1 1 Рис. 3.22. Псевдограф За допомогою МС легко можна обчислити степінь будь-якої вершини. Для цього достатньо додати всі числа відповідного рядка (або стовпця) і до результату додати число, що знаходиться на перетині даного рядка (або стовпця) з головною діагоналлю. Наприклад, степінь вершини 4 дорівнює (1+2+2+1)+2. Велика перевага МС як способу подання графу – швидкий і простий доступ до інформації: за один крок можна одер- жати відповідь на питання, чи існує ребро з vi у vj. Окрім того, перевагою МС є легка перевірка на тип графа – простий, мультиграф чи псевдограф. Якщо матриця містить лише 0 та 1, то маємо простий граф. Якщо серед елементів є числа, відмінні від одиниць та нулів, і всі діагональні елементи є нулями – це мультиграф. Якщо в матриці хоч один діагональний елемент не рівний нулю – це псевдограф. Недолік такого способу подання полягає в тому, що незалежно від кількості ребер обсяг пам’яті становить n2 комірок. Для відновлення графа нам досить лише тих елементів матриці суміжності, які розміщені над головною діагоналлю. Означення 3.3.3. Список пар (список ребер) – це спосіб подання графа, при якому пара [vi, vj ] відповідає ребру vi vj. Він є економнішим щодо пам’яті, особливо коли кількість ребер т є значно меншою, ніж кількість вершин п, адже обсяг пам’яті дорівнює 2т. Недолік – велика (порядку т) кількість кроків для знаходження множини вершин, до яких ідуть ребра з заданої. Ситуацію можна поліпшити, упорядкувавши множину пар лексикографічно та застосувавши двійковий пошук. Приклад 3.3.4. Побудуємо список пар для графа, наведеного на рис. 3.24. Розв’язання. У список записуємо в лексикографічному порядку усі існуючі ребра (перші два стовпці табл. 3.5). Кількість пар дорівнює кількості ребер графу. ▲ Таблиця 3.5 Вершина Вершина Вершина Список виходу входу виходу вершин входу 1 1 1 1, 2, 3 1 2 2 1, 2, 4 1 3 3 1, 4, 4, 4 2 2 4 2, 3, 3, 3 2 4 3 4 3 4 3 4 Рис. 3.24. Псевдограф Означення 3.3.4. Список суміжності – це спосіб подання графа, при якому для кожної вершини вказують список вершин, у які вона входить. У третьому і четвертому стовпцях табл. 3.5 подано список суміжності неорієнтованого графа, зображеного на рис. 3.24. Цей спосіб подання графа використовують тоді, коли кількість ребер значно менша, ніж кількість вершин в степені 2 (m<<n2), а також для випадків динамічних графів, коли у графі постійно додаються нові вершини та ребра. Головний недолік такого способу подання графу – це неможливість швидкої перевірки наявності ребра vivj. 3.4. Вершинна та реберна зв’язність Означення 3.4.1. Числом вершинної зв’язності (числом зв’язності) к(G) простого графа G називають найменшу кількість вершин, вилучення яких дає незв’язний або одновершинний граф, при цьому вершину вилучають з інцидентними їй ребрами. Граф G, зображений на рис. 3.25, зв’язний, але його зв’язність можна порушити вилученням вершини и, тому, к(G)=1. Якщо ж спробувати порушити зв’язність цього графа вилученням ребер (а не вершин), то треба вилучити не менше трьох ребер. y v y z u u z p w x v t s x G t s w H Рис. 3.25. Зв’язний граф Означення 3.4.2. Числом реберної зв’язності (G) простого графа G з п>1 вершинами називають найменшу кількість ребер, вилучення яких дає незв’язний граф (але вершини, які з’єднує це ребро, залишаються). Число реберної зв’язності одновершинного графа вважають рівним 0. Для графа G з рис. 3.25 (G)=3. Означення 3.4.3. Вершину простого графа називають точкою з’єднання, якщо в разі її вилучення новий граф матиме більше компонент, ніж даний. Ребро графа називають мостом, якщо його вилучення збільшує кількість компонент. Граф називають нероздільним, якщо він є зв’язний і не має точок зчленування. Граф називають сепарабельним, якщо він має хоча б одну точку зчленування (він є роздільним). Отже, точки з’єднання і мости – це свого роду «вузькі місця» простого графа. Граф Н з рис. 3.25 має три точки з’єднання t, s, p та один міст ts. Означення 3.4.4. Простий граф називають t-зв’язним (вершинно-t-зв’язним), якщо к(G) t і реберно-t-зв’язним, якщо (G) t . Граф G, зображений на рис. 3.25, однозв’язний і реберно-3-зв’язний. Неважко побачити, що зв’язність (вершинна і реберна) незв’язного графа дорівнює нулю, к(Кп)= (Кп)=п-1, к(Сп)=2. Теорема 3.4. Для кожного простого зв’язного графа G маємо к(G) (G) (G ) , де (G ) – найменший степінь вершин графа G. Нерівності цієї теореми покращити не можна – має місце теорема. Теорема 3.5. Для довільних цілих чисел а, b, c (0<a b c) існує граф G, для якого к(G)=a, (G)=b, (G ) =c. Якщо зв’язати ці величини з кількістю вершин графа, то отримаємо таку умову. Теорема 3.6. Якщо граф має п вершин і (G ) [n / 2] , то (G ) (G ) , тут [a] – ціла частина числа а. Наведемо достатні умови того, що простий граф є вершинно-t-зв’язним. Теорема 3.7 (теорема Бонді). Нехай G – простий граф з п вершинами, які позначені так, що (v1 ) (v2 ) ... (vn ) . Тоді граф G є вершинно-t-зв’язним, якщо (v r ) r t 1 для 1 r n 1 (v n t 1 ) . 3.5. Ейлерові графи Модель поставленої Ейлеру задачі – це мультиграф, складений з множини вершин і множини ребер, що з’єднують ці вершини. Вершини А, В, С і D символізують береги ріки і острови, а ребра a, b, c, d, e, f і g позначають 7 мостів (рис. 3.26). Шуканий маршрут (якщо він існує) відповідає обходу ребер мультиграфа так, що кожне з них проходять лише один раз. Прохід ребра, очевидно, відповідає переходу ріки по мосту. Отже, задачу про кенігсбергські мости мовою теорії графів можна сформулювати так: чи існує в мультиграфі простий цикл, який містить усі його ребра? Рис. 3.26. Модель задачі про мости Кенігберга Означення 3.5.1. Ейлеровим циклом (ЕЦ) у зв’язному мультиграфі називають простий цикл, що містить усі ребра графа. Ейлеровим маршрутом (ЕМ) у зв’язному мультиграфі називають простий маршрут, що містить усі ребра графа. Ейлеровим графом (ЕГ) називають граф, який містить ейлеровий цикл, тобто у ньому знайдеться маршрут, що починається і закінчується в тій самій вершині і проходить через усі ребра графа лише один раз. Приклад 3.5.1. Визначимо, які з графів, зображених на рисунку 3.27, мають ЕЦ і ЕМ. Розв’язання. Граф G1 має ЕЦ, наприклад, а-е-c-d-e-b-a; граф G2 не має ні ЕЦ, ні ЕМ; граф G3 не має ЕЦ, але має ЕМ: а-c-d-e-b-d-a-b. а b а e G1 а b e c d b d c с d G2 G3 Рис. 3.27. Ейлерові цикли і ейлерові маршрути ▲ e Ейлер зауважив, що якщо в графі є ейлеровий цикл, то для кожного ребра, що входить у якусь вершину, має існувати інше ребро, що з неї виходить (бо з умови задачі, зайшовши у вершину, ми не можемо вийти по тому ж ребру) і отримав з цього простого спостереження такий висновок: якщо в графі існує ейлеровий цикл, то до кожної вершини має підходити парна кількість ребер. Крім того, Ейлеру вдалося довести й протилежне твердження і таким чином сформулювати теорему. Теорема 3.8 (теорема Ейлера). Граф, в якому будь-яка пара вершин зв’язана деякою послідовністю ребер, є ейлеровим тоді і лише тоді, коли всі його вершини мають парний степінь. Тепер цілком очевидно, що в графі, яким змодельована задача про мости Кенігсберга, неможливо знайти ейлерового циклу. Дійсно, степені всіх його вершин непарні: ( B ) (C ) ( D ) 3 і ( A) 5 . Алгоритм Флері побудови ейлерового циклу У процесі побудови ЕЦ здійснено нумерацію його ребер. Крок 1. Починаємо з довільної вершини и та присвоюємо довільному ребру uv номер k=1. Викреслюємо це ребро і переходимо у вершину v. Крок 2. Вибираємо довільне ребро, інцидентне вершині v, причому міст вибираємо лише тоді, коли немає інших можливостей. Присвоюємо йому номер k=k+1 і викреслюємо його. Крок 3. Якщо всі ребра графа викреслено та пронумеровано, то кінець (вказані номери задають послідовність ребер в ЕЦ), інакше переходимо на крок 2. Теорема 3.9. Зв’язний мультиграф має ЕМ, але не має ЕЦ, тоді і лише тоді, коли він має точно дві вершини непарного степеня. Доведення. Необхідність. Припустимо, що зв’язний мультиграф має ЕМ від и до v, але не має ЕЦ. Перше ребро циклу додає 1 до степеня вершини и. Щоразу, коли маршрут проходитиме через вершину и, він додаватиме до її степеня 2. Останнє ребро шляху додасть 1 до степеня вершини v, а кожне проходження маршруту через вершину v додаватиме до її степеня 2. Отже, вершини и та v мають непарний степінь. Усі інші вершини – парного степеня, бо маршрут додає 2 до степеня вершини, коли проходить через неї. Достатність. Припустимо, що граф G має точно 2 вершини, нехай и та v, з непарним степенем. Розглянемо граф G' , одержаний з графа G додаванням нового ребра uv. Кожна вершина графа G' має парний степінь, отже, G' має ЕЦ. Тепер вилучимо нове ребро і одержимо ЕМ у графі G. Теорему доведено. Зазначимо, що будь-який ЕМ починається в одній з цих двох вершин непарного степеня, а закінчується в іншій. Оскільки степені всіх вершин графа, яким змодельована задача про мости Кенігсберга, непарні, то він не має навіть ЕМ, тобто неможливо пройти кожний міст по одному разу, навіть якщо не потрібно повертатись у початкову точку. 3.6. Гамільтонові графи Ми вивчили ейлерові графи, які володіють замкнутим маршрутом, що проходить через всі ребра графа лише один раз. Означення 3.6.1. Маршрут, який проходить через кожну вершину графа лише один раз, називають гамільтоновим маршрутом. Цикл, який проходить через кожну вершину графа (окрім першої і останньої) лише один раз, називають гамільтоновим циклом (ГЦ), а відповідний граф – гамільтоновим графом. Термін «гамільтоновий» походить від імені відомого ірландського математика В. Гамільтона, який 1857 р. запропонував гру «Навколосвітня подорож». Кожній з 20-ти вершин додекаедра (правильного 12-тигранника, грані якого є п’ятикутниками) приписано назву одного з великих міст світу. Потрібно, розпочавши з довільного міста, відвідати решту 19 міст лише один раз і повернутись у початкове; перехід дозволено ребрами додекаедра. Цю задачу зображено на площині (рис. 3.28). Вона зводиться до відшукання в графі ГЦ. Один з можливих розв’язків показано потовщеними лініями. 1 2 6 3 5 7 20 13 4 14 9 8 11 12 10 18 17 16 19 15 Рис. 3.28. Гамільтоновий цикл Не всі зв’язні графи мають ГЦ хоча б тому, що такі графи мають бути двозв’язними (необхідна умова), але граф, що має дві точки з’єднання, може не мати ГЦ. Граф, зображений на рис. 3.29, є двозв’язним (можна, наприклад, вилучити точки 1 і 5), але цього недостатньо для наявності ГЦ. 1 3 2 5 4 6 7 8 Рис. 3.29. Двозв’язний граф без гамільтонового циклу Гамільтонові графи слугують моделлю при складанні розкладів руху поїздів, для телекомунікаційних мереж і т.д. На відміну від задачі Ейлера, простого критерію, чи граф є гамільтоновий, поки що немає. Пошук хорошого критерію залишається однією з головних нерозв’язаних задач теорії графів. Тим не менше, багато графів є гамільтоновими, зокрема, у будь-якому повному графі можна знайти ГЦ. Розглянемо повний граф K5, зображений на рис. 3.30. Його цикл a-b-c-d-e-a є гамільтоновим, в ньому є й інші ГЦ. Оскільки кожна вершина суміжна з іншими, то починаючи з вершини а, як другу вершину циклу ми можемо вибрати будь-яку з 4-х інших. Далі у нас буде 3 варіанти вибору для 3-ї вершини і 2 для 4-ї, після чого ми вернемося у вершину а. Тому ми маємо 4х3х2=24 цикли. Але оскільки кожен цикл може проходити як в одному напрямі, так і в іншому, то реально в графі K5 є лише 12 різних ГЦ (дві різні послідовності вершин a-b-c-d-e-a і a-e-d-c-b-a задають, зрозуміло, той самий цикл). Рис. 3.30. Повний граф K5 Пошук ГЦ (якщо він існує) в довільному зв’язному графі – задача дуже непроста і трудоємна. Гамільтонові графи застосовують для моделювання багатьох практичних задач. Основою всіх таких задач є класична задача комівояжера: Комівояжер повинен здійснити поїздку містами і повернутися, побувавши в кожному місті лише один раз з мінімальними витратами на пересування. Графічна модель задачі комівояжера складається з гамільтонового графа, вершини якого відповідають містам, а ребра – дорогам, які їх зв’язують. Вага ребра позначає транспортні витрати, необхідні для мандрівки відповідною дорогою, такі, як, наприк- лад, відстань між містами чи час руху по дорозі. На жаль, ефективного алгоритму розв’язування даної задачі поки що не знайдено. Для складних мереж кількість ГЦ, які необхідно переглянути для виділення мінімального, надзвичайно велика. Однак існують алгоритми пошуку субоптимального розв’язку. Субоптимальний розв’язок необов’язково дасть цикл мінімальної загальної ваги, але знайдений цикл буде мати, як правило, значно меншу вагу, ніж більшість довільних ГЦ. Розглянемо один з таких алгоритмів. Алгоритм найближчого сусіда Він знайде субоптимальний розв’язок задачі комівояжера, генеруючи гамільтонові цикли у зваженому графі з множиною вершин V. Цикл, отриманий в результаті роботи алгоритму, співпадатиме з кінцевим значенням змінної маршрут, а його загальна довжина – кінцеве значення змінної w. { вибрати v V ; маршрут=v; w=0; v' v ; відмітити v' ; while (залишаються невідмічені вершини) { вибрати непозначену вершину u, найближчу до v' ; маршрут=маршрут - u; w=w + вага ребра v' u; v' =u; відмітити v' ; } маршрут=маршрут - v; w=w + вага ребра v' v; } Приклад 3.6.1. Застосуємо алгоритм найближчого сусіда до графа, зображеного на рис. 3.31. За вихідну вершину візьмемо вершину D. Рис. 3.31. Зважений граф для пошуку ГЦ Розв’язання. Запишемо таблицю (табл. 3.6). Таблиця 3.6 Вихідні значення Останній прохід u _ маршрут D w 0 v' D C A B B D-C D-C-A D-C-A-B D-C-A-B-D 3 9 14 24 C A B B У результаті роботи алгоритму знайдено ГЦ D-C-A-B-D загальною вагою 24. Роблячи повний перебір всіх циклів в цьому малому графі, можна знайти ще 2 інших ГЦ: A-B-C-D-A загальною вагою 23 і A-C-B-D-A загальною вагою 31. ▲ У повному графі з 20 вершинами існує приблизно 6,1 1016 ГЦ, перебір яких вимагає надзвичайно багато машинної пам’яті і часу. Вивчення достатніх умов наявності в графі ГЦ – один з важливих напрямів у теорії графів. Інтуїтивно зрозуміло, що граф з багатьма ребрами, достатньо рівномірно розподіленими, має великий шанс містити ГЦ. Ми вже зауважували, що такого гарного критерію гамільтоновості графа, як теорема 3.8 для ейлерових графів, нема. Достатні умови гамільтоновості дає, наприклад, така теорема. Теорема 3.10. Простий граф з послідовністю степенів S: d1 d 2 ... d n , п 3 , гамільтоновим, якщо виконується одна з таких умов: 1) d j n / 2 для всіх j 1, n ; 2) для кожної пари несуміжних вершин v i w маємо (v ) ( w) n ; 3) для всіх k: 1 k n / 2 виконується d k k ; 4) для всіх j,k, де j<k, з того, що d j j d k k 1 випливає, що d j d k n ; 5) з того, що d k k n / 2 випливає, що d n k n k . Причому маємо: 1) 2) 3) 4) 5). Зауважимо, що жодна з умов (1 – 5) може не виконуватися, але граф таки буде гамільтоновим. Найпростіший приклад – циклічний граф Сп , п 6 . Його послідовність степенів S: 2, 2,..., 2 не задовольняє жодну з цих умов. Як знайти ГЦ або переконатись, що його немає? Очевидний алгоритм повного перебору всіх можливостей, тобто п! перестановок усіх вершин графа і перевірок практичного застосування не має. Ми розглянемо практично застосовний алгоритм бектрекінгу у п’ятій темі. Задача знаходження ГЦ NP-повна, тобто належить до класу задач, для яких невідомий (і є вагомі підстави вважати, що його не існує) ефективний (тобто з поліноміальною складністю) алгоритм їхнього розв’язання. 3.7. Обхід графів Існує багато алгоритмів на графах, які грунтуються на систематизованому переборі їхніх вершин, під час якого кожну вершину переглядають і позначають рівно один раз, тобто вона одержує унікальний порядковий номер. Алгоритми обходу вершин графа називають методами пошуку. 3.1.1. Пошук углиб у простому зв’язному графі (DFS – Depth First Search) Нехай G=(V, E) – простий зв’язний граф, усі вершини якого позначені різними символами. У процесі пошуку вглиб вершинам графа надають номери та певним чином позначають ребра. У ході роботи алгоритму використовують структуру даних для збереження номерів вершин, яку називають стеком (stack). Зі стеку можна вилучити лише той елемент, який було додано до нього останнім, тобто він працює за принципом «останній прийшов – перший вийшов» (LIFO – last in, first out). Додавання і вилучення елементів у стеку відбувається з одного кінця, який називають верхівкою стеку, номер вершини х позначають DFS(x). Алгоритм пошуку углиб у простому зв’язному графі Крок 1. Починаємо з довільної вершини vs та присвоюємо DFS(vs):=1. Включаємо цю вершину в стек. Крок 2. Розглядаємо вершину у верхівці стеку: нехай це буде вершина х. Якщо всі ребра, інцидентні вершині х, позначено, то переходимо до кроку 4, інакше – до кроку 3. Крок 3. Нехай ху – непозначене ребро. Якщо DFS(у) вже визначено, то позначаємо ребро ху тонкою суцільною лінією та переходимо до кроку 2. Якщо DFS(у) не визначено, то позначаємо ребро ху потовщеною суцільною лінією, визначаємо DFS(у) як черговий DFS-номер, включаємо цю вершину в стек і переходимо до кроку 2. Крок 4. Виключаємо вершину х зі стеку. Якщо стек порожній, то кінець, інакше – перейдемо до кроку 2. Щоб вибір був однозначним, доцільно домовитись, що вершини, суміжні з тією, яка вже отримала DFS-номер, аналізують за зростанням їх нумерації (або в алфавітному порядку). Динаміку роботи алгоритму зручно відображати протоколом обходу графа пошуком углиб – таблицею з трьома стовпцями: вершина, DFS-номер, вміст стеку. Приклад 3.7.1. Виконаємо обхід графа, зображеного на рис. 3.32, пошуком углиб, починаючи з вершини b. а d f c b e h g Рис. 3.32. Граф Розв’язання. Розв’язок подано на рис. 3.33, протокол пошуку вглиб – в табл. 3.7 (у ній в третьому стовпці вважаємо, що верхівка стеку праворуч). 4 3 5 2 1 6 8 7 Рис. 3.33. Пошук углиб у графі Таблиця 3.7 Вершина DFS-номер Вміст стеку b c d a f e g h - 1 2 3 4 5 6 7 8 - b bc bcd bcda bcd bc bcf bcfe bcfeg bcfe bcf bc bch bc b Ребра, які позначено потовщеною суцільною лінією, називають прямими, а тонкою – зворотними. Їх використовують у різних алгоритмах, основаних на пошуку углиб.▲ 3.1.2. Пошук вшир у простому зв’язному графі (BFS – Breadth First Search) Під час пошуку рухаються вшир: спочатку проглядають всі сусідні вершини, їм надають ВFS-номери, потім сусіди сусідів і т.д. У ході реалізації алгоритму використовують структуру даних для збереження номерів вершин, яку називають чергою (queue). З черги можна вилучити лише той елемент, який перебував у ній найдовше: працює принцип «першим прийшов – першим вийшов» (FIFO – first in, first out). Елемент включають в хвіст черги (праворуч), а виключають з її голови (ліворуч). Використання вершини полягає у перегляді всіх ще не відвіданих її сусідів, номер вершини х позначають ВFS(x). Алгоритм пошуку вшир у простому зв’язному графі Крок 1. Починаємо з довільної вершини vs та присвоюємо ВFS(vs):=1. Включаємо цю вершину в чергу. Крок 2. Розглядаємо вершину, яка знаходиться на початку черги: нехай це буде вершина х. Якщо для всіх вершин, суміжних з вершиною х, уже визначені ВFSномери, то переходимо до кроку 4, інакше – до кроку 3. Крок 3. Нехай ху – ребро, в якому номер ВFS(у) не визначено, тоді позначимо це ребро ху потовщеною суцільною лінією, визначимо ВFS(у) як черговий ВFS-номер, включаємо вершину у у чергу та переходимо до кроку 2. Крок 4. Виключаємо вершину х з черги. Якщо черга порожня, то кінець, інакше – перейдемо до кроку 2. Щоб вибір був однозначним, вершини, суміжні з вершиною х, аналізують за зростанням їх нумерації (або в алфавітному порядку). Динаміку роботи алгоритму зручно відображати протоколом обходу, аналогічним попередньому за винятком третього стовпця (тепер це вміст черги). Приклад 7.3. Виконаємо обхід графа, зображеного на рис. 3.32, пошуком вшир, починаючи з вершини b. Розв’язання. Розв’язок подано на рис. 3.34, протокол пошуку вшир – в табл. 3.8. 7 3 4 2 1 8 6 5 Рис. 3.34. Пошук вшир у графі ▲ Обчислювальна складність обох алгоритмів обходу однакова й у разі подання графа списками суміжності становить О(т+п), де т – кількість ребер, п – кількість вершин графа, отже, ці алгоритми мають лінійну складність, тобто їх ефективність досить висока. Таблиця 3.8 Вершина ВFS-номер Вміст черги b c d f g h a e - 1 2 3 4 5 6 7 8 - b bc bcd cd cdf cdfg cdfgh dfgh dfgha fgha fghae ghae hae ae e 3.8. Ізоморфізм графів Буквальний переклад слова “ізоморфізм” означає “однаковість форми”. Форма графа – це його структура. Таким чином, ізоморфізм графів означає однаковість їх структури. Означення 3.8.1. Два графи G1 = (V1, E1) і G2 = (V2, E2) називають ізоморфними (позначають G1 G2), якщо між множинами їх вершин існує взаємно однозначне відображення f : V1→V2, яке зберігає суміжність, тобто для довільних вершин v і w ребро vw E1 тоді й лише тоді, коли f(v)f(w) E2. При цьому f називають ізоморфним відображенням або ізоморфізмом графа G1 на граф G2. Простіше кажучи, граф, ізоморфний до заданого, – це той самий граф з точністю до позначення вершин і графічного зображення. Але побачити це часом не так просто. Два графи, показані в табл. 3.9, ізоморфні, незважаючи на свою зовнішню відмінність. Графи, зображені на рис. 3.30 (повний граф K5) та 3.35, теж ізоморфні. Таблиця 3.9 Граф G Граф H Ізоморфізм між G і H ƒ(a) = 1 ƒ(b) = 6 ƒ(c) = 8 ƒ(d) = 3 ƒ(g) = 5 ƒ(h) = 2 ƒ(i) = 4 ƒ(j) = 7 Рис. 3.35. Граф, ізоморфний до повного графа K5 Алгоритм перевірки графів на ізоморфізм (необхідні умови). Крок 1. Кількості вершин графів G1 та G2 мають співпадати. Крок 2. Кількість ребер графів G1 та G2 мають співпадати. Крок 3. Степені вершин графів G1 та G2 мають співпадати. Крок 4. Якщо у графі G1 існує маршрут v1-v2-…-vn і (v1)=k1, (v2)=k2, … (vп)=kп, то і у графі G2 повинен існувати маршрут через вершини зі степенями k1, k2, … k п. Крок 5. Якщо хоча б одна з цих умов не виконується, то графи не ізоморфні. Але якщо вони всі виконуються, то це не означає, що графи ізоморфні. Тоді потрібно шукати нумерацію вершин таким чином, щоби виконувалось означення 3.8.1. У загальному випадку таких способів є n!. Отже, кроки 1-4 пришвидшують відповідь на запитання, чи графи ізоморфні. Приклад 3.8.1. Показати, що пари графів, зображених на рис. 3.36 а, б, є ізоморфними, а пара графів на рис. 3.36 в не є ізоморфною. г) д) Рис. 3.36. Приклади ізоморфних та неізоморфного графів Розв’язання. Розглянемо пару графів (рис. 3.36, а). Перевіримо необхідні умови ізоморфізму. Крок 1: кількість вершин – 5=5. Крок 2: кількість ребер – 5=5. Крок 3: сума степенів – 10=10. Крок 4: сума степенів сусідніх вершин співпадає, бо кожна вершина має однаковий степінь (2). Крок 5: Пронумерувавши кожну вершину графа, ми бачимо, що існує однозначне відображення кожної вершини обох графів. Отже, графи на рис. 3.36, а ізоморфні. Розглянемо пару графів (рис. 3.36, б). Перевіримо необхідні умови ізоморфізму. Крок 1: кількість вершин – 4=4. Крок 2: кількість ребер – 6=3. Крок 3: сума степенів – 12=12. Крок 4: сума степенів сусідніх вершин співпадає, бо кожна вершина має однаковий степінь (3). Крок 5: Пронумерувавши кожну вершину графа, ми бачимо, що існує однозначне відображення кожної вершини обох графів. Отже, графи на рис. 3.36, б ізоморфні. Розглянемо пару графів (рис. 3.43, в). Перевіримо необхідні умови ізоморфізму. Крок 1: кількість вершин – 6=3. Крок 2: кількість ребер – 5=5. Крок 3: сума степенів – 3+2х2+3=10, 10=10. Кроки 4-5: пронумеруємо вершини обох графів (рис. 3.36, г, д): Після нумерації вершин обох графів у графі 3.36, г є вершина 2 зі степенем (2)=3, сусідами якої є вершини 1, 3 та 4 зі степенями (1)=1, (3)=2, (4)=1 відповідно. У графі 3.36, д теж є вершина 2 зі степенем (2)=3, сусідами якої є вершини 1, 3 та 4 зі степенями (1)=2, (3)=2, (4)=1 відповідно. Отже, не існує однозначної відповідності вершин, тому графи не є ізоморфними. ▲ Для того, щоб граф G1 був ізоморфним графу G2 , необхідно і достатньо, щоб існувала така підстановка, яка встановлювала б взаємно однозначну відповідність між вершинами графа, а також між їх ребрами. Далі дамо відповідь на запитання: чи можна встановити ізоморфізм графів за їхніми матрицями інцидентності та суміжності або за списками ребер та суміжності? Для перевірки ізоморфності графів G1 і G2 за матрицею суміжності необхідно визначити, чи існує така перестановка рядків і стовпців у матриці суміжності G1 , щоб у результаті вийшла матриця G2 . З цією метою треба зробити всі можливі перестановки рядків і стовпців (а їхня максимальна кількість дорівнює n!∙ n!). Якщо після однієї із цих перестановок матриці суміжності тотожньо збігаються, то графи ізоморфні. Для перевірки ізоморфності графів G1 і G2 за матрицею інцидентності необхідно визначити, чи існує така перестановка рядків і стовпців у матриці інцидентності G1 , щоб у результаті вийшла матриця G2 . З цією метою треба зробити всі можливі пари перестановок рядків і стовпців (а їхня максимальна кількість дорівнює n!m! ). Якщо після однієї із цих перестановок матриці інцидентності тотожно збігаються, то графи ізоморфні. Аналогічно, переставляючи рядки у списках ребер чи суміжності одного графа, можна визначити, чи він є ізоморфним іншому. І в першому, і в другому випадку це доволі трудомісткі операції, і розв’язування задачі “вручну” не завжди виправдано. Часто ізоморфність графів простіше встановити за їхніми графічними поданнями. Наприклад, на рис. 3.37 зображено графи G і H з однаковою кількістю вершин і ребер. Рис. 3.37. Пара графів для перевірки на ізоморфізм Степінь кожної вершини для цих графів запишемо в табл. 3.10: Таблиця 3.10 Степінь у графі H 3 6 2 2 3 2 Назва вершини a b c d e f Степінь у графі G 3 2 2 5 3 3 Як бачимо з табл. 3.10, степені вершин b, d та f не збігаються, тому графи не є ізоморфними. Приклад 3.8.2. Знайдемо серед графів Н, К і L, зображених на рис. 3.38, підграфи графа G. Розв’язання. Позначимо вершини графів H, K і G як показано на рис. 3.39. Графи Н і K – підграфи в G, а граф L не є підграфом в G, бо у нього є вершина степеня 4, якої нема в G. Рис. 3.38. Графи для пошуку підграфів Рис. 3.39. Граф G і підграфи ▲ 3.9. Планарні та плоскі графи Часто немає значення, як зобразити граф на рисунку, бо ізоморфні графи несуть одну й ту саму інформацію. Проте інколи важливо, чи можна подати граф на площині так, щоб його зображення задовольняло певним вимогам. Наприклад, у радіоелектроніці в процесі виготовлення мікросхем друкованим способом електричні ланцюги наносять на плоску поверхню ізоляційного матеріалу. Оскільки провідники не ізольовані, то вони не мають перетинатись. Аналогічна задача виникає під час проектування залізничних та інших шляхів, де переїзди небажані. Так виникає поняття плоского графа. Означення 3.9.1. Плоским називають граф, зображений на площині так, що жодні два його ребра геометрично не перетинаються ніде, окрім інцидентних їм вершин. Граф, ізоморфний до плоского, називають планарним. Плоский граф розбиває площину на області (грані), одна з яких необмежена (зовнішня грань), інші називають внутрішніми. Наприклад, усі три графи на рис. 3.40 планарні, але лише другий і третій із них плоскі. На рис. 3.41 зображено плоский граф. Він має чотири грані: r1, r2, r3, r4, з них грань r4 – зовнішня. а) б) Рис. 3.40. Планарні (а-в) та плоскі (б, в) графи в) Рис. 3.41. Плоский граф з гранями Теорема 3.11 (теорема Ейлера про плоскі графи). Нехай зв’язний плоский граф G має п вершин, т ребер і r граней. Тоді п + r - т = 2. Доведення. Здійснимо індукцію за кількістю ребер у графі G. Якщо т = 0, то п = 1, r = 1, і теорема справджується. Допустимо, що теорема справджується для довільного плоского графа G, який має т-1 ребро, і додамо до G нове ребро e. Можливі три випадки. 1. Ребро e – петля; тоді виникне нова грань, а кількість вершин залишиться незмінною. 2. Ребро e з’єднує дві різні вершини графа G, тоді одна з граней розпадеться на дві, тому кількість граней збільшиться на одну, а кількість вершин не зміниться. 3. Ребро e інцидентне лише одній вершині в G, тоді потрібно додати ще одну вершину; отже, кількість вершин збільшиться на одну, а кількість граней не зміниться. Твердження теореми залишається правильним у кожному з цих трьох випадків. Оскільки інші випадки неможливі, то індукцію завершено й теорему доведено. Легко побачити, що формула Ейлера правильна і для кількості вершин, ребер та граней довільних багатогранників. Неважко перенести цю формулу і на випадок незв’язних графів. Теорема 3.12. Нехай плоский граф G має п вершин, т ребер, r граней і k компонент зв’язності. Тоді п + r -m= k+1. Доведення. Застосуємо формулу Ейлера до кожної компоненти Gi окремо: пi + ri - тi = 2 і просумуємо k ( ni ri mi ) 2 k . Враховуючи, що необмежену компоненту потрібно i 1 k k k i 1 i 1 i 1 порахувати лише раз, отримаємо ni n, mi m, ri ( k 1) r , n-m+r=2k-(k-1). Теорема 3.13. Графи К5 і К3,3 не планарні. Доведення. Граф К5 (див. рис. 3.30) має n=5 вершин і m=10 ребер. Припустимо, що він планарний; тоді існує ізоморфний до нього плоский граф. За теоремою Ейлера r = m + 2 - п = 10 + 2 - 5= 7. Зазначимо, що будь-яке ребро плоского графа або розділяє дві різні грані, або є мостом. Позаяк граф К5 не має петель і кратних ребер, то кожна грань обмежена принаймні трьома ребрами. Тому число 3r – оцінка знизу подвоєної кількості ребер графа, тобто 3r 2т, звідки випливає, що 21 20. Отримали суперечність. У графі К3,3 (див. рис. 3.20) кількість вершин п=3+3=6, а кількість ребер т=3х3=9. Припустимо, що він планарний. Тоді в ізоморфному до нього плоскому графі за теоремою Ейлера кількість граней r = т + 2 - п= 9 + 2 - 6=5. Будь-яка грань двочасткового графа має бути обмежена принаймні чотирма ребрами (за теор. 3.2 двочастковий граф має лише прості цикли з парною довжиною). Отже, 4r 2m (2r m), звідки випливає, що 10 9. Знову отримали суперечність. Доведення завершено. Означення 3.9.3. Граф G1 називають гомеоморфним графу G, якщо його можна отримати з графа G додаванням до його ребер нових вершин степеня 2 (рис. 3.42). Іншими словами, якщо графи гомеоморфні, то це той самий граф з точністю до вершин степеня 2. Рис. 3.42. Гомеоморфні графи Наступна теорема дає критерій (необхідну й достатню умову) планарності графа. Теорема 3.14. (теорема Куратовського). Граф планарний тоді й лише тоді, коли він не містить підграфів, гомеоморфних графам К5 або К3,3. Необхідність умов теореми вже доведено, бо доведено непланарність графів К5 і К3,3 (теорема 3.13), а доведення достатності складне, і ми його не наводимо. На рис 3.43 зображено підграф графа Петерсена (див. рис. 3.13), гомеоморфний К3,3. Тому за теоремою Куратовського граф Петерсена непланарний. Рис. 3.43. Підграф графа Петерсена, гомеоморфний К3,3 Окрім теореми Куратовського є й інші критерії планарності графів. Практично перевірити умови, якими характеризуються планарні графи, не завжди просто. Проте розроблено ефективні алгоритми, які дають змогу для будь-якого заданого графа знайти його зображення на площині без перетину ребер або переконатись, що це неможливо (якщо граф непланарний). 3.10. Алгоритм укладання графу Алгоритм укладання графу G є процесом послідовного приєднання до деякого укладеного підграфу G графу G нового ланцюга, обидва кінці якого належать G . Як початковий плоский граф G вибирають будь-який простий цикл графу G . Процес продовжується доти, поки не буде побудовано плоский граф, ізоморфний графові G , або приєднання деякого ланцюга виявиться неможливим. В останньому випадку граф G не є планарним. Нехай побудоване деяке укладання підграфу G графу G . Сегментом S відносно G будемо називати підграф графу G, який має один з виглядів: – ребро e E , e u , v , таке, що e E , u, v V , G V , E ; – зв’язний компонент графу G – G , доповнений всіма ребрами графу G, інцидентними вершинам узятого компонента, і кінцями цих ребер. Вершину v сегмента S відносно G будемо називати контактною, якщо v V . Припустимою гранню для сегмента S відносно G називають грань Г графу G , що містить усі контактні вершини сегмента S. Через Г(S) будемо позначати множину припустимих граней для S. Назвемо α-ланцюгом простий ланцюг L сегмента S, що містить дві різні контактні вершини і не містить інших контактних вершин. Алгоритм . 1. Виберемо деякий простий цикл С графу G і укладемо його на площині; покладемо G С . 2. Знайдемо грані графу G і сегменти відносно G . Якщо множина сегментів порожня, то перейдемо до пункту 8. 3. Для кожного сегмента S визначимо множину Г(S). 4. Якщо існує сегмент S, для якого Г(S)= , то граф G не планарний. Кінець. 5. Якщо існує сегмент S, який має єдину припустиму грань Г, то перейдемо до пункту 7. 6. Для деякого сегмента S Г(S)>1. У цьому випадку вибираємо довільну припустиму грань Г. 7. Розмістимо довільний α-ланцюг L S у грань Г; замінимо G на G L і перейдемо до пункту 2. 8. Побудовано укладання G графу G на площині. Кінець. Кроком алгоритму будемо вважати приєднання до G α-ланцюга L. Приклад 3.8.3. Перевірити, чи граф G, зображений на рис. 3.44, є планарним. 2 3 1 5 6 4 Рис. 3.44. Граф для перевірки на планарність Розв’язання Укладемо спочатку цикл C=1-2-3-4-1, що розбиває площину на дві грані Г1 і Г2 . На рис. 3.45, а зображено граф G C і сегменти S1, S2, S3 відносно G з контактними вершинами, обведеними колами. Оскільки Г(Si) = {Г1, Г2} (i=1, 2, 3), то кожний α-ланцюг довільного сегмента можна укладати в будь-яку припустиму для нього грань. Помістимо, наприклад, α-ланцюг L=2-5-4 у Г1. Виникає новий граф G і його сегменти (рис. 3.45, б). При цьому Г(S1)={Г3}, Г(S2)={Г1, Г2}, Г(S3)={Г1, Г2, Г3}. 1 5 6 2 2 Г2 Г1 ~ G 4 1 3 2 S1 4 2 3 S2 4 4 S3 а 1 Г3 Г2 4 5 ~ G 2 15 3 1 6 2 Г1 S1 2 3 S2 4 4 S3 б Рис. 3.45. Алгоритм укладання графу (початок) Укладаємо L=1-5 у грань Г3 (рис. 3.46, а). Тоді Г(S2)={Г1, Г2}, Г(S3)={Г1, Г2}. Потім укладемо α-ланцюг L=2-6-4 сегмента S2 у Г1 (рис. 3.46, б). У результаті маємо Г(S2 )={Г 5}, Г(S3)={Г1 , Г2, Г5}. Нарешті, уклавши ребро 6-3 у Г5, а ребро 2-4 – наприклад, у Г1 (тоді Г(S3)={Г1}), одержуємо укладання графу G на площині (рис. 3.46, б). 1 6 2 2 Г4 Г3 Г2 5 4 Г1 2 3 ~ G 3 4 4 S2 S3 а 1 2 6 2 Г4 Г3 Г2 4 Г1 5 ~ G 6 1 2 5 Г5 3 3 S2 4 S3 4 6 3 б Рис. 3.46. Алгоритм укладання графу (завершення) Контрольні запитання до теми 3 1. Які типи неорієнтованих графів ви знаєте? 2. Які графи є об’єднанням та перетином двох графів? 3. Який граф називають доповненням до заданого? Скільки він має вершин і ребер? 4. Що називають степенем вершини? 5. Сформулюйте лему про естафету. 6. Який граф називають однорідним? Як обчислюють його кількість вершин і ребер? 7. Який граф називають повним і як його позначають? Як обчислюють кількість вершин і реберу ньому? 8. Який граф називають графом-циклом і як його позначають? Як обчислюють кількість вершин і ребер у ньому? 9. Який граф називають графом-колесом і як його позначають? Як обчислюють кількість вершин і ребер у ньому? 10. Який граф називають п-мірним кубом і як його позначають? 11. Який граф є двочастковим? 12. Який граф є повним двочастковим і як його позначають? Як обчислюють кількість вершин і ребер у ньому? 13. Сформулюйте критерій двочастковості графа. 14. Які способи подання графів ви знаєте? Які з них ефективніші щодо об’єму зайнятої пам’яті і які щодо швидкості пошуку? 15. Який спосіб подання графа є найефективнішим щодо перевірки на тип? 16. Який граф є зв’язним? 17. Що називають числом вершинної та реберної зв’язності простого графа? 18. Що є “вузькими місцями” простого графа? 19. Опишіть алгоритм визначення зв’язності графа. 20. Який граф називають ейлеровим? Сформулюйте необхідні і достатні умови того, що граф є ейлеровим. 21. Опишіть алгоритм Флері побудови ейлерового циклу. 22. Сформулюйте необхідні і достатні умови того, що граф має лише ейлеровий маршрут. 23. Який граф називають гамільтоновим? Чи існує критерій того, що довільний граф є гамільтоновим? 24. Чи існує гамільтоновий цикл у повному графі? 25. Сформулюйте задачу комівояжера. Який граф їй відповідає? 26. Опишіть алгоритм найближчого сусіда? Який розв’язок задачі комівояжера він знаходить? 27. Які умови існування гамільтонового циклу у простому зв’язному графі? 28. Яку структуру даних використовують при пошуку вглиб у графі? За яким принципом вона працює? 29. Опишіть алгоритм пошуку углиб у простому зв’язному графі. 30. Яку структуру даних використовують при пошуку вшир у графі? За яким принципом вона працює? 31. Опишіть алгоритм пошуку вшир у простому зв’язному графі. 32. Яка складність обох алгоритмів пошуку? 33. Які графи називають ізоморфними? 34. Опишіть алгоритм перевірки графів на ізоморфізм. 35. Як можна перевірити графи на ізоморфізм за їхніми матрицями інцидентності та суміжності? 36. Як можна перевірити графи на ізоморфізм за їхніми списками ребер та суміжності? 37. Який граф називають плоским? Планарним? 38. Сформулюйте і доведіть теорему Ейлера про плоскі графи. 39. Які графи називають гомеоморфними? 40. Сформулюйте теорему Куратовського і доведіть необхідність її умов. 41. Чи граф Петерсена є планарним? 4.1. Термінологія Орієнтовані графи (орграфи) використовують для моделювання ситуацій при зображенні інформаційних потоків, мережевому плануванні і плануванні завдань. Ми введемо стандартну термінологію з теорії орграфів і обговоримо систему планування і керівництва розробками ПЕРТ (англійською PERT – скорочено від Program Evaluation and Review Technique), яка була розроблена для допомоги в конструюванні підводного човна військово-морського флоту США. Основну частину часу присвятимо проблемі пошуку шляхів в мережах. Слово «мережа» вживають у випадках, коли в графі відокремлено певні вузли, їх називають полюсами і поділяють на вхідні та вихідні. Існування шляхів встановлюватимемо за допомогою матриць досяжності, опишемо ефективний алгоритм їх обчислення, відомий як алгоритм Воршелла. Обговоримо алгоритм Дейкстри, призначений для пошуку найкоротшого шляху в мережі від заданого вузла до решти, та алгоритм Флойда пошуку найкоротших шляхів між усіма парами вузлів у графі. Означення 4.1.1. Орієнтований граф (орграф) – це пара G=(V, E), де V – скінченна множина вузлів, E – множина орієнтованих ребер (названих дугами), причому будь-якій дузі інцидентна впорядкована пара вузлів з множини V (рис. 4.1, а). Орграф будемо називати простим, якщо він не має петель і співнапрямлених дуг (але може мати протилежно спрямовані дуги). Граф, що має орієнтовані та неорієнтовані ребра одночасно, називають змішаним (рис. 4.1, б). Орієнтований мультиграф – це пара G=(V,E), де V – непорожня скінченна множина вузлів, Е – сім’я впорядкованих пар елементів із V, тобто це граф, що містить кратні дуги та петлі (рис. 4.1, в). Прикладом орграфу є зображення транспортної мережі міста з урахуванням вулиць з одностороннім рухом. Дугу, яка з’єднує пару вузлів u і v орграфа G, позначають uv. Отже, для будь-якої пари вузлів u і v в простому орграфі знайдеться не більше однієї дуги uv з вузла u в v і не більше однієї дуги vи з вузла з v в и. а) б) в) Рис. 4.1. Графи: а) змішаний; б) орієнтований; в) орієнтований мультиграф. Означення 4.1.2. Шляхом довжини k в орграфі називають послідовність різних вузлів v0, v1,…, vk, кожна пара vі-1vі (і=1,..., k) якої утворює дугу (дуги можуть повторюватися). Довжиною шляху називають кількість дуг, з яких він складається. Контуром в орграфі називають послідовність вузлів v0, v1,…, vk, що утворює шлях, в якій перший вузол v0 співпадає з останнім vk, а інших повторювальних вузлів в ньому нема. Орграф називають безконтурним, якщо в ньому нема контурів. Шлях або контур називають простим, якщо він не містить повторюваних дуг. Від орграфів існує природній перехід до неорієнтованих графів, який полягає у «витиранні стрілок». Означення 4.1.3. Граф Н=(V, E), утворений з орграфа G=(V, E), якщо його кожну дугу замінити на ребро, називають основою орграфа. Якщо орграф простий, то це ще не означає, що простим є його граф-основа (протилежно спрямовані дуги переходять у пару кратних ребер). Поняття суміжності та інцидентності переносяться на орграф з його основи: кажемо, що дуга інцидентна вузлам, які вона з’єднує; вузли є суміжні, якщо вони з’єднані деякою дугою; дуги суміжні, якщо вони мають спільний вузол. Означення 4.1.4. Вузол и називають антецедентом вузла v, якщо існує дуга uv орграфа. Степенем (або валентністю) вузла v орграфа G називають кількість дуг (v) , які інцидентні цьому вузлу (петлю домовимося рахувати двічі). Півстепенем виходу вузла v називають число дуг (v ) орграфа, які виходять з v, а півстепенем входу цього вузла називають число дуг (v ) орграфа, які входять в неї. Через (G ) і (G ) позначимо мінімальні півстепені виходу і входу всіх вузлів орграфа G, а через (G ) і (G ) – їх максимальні півстепені виходу і входу. Якщо для вузла маємо (v ) =0, то його називають стоком орграфа, якщо (v ) =0, то – джерелом. Теорема 4.1. Нехай G – орграф з т дугами. Тоді (v ) (v ) m . vV vV Підграфи і породжені підграфи означають аналогічно до випадку неорієнтованих графів. Означення 4.1.5. Орграфи G=(VG, EG) і Н=(VH, EH) називають ізоморфними, якщо існує взаємно однозначне відображення між вузлами графів f: VG VH таке, що у G існує стільки дуг з початковим вузлом v1 і кінцевим v2, скільки дуг з початком у вузлі f(v1) та кінцем у f(v2) є в графі Н. Іншими словами, два орграфи є ізоморфними, якщо існує ізоморфізм між їхніми основами, який зберігає орієнтацію ребер. Поняття зв’язності на випадок орграфів переноситься дещо складніше. Для орієнтованого графа його вводять по-різному, залежно від того, чи враховують напрям дуг, тому отримують кілька зв’язностей. Означення 4.1.6. Орієнтований граф називають слабко зв’язним, якщо існує маршрут між будь-якими двома різними вершинами у відповідному йому неорієнтованому графі (тобто без урахування напрямку дуг). Орієнтований граф називають односторонньо зв’язним, якщо між будь-якими двома різними вузлами існує шлях з першого в другий або з другого в перший. З іншого боку, якщо для будьякої впорядкованої пари його вузлів існує шлях, який веде з першого в другий, то такий орграф називають сильно зв’язним. а) б) в) Рис. 4.2. Сильна (а), одностороння (б) і слабка зв’язність (в) Означення 4.1.7. Максимальний сильно зв’язний підграф орграфа називають його сильно зв’язною компонентою. Орграф називають мінімально зв’язним, якщо він є сильно зв’язним, але при вилученні будь-якої своєї дуги цю властивість втрачає. Ясно, що мінімальний зв’язний орграф не може мати ні петель, ні паралельних дуг. Теорема 4.2. Якщо мінімально зв’язний орграф має більше, ніж один вузол, то він містить не менше, ніж два вузли степеня 2. Означення 4.1.8. Ейлеровим шляхом (контуром) у слабко зв’язному орієнтованому мультиграфі називають простий шлях (контур), який містить усі дуги графа. Ейлеровим орграфом називають орграф, який містить ейлеровий контур. Теорема 4.3. Орієнтований слабко зв’язний мультиграф має ейлеровий контур тоді і лише тоді, коли півстепінь входу кожного вузла дорівнює його півстепеню виходу. Теорема 4.4. Орієнтований слабко зв’язний мультиграф має ейлеровий шлях тоді і лише тді, коли існують два такі вузли v1 і v2 , для яких (v1) (v1) 1 і (v2 ) (v2 ) 1, а для всіх інших вузлів півстепінь входу дорівнює півстепеню виходу. Означення 4.1.9. Гамільтоновим шляхом (контуром) у слабко зв’язному орієнтованому мультиграфі називають простий шлях (контур), який проходить через усі вузли графа. Гамільтоновим орграфом називають орграф, який містить гамільтоновий контур. Орграф називають повним (або турніром), якщо його основа є повним графом. Повним графом можна зображати результати тенісних чи інших спортивних турнірів, в яких усі учасники зустрічаються між собою, і в результаті зустрічі хтось виграє (немає нічиїх). Якщо вузли орграфа означають команди (чи гравців), то дуга uv означатиме, що команда и виграла в команди v. Як і у випадку неорієнтованих графів, характеризація гамільтонових орграфів є складною. Наведемо декілька достатніх умов гамільтоновості орграфів. Теорема 4.5. Нехай G – повний сильно зв’язний орграф з п вузлами. Тоді через кожен його вузол проходить контур довільної довжини k, де 3 k n . Наслідок. Сильно зв’язний турнір є гамільтоновим. Теорема 4.6. Нехай G – сильно зв’язний орграф з п вузлами, який не має паралельних дуг і петель. Якщо для кожного його вузла v виконується нерівність (v ) (v ) n , то цей орграф гамільтоновий. Наслідок. Нехай G – орграф з п вузлами, який не має паралельних дуг і петель. Якщо для нього виконується нерівність min( (G ), (G )) n / 2 1 , то цей орграф гамільтоновий. Теорема 4.4. Кожен турнір має гамільтоновий шлях. Безконтурні орграфи моделюють ситуації, коли задачі мають виконуватись у визначеному порядку (контур в такій інтерпретації означає, що та чи інша задача виконується з деякою періодичністю і передує сама собі). В задачі про планування завдань відповідний безконтурний орграф має кодову назву «система ПЕРТ». Приклад 4.1.1. Для отримання ступеня магістра біології студенту університету, зокрема, необхідно прослухати 8 курсів, які частково залежать один від одного (табл. 4.1). Зобразимо систему ПЕРТ, яка ілюструє пріоритетну структуру курсів. Розв’язання. Система ПЕРТ (рис. 4.3) – це орграф, який подає дану пріоритетну структуру. Його вузли – 8 курсів, позначені літерами латинського алфавіту. Дуги відображають вимоги, необхідні для засвоєння курсу. Таблиця 4.1. Попередні курси A Біотехнології B B Початковий курс біотехнології C C Цитологія H D Структура ДНК C E Ензимологія D, G F Дієтологія E G Генна інженерія C H Біологія людини Без вимог Рис. 4.3. Система ПЕРТ: пріоритетна структура курсів ▲ 4.2. Алгоритм топологічного сортування Означення 4.2.1. Послідовністю узгоджених міток вузлів безконтурного орграфа G=(V, E) називають мітки 1, 2,..., п вузлів, причому якщо uv – дуга орграфа, що йде від вузла и з міткою і до вузла v з міткою j, то і<j. Допустимо, що студент хоче визначити порядок, в якому йому треба вивчати предмети (приклад 4.1.1), враховуючи їхню залежність один від одного. Він може зробити це за допомогою алгоритму топологічного сортування, який створює послідовність узгоджених міток. Алгоритм топологічного сортування На початку роботи алгоритму антецеденти кожного вузла v записують в множину A(v). { for ( v V ) { обчислити A(v); label=0; while (є непозначені вузли, для яких A(v) ) { label= label+1; u= вузол з A(v) ; присвоїти мітку вузлу u; for (кожного непозначеного вузла v V ) A(v)=A(v)\{u}; } } Кожен вузол отримує чергову мітку в тому випадку, якщо він не має непозначених антецедентів. Приклад 4.2.1. Знайдемо послідовність міток для орграфа, зображеного на рис. 4.3. Розв’язання. Крок 0. Множина антецедентів має вигляд: A(A)={B}, A(B)={C}, A(C)={H}, A(D)={C}, A(E)={D, G}, A(F)={E}, A(G)={C}, A(H)= . Крок 1. Перший прохід циклу while. Призначити мітку 1 вузлу Н і викреслити його з решти множин А(v). A(A)={B}, A(B)={C}, A(C)= , A(D)={C}, A(E)={D, G}, A(F)={E}, A(G)={C}. Крок 2. Другий прохід циклу while. Призначити мітку 2 вузлу С і викреслити його з решти множин А(v). A(A)={B}, A(B)= , A(D)= , A(E)={D, G}, A(F)={E}, A(G)= . Крок 3. Третій прохід циклу while. У нас з’явився вибір: якому вузлу присвоїти чергову мітку? Залежно від нашого вибору отримаємо різні послідовності міток. Присвоїмо, наприклад, мітку 3 вузлу В і викреслимо його з А(v). A(A)= , A(D)= , A(E)={D, G}, A(F)={E}, A(G)= . Крок 4. Четвертий прохід циклу while. Ми знову маємо вибір. Присвоїмо мітку 4 вузлу А і викреслимо його з А(v). A(D)= , A(E)={D, G}, A(F)={E}, A(G)= . Крок 5. П’ятий прохід циклу while. Присвоїмо мітку 5 вузлу D і викреслимо його з А(v). A(E)={G}, A(F)={E}, A(G)= . Крок 6. Шостий прохід циклу while. Присвоїмо мітку 6 вузлу G і викреслимо його з А(v). A(E)= , A(F)={E}. Крок 4. Сьомий прохід циклу while. Присвоїмо мітку 7 вузлу Е і викреслимо його з А(v). A(F)= . Крок 8. Останній прохід циклу while. Присвоїмо мітку 8 вузлу F. Отже, один з можливих пріоритетних списків: H, C, B, A, D, G, E, F. Він дає нам порядок, в якому можна вивчати курси, зберігаючи необхідну послідовність. ▲ 4.3. Способи подання орієнтованих графів Означення 4.3.1. Матриця інцидентності (МІ) – матриця, у якій для кожної дуги вказані інцидентні їй вузли, тобто рядкам матриці відповідають номери вузлів, стовпцям – дуги графа. Для орієнтованого мультиграфа елементи МІ знаходять так: 1, якщо дуга vi v j виходить з вузла vi , 1, якщо дуга v v входить у вузол v , j i i mij 2 якщо дуга vi vi є петлею, якщо дуга не існує. 0, Приклад 4.3.1. Побудуємо МІ для орієнтованого мультиграфа, зображеного на рис. 4.4. Розв’язання. Перший стовпець показує напрям дуги а. Оскільки дуга а входить у перший вузол та виходить з другого, то елементи т11=-1, т21=1 і т.д. Отримаємо таку матрицю (табл. 4.2) ▲ Таблиця 4.2 a b c d e f g 1 -1 0 0 0 0 0 0 -1 1 1 2 1 1 1 1 -1 0 0 0 0 0 3 0 -1 -1 -1 1 1 1 0 0 0 4 0 0 0 -1 -1 0 0 h k m 1 -1 -1 Рис. 4.4. Орієнтований мультиграф Означення 4.3.2. Матрицю, побудовану на множині вузлів орграфа з урахуванням дуг, називають матрицею суміжності (МС), тобто МС – це квадратна таблиця розміром n×n, де n – кількість вузлів орграфа. Рядкам і стовпцям матриці відповідають вузли, а на перетинах рядків і стовпців записують числа, які показують, скільки дуг з’єднують відповідні вузли орграфа. Для орієнтованого мультиграфа елементи МС знаходять так: kij , vi v j E , mij , 0 , інакше, де vivj – дуга графа, kij – кількість дуг, що виходять з вузла vi та входять у вузол vj, тобто для орграфа матриця суміжності булева (але зазвичай несиметрична), для орієнтованого мультиграфу елемент тij дорівнює кількості дуг, які мають vi початковим вузлом, а vj – кінцевим. Приклад 4.3.2. Побудуємо МС для орієнтованого мультиграфа, зображеного на рис. 4.5. Розв’язання. Діагональні елементи МС (табл. 4.3) дорівнюють нулю через відсутність петель. Елемент т12=0, бо з вузла 1 у вузол 2 не входить жодної дуги. Елемент т14=2, бо з вузла 1 у вузол 4 входить дві дуги і т.д. ▲ Таблиця 4.3 1 2 3 4 1 0 0 0 2 2 1 0 3 0 3 0 1 0 2 4 1 0 0 0 Рис. 4.5. Орієнтований мультиграф Означення 4.3.3. Список пар (список дуг) – це спосіб подання орієнтованого графу, за якого пара [vi, vj ] відповідає дузі vivj. У перших двох стовпцях табл. 4.4 подано список пар орграфа, зображеного на рис. 4.6. Таблиця 4.4 Вузол Вузол Вузол Список вузлів виходу входу виходу входу 1 2 1 2, 3 1 3 2 3, 4 2 3 3 4 2 4 4 2, 4, 5 3 4 5 4 2 4 4 4 5 Рис. 4.6. Орграф У список записують в лексикографічному порядку всі існуючі дуги. Кількість пар дорівнює кількості дуг орграфа. Означення 4.3.4. Список суміжності – це спосіб подання орграфа, при якому для кожного вузла вказують список вузлів, у які він входить. Цей спосіб подання орграфу використовують тоді, коли кількість дуг значно менша, ніж кількість вузлів у степені 2 (m<<n2), а також для випадків динамічних графів, коли у графі постійно додаються нові вузли та дуги. Приклад 4.3.4. Побудуємо список суміжності для орграфа, зображеного на рис. 4.6. Розв’язання. Кількість стовпців списку суміжності дорівнює 2, кількість рядків –кількості вузлів графа (третій та четвертий стовпці табл. 4.4). ▲ Головний недолік такого способу подання графу – це неможливість швидкої перевірки наявності дуги vivj. 4.4. Шляхи в орграфах. Алгоритм Воршелла Орієнтовані графи успішно застосовують для схематичного зображення аероліній, які з’єднують міста всього світу, чи комунікаційних мереж між комп’ютерами. У таких мережах важливо знати послідовність виключень будь-якого з’єднання (дуги чи вузла) у всій мережі. Наприклад, якщо літак не може приземлитися для дозаправки в якомусь місті внаслідок несприятливих погодніх умов, то помилка в його переадресації грозить катастрофою: йому може не вистачити пального для досягнення неправильно призначеного аеропорту. Аналогічно, якщо один чи декілька ланцюгів у комп’ютерній мережі не працюють, то для деяких користувачів окремі сервери можуть виявитися взагалі недоступними. Так ми підійшли до задачі про пошук шляхів між довільною парою вузлів в орграфі. Означення 4.4.1. Матрицею досяжності називають матрицю M* M M 2 ... M n , в якій записані шляхи будь-якої довжини між вузлами. Якщо ми маємо дві булеві матриці одного розміру, то в результаті логічної операції диз’юнкції отримаємо матрицю, елементи якої є результатом застосування цієї операції до відповідних елементів двох матриць: a11 a A B 21 ... a m1 a12 a 22 ... a m2 ... a1n b11 b12 ... a 2 n b21 b22 ... ... ... ... ... a mn bm1 bm 2 ... b1n a11 b11 ... b2 n a 21 b21 ... ... ... ... bmn a m1 bm1 a12 b12 a 22 b22 ... a m 2 bm 2 a1n b1n ... a 2 n b2 n , ... ... ... a mn bmn ... а в результаті множення двох квадратних a11 a A B 21 ... a n1 матрицю С з елементами c ij a12 a 22 ... an2 n k 1 ... a1n b11 b12 ... a 2 n b21 b22 ... ... ... ... ... a nn bn1 bn 2 ... b1n ... b2 n ... ... ... bnn ( a ik b kj ) . Приклад 4.4.1. Обчислимо матрицю досяжності орграфа, зображеного на рис. 4.7. Розв’язання. Спочатку запишемо матрицю суміжності орграфа: Рис. 4.7. Орграф 0 0 M 0 0 1 0 0 0 1 1 . 0 0 0 0 1 0 Квадрат матриці дорівнює: 0 0 2 M MM 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 1 1 0 0 1 1 0 0 1 0 . 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 Зазначимо, що цифри 1 в цій матриці відповідають шляхам довжини 2 в орграфі, а саме: a-b-c, a-b-d і b-d-c. Подальші обчислення приводять до 3-го і 4-го степенів матриці М: 0 0 1 0 0 0 0 0 0 1 1 1 3 0 0 0 0 4 0 0 0 0 * 0 0 1 1 M , M . Отже, M . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 Відзначимо, наприклад, що цифра 1 у верхньому правому куті цієї матриці з’являється з матриці М2 і відповідає шляху a-b-d. ▲ Нехай G=(V, E) – орграф з п вузлами, а М – його матриця суміжності. В матриці М дуга, за означенням, є шляхом довжини 1. Булевий добуток матриці на саму себе позначають М2 – в цій матриці цифра 1 символізує наявність шляху довжини 2. За матрицею М3 можна визначити всі шляхи довжини 3, тобто в загальному випадку матриця Мk зберігає відомості про шляхи довжини k. Для великих орграфів обчислення матриці М* піднесенням до все більшого степеня матриці суміжності втомливе і неефективне. Зручніше це зробити за допомогою алгоритму Воршелла. Нехай G=(V, E) – орграф з вузлами v1, v2, …, vn. Алгоритм Воршелла генерує послідовність матриць W0=M, W1, W2, …, Wn, причому елемент Wk(і, j) матриці Wk (k 1 ), який стоїть на перетині і-го рядка і j-го стовпця, дорівнює 1 в тому і лише в тому випадку, коли існує шлях (довільної довжини) з вузла vі у вузол vj з внутрішніми вузлами з множини {v1, v2, …, vk}. Матриця W0 співпадає з матрицею суміжності М орграфа, а Wn – шукана матриця досяжності М*. Вдале поєднання циклів for надає алгоритму особливої елегантності. Послідовні проходи цього циклу (пронумеровані індексом k) обчислюють матриці W1, W2, …, Wn. Алгоритм Воршелла { W=M; for (k=1; k<= n; k++) { for (j=1; j<= n; j++) { W(i, j)= W(i, j) || (W (i, k ) & &W (k , j )) ; } } } Для кращого розуміння роботи цього алгоритму більш детально розглянемо його кроки. За кожен прохід циклу (пронумерований індексом k) алгоритм генерує матрицю Wk, використовуючи елементи попередньої матриці Wk-1. Щоб знайти і-й рядок матриці Wk, нам треба обчислити вирази: Wk-1(i, j) (Wk 1 (i, k ) Wk 1 (k , j )) (4.1) при різних значеннях j. Якщо Wk 1 (i, k ) 0 , то (Wk 1 (i, k ) Wk 1 (k , j )) 0 і значення виразу (4.1) співпадає зі значенням Wk-1(i, j). Інакше кажучи, і-й рядок матриці залишається незмінним. У тому випадку, коли Wk 1 (i, k ) 1 , треба обчислити вираз (Wk 1 (i, j ) Wk 1 (k , j )) , при цьому і-й рядок отримуємо за допомогою логічної операції диз’юнкції з поточних рядків і та k. Тому при обчисленні Wk діють так: 1. Беруть k-й стовпець матриці Wk-1. 2. Рядок з номером і (і=1, 2,..., п), у якого на k-му місці стоїть 0, переписують в і-й рядок матриці Wk. 3. Рядок з номером і (і=1, 2,..., п), у якого на k-му місці стоїть 1, логічно додають з k-м рядком матриці Wk-1. Приклад 4.4.2. За допомогою алгоритму Воршелла обчислимо матрицю досяжності орграфа, зображеного на рис. 4.8. Рис. 4.8. Орграф Розв’язання. Матриця W0 співпадає з матрицею суміжності М даного орграфа: 0 1 0 0 0 0 0 1 0 0 W0 1 0 0 1 0. 0 0 0 0 0 1 0 1 0 0 Обчислимо W1. Враховуючи 1-й пункт, ми розглядаємо 1-й стовпець (k=1) матриці W0. Керуючись вказівками 2-го пункту, скопіюємо рядки матриці W0 з номерами 1, 2 і 4 в матрицю W1 на ті ж місця: 0 1 0 0 0 0 0 1 0 0 W1 ? ? ? ? ? . 0 0 0 0 0 ? ? ? ? ? Далі згідно 3-го пункту рядок з номером диз’юнкції 1-го і 3-го рядків матриці W0: 0 1 0 0 W1 1 1 0 0 ? ? 3 матриці W1 отримуємо за допомогою 0 0 0 1 0 0 0 1 0 . 0 0 0 ? ? ? Знову застосуємо пункт 3 для обчислення 5-го рядка матриці W1 за допомогою диз’юнкції 1-го і 5-го рядків матриці W0: 0 1 0 0 0 0 0 1 0 0 W1 1 1 0 1 0 . 0 0 0 0 0 1 1 1 0 0 Тепер будуємо матрицю W2 за матрицею W1. Дивлячись на 2-й стовпець (k=2) матриці W1, бачимо, що рядки з номерами 2 і 4 копіюються в W2. 1-й рядок матриці W2 отримуємо логічним додаванням 2-го і 1-го рядків з W1, 3-й рядок – 2-го і 3-го рядків, 5-й рядок – 2-го і 5-го рядків: 0 1 1 0 0 0 0 1 0 0 W2 1 1 1 1 0. 0 0 0 0 0 1 1 1 0 0 Відзначимо, зокрема, що на перетині 3-го рядка і 3-го стовпця останньої матриці є 1 – це означає, що існує контур, який починається у вузлі 3 і проходить через один або обидва вузли з номерами 1 і 2. Глянувши на зображення графа (рис. 4.12), переконуємось, що дійсно існує контур довжини 3: 3-1-2-3. Аналогічно обчислюємо матрицю W3: 1 1 1 1 0 1 1 1 1 0 W3 1 1 1 1 0. 0 0 0 0 0 1 1 1 1 0 Оскільки з вузла 4 не виходить жодної дуги, то ми не можмо побудувати жодного шляху, який би проходив через нього, тому матриця W4 співпадає з W3. Крім того, в орграфі відсутні дуги, які ведуть у вузол 5, тому нема й шляхів, які б проходити через нього, тобто W5=W4 і W5=М*, бо граф має лише 5 вузлів.▲ 4.5. Найкоротший шлях між парою вузлів у зваженому орграфі. Алгоритм Дейкстри Розглянемо задачу пошуку найкоротшого шляху між парою вузлів у зваженому орграфі. Слово «найкоротший» тут цілком доречно, бо доволі часто ваги в орграфі – це відстані між пунктами. Типова ситуація, яку моделюють зваженим орграфом – це транспортна мережа (якою перевозять товари між пунктами) і комунікаційна мережа (якою передають інформацію). Означення 4.5.1. Найкоротшим шляхом називають шлях найменшої загальної ваги, що з’єднує вибрані вузли. Загальна вага дорівнює сумі ваг всіх дуг, що складають шлях. Відстанню від вузла и до вузла v називають загальну вагу найкоротшого шляху, що сполучає їх. Якщо шляху від u до v не існує, то відстань між ними прийнято вважати нескінченною і позначати символом . Означення 4.5.2. Ваговою матрицею називають матрицю W, елементи якої задають формулою: 0, якщо u v, w(u , v) , якщо u і v не з' єднані дугою, d , якщо uv є дугою ваги d . Алгоритм Дейкстри Розглянемо задачу пошуку найкоротшого шляху в мережі з невід’ємними дугами. Алгоритм, який запропонував нідерландський математик Дейкстра, дає змогу обчислити довжину найкоротшого шляху від початкового вузла s до заданого t та вказати вузли, через які він проходить. Він використовує таку ідею: замість пошуку найкоротшого шляху з s в t шукають найкоротші шляхи з s в усі інші вузли мережі, оскільки будь-який вузол може виявитись деяким проміжним вузлом найкоротшого шляху з s в t. По суті будують дерево найкоротших шляхів з s в усі вузли мережі. При пошуку найкоротшого шляху з s в t роботу алгоритму можна припинити, коли досягнемо вузла t. Перед виконанням алгоритму всі вузли та дуги мережі непереглянуті. Кожному вузлу при роботі алгоритму присвоюємо значення d(v), рівне найкоротшій віддалі з s в t, що включає лише позначені вузли. Крок 1. Початкові присвоювання. Присвоїмо d(s)=0 та d (v ) для всіх v s . Позначимо вузол s та присвоїмо u=s, де u – останній з позначених вузлів. Крок 2. Для кожного з непозначених вузлів v обчислюємо значення d (v) min (u, v) A {d (v); d (u ) wuv } , де wuv – довжина дуги (u, v). Якщо d (v ) для всіх непозначених вузлів, то кінець: у графі відсутній шлях з s в непозначені вузли, тобто шлях з s в t відсутній. Крок 3. Позначимо той з непозначених вузлів, для якого d (v) min . Позначаємо дугу, що веде до обраного вузла, та присвоюємо u=v. Мітки позначених вузлів називатимемо постійними. Крок 4. Якщо u=t, то кінець: найкоротший шлях з s в t знайдений. Інакше – перехід до кроку 2. Якщо треба побудувати дерево найкоротших шляхів з s у всі інші вузли, то дивимось: якщо на даний момент всі вузли позначені, то їх мітки дають довжини найкоротших шляхів, якщо ні, то роботу алгоритму продовжуємо (переходимо на крок 2 до непозначеного вузла), поки всі вузли не будуть позначені. Отже, алгоритм вибирає найкоротший шлях від вузла А до будь-якого вузла v і присвоює його довжину змінній d(v). Приклад 4.5.1. Знайти за допомогою алгоритму Дейкстри найкоротший шлях від вузла А графа, зображеного на рис. 4.9, до будь-якого іншого. Рис. 4.9. Зважений орграф Розв’язання. Вагова матриця має вигляд: A B C D E F A 0 2 3 B 0 1 4 C 0 5 W . D 0 2 E 0 1 F 0 Під час роботи алгоритму кожному вузлу орграфа присвоюється число d(v), рівне відстані від вузла А до v. Перед початком роботи d(v) співпадає з вагою дуги Аv, якщо така існує, або рівне у протилежному випадку. Проходячи вузли, ми будемо уточнювати значення d(v). На кожному кроці алгоритму позначають один вузол и, до якого вже знайдено найкоротший шлях від А і відстань d(и) до нього. Далі отримане значення d(и) позначеного вузла не змінюється. Для решти непозначених вузлів v число d(v) буде змінюватись з урахуванням того, що шуканий шлях до них від А буде проходити через останній позначений вузол и. Алгоритм завершиться в той момент, коли всі всеможливі вузли будуть позначені і отримають свої кінцеві значення d(v). Для кожного кроку алгоритму у відповідний рядок таблиці заносять позначений вузол, поточні значення d(v) і решту непозначених вузлів. При цьому напівжирним шрифтом виділяють найменше зі значень d(v) серед непозначених вузлів. Відповідний вузол треба позначити. Крім того, в таблиці всі значення d(v) для позначених вузлів відділені ламаною лінією. 1. Оскільки нас цікавлять найкоротші шляхи від вузла А, ми позначаємо його і використовуємо 1-й рядок вагової матриці W для визначення початкових значень d(v). Так отримуємо 1-й рядок табл. 4.5. Найменше число зі всіх d(v) серед непозначених вузлів – це d(В)=wAB=2. Таблиця 4.5 Крок Позначені Відстань до вузла Непозначені вузли вузли A B C D E F 0 A 0 3 2 B, C, D, E, F 2. Позначаємо вузол В, бо він є найближчим до А. Обчислюємо довжини шляхів, які ведуть від А до непозначених вузлів через В. Якщо нові значення d(v) виявляться меншими за старі, то змінюємо останні на нові. При цьому проході циклу шляхи АВ-С та А-В-Е мають відповідно ваги (використовуємо 2-й рядок вагової матриці): d(C)=d(B)+wBC =2+1=3, d(Е)=d(B)+wBE =2+4=6, в той час, як старі відстані до цих вузлів від А wAC і wAE були . Тому, заповнюючи 2-й рядок таблиці, ми замінимо d(С)=3, d(Е)=6. Крок 0 1 Позначені вузли A B Відстань до вузла A 0 0 B 2 2 C 3 D 3 3 E 6 Таблиця 4.5 (продовження) Непозначені вузли F B, C, D, E, F C, D, E, F 3. З непозначених вузлів С і D знаходяться найближче до А. Позначити можна будьякий. Візьмемо вузол D. Оскільки довжина шляху А-D-Е рівна d(Е)=wAD+wDE =3+2=5 (див. 1-й і 4-й рядки вагової матриці), поправляємо поточне значення d(Е) з 6 на 5. Заповнюємо 3-й рядок таблиці. Найменше значення d(v) серед непозначених на цей момент вузлів є у вузла С. Таблиця 4.5 (продовження) Крок Позначені Відстань до вузла Непозначені вузли вузли A B C D E F 0 A 0 3 2 B, C, D, E, F 1 B 0 2 3 6 3 C, D, E, F 2 D 0 2 3 5 3 C, E, F 4. Позначаємо вузол C. Тепер можна дійти до вузла F, йдучи шляхом A-B-C-F, значення d(F)=d(С)+wCF=3+5=8 (див. 3-й рядок вагової матриці). Заповнюємо 4-й рядок таблиці. Найменше значення d(v) серед непозначених на цей момент вузлів (Е і F) має вузол Е. Крок 0 1 2 3 Позначені вузли A B D C Відстань до вузла A 0 0 0 0 B 2 2 2 2 C 3 3 3 D 3 3 3 3 E 6 5 5 Таблиця 4.5 (продовження) Непозначені вузли F B, C, D, E, F C, D, E, F C, E, F 8 E, F 5. Позначаємо вузол Е. Тепер можна дійти до вузла F, йдучи шляхом A-D-E-F, що дозволить нам поправити d(F)=d(Е)+wEF =5+1=6 (див. 5-й рядок вагової матриці). Заповнюємо 5-й рядок таблиці. Таблиця 4.5 (продовження) Крок Позначені Відстань до вузла Непозначені вузли вузли A B C D E F 0 A 0 3 2 B, C, D, E, F 1 B 0 2 3 6 3 C, D, E, F 2 D 0 2 3 5 3 C, E, F 3 C 0 2 3 3 8 E, F 5 4 E 0 2 3 3 5 6 F 5 F 0 2 3 3 5 6 6. Позначаємо вузол F. Крок 0 1 2 3 4 5 Позначені вузли A B D C E F Таблиця 4.5 (закінчення) Непозначені вузли Відстань до вузла A 0 0 0 0 0 0 B 2 2 2 2 2 2 C 3 3 3 3 3 D 3 3 3 3 3 3 E 5 5 5 5 F 8 6 6 B, C, D, E, F C, D, E, F C, E, F E, F F З останньої таблиці ми можемо визначити довжини найкоротших шляхів від вузла A до будь-якого вузла – це числа, позначені напівжирним шрифтом у табл. 4.5, і вузли, із яких у даний безпосередньо потрапляє найкоротший шлях. Довжина найкоротшого шляху з A до F дорівнює 6 (у стовпці, що відповідає F, ця цифра позначена напівжирним). Сам шлях знаходимо так. Кінцевою є вузол F, у нього потрапляємо з вузла E (у рядку, що йому відповідає, вперше з’явилася ця цифра). У вузол E потрапляємо з D (у рядку, що йому відповідає, вперше з’явилася цифра 5, пізніше позначена напівжирним), в D з A (у рядку, що йому відповідає, вперше з’явилася цифра 3, пізніше позначена напівжирним), яка є початковою: A D E F , а найкоротший шлях від вузла A до вузла F такий: A D E F . Оскільки у розглядуваному прикладі більше непозначених вузлів нема, то ми побудували дерево найкоротших шляхів (ДНШ) з вузла A у всі інші (рис. 4.10). A 2 3 B D 2 1 C E 1 F Рис. 4.10. Дерево найкоротших шляхів з вузла A до всіх інших 4.6. Найкоротший шлях між усіма парами вузлів у зваженому орграфі. Алгоритм Флойда Ми розглянули задачу знаходження в орграфі найкоротшого шляху від деякого виділеного (початкового) вузла до будь-якого іншого. Розглянемо задачу пошуку в орграфі найкоротших шляхів між усіма парами вузлів. Звичайно, цю задачу можна розв’язати багатократним застосуванням алгоритму Дейкстри з послідовним вибором кожного вузла орграфа як початкового. Проте існує прямий спосіб розв’язування даної задачі, який використовує алгоритм Флойда. В цьому алгоритмі довжини дуг можуть бути від’ємними, однак довжина кожного контуру має бути невід’ємною. Ребро замінюємо парою орієнтованих в протилежних напрямках дуг з такими довжинами, як у нього. Нехай N={1,...,n} – множина вузлів графа, cij – довжина орієнтованої дуги (i, j) A, dik – довжина найкоротшого шляху з вузла i у вузол k, D(nxn) – матриця віддалей, R(nxn) – матриця шляхів. Алгоритм Флойда будується, виходячи з наступних міркувань. Нехай dik – найкраща поточна оцінка довжини найкоротшого шляху з вузла i у вузол k. Розглянемо довжину найкоротшого шляху з i в k, який проходить через певний проміжний вузол j: d ik ( j ) dij d jk . Якщо d ik ( j ) d ik , то біжуче значення d ik d ik ( j ) . Виходячи з цього алгоритм Флойда працює так: початкова оцінка довжини найкоротшого шляху становить cik, далі послідовно перевіряють всі проміжні вузли, розташовані між i та k; якщо довжина шляху, що проходить через деякий проміжний вузол, менша, ніж поточне значення оцінки, то це значення присвоюють оцінці. Цю процедуру повторюють для всіх пар вузлів до того часу, поки не будуть отримані значення найкоротших віддалей. Алгоритм Флойда Крок 1. Початкові присвоєння значень елементам матриць D та R: якщо вузли i та j з’єднані дугою, то dij(0) cij , якщо ні – то d ij(0) , i j ; d ii(0) 0 ; rij(0) i ; i j ; rii(0) 0 ; l=0 – параметр, що використовується для позначення базового вузла на кожній ітерації. Крок 2. l=l+1. Якщо l>n, то кінець: значення найкоротших віддалей між всіма парами вузлів знайдені та зберігаються в матриці D, а шляхи – в матриці R. В іншому випадку вузол l буде базовим. Викреслюємо базові стовпчик та рядок матриці D, а також ті її рядки та стовпчики, які мають значення , що знаходиться в базових рядку чи стовпчику. Крок 3. Перерахунок значень елементів матриць D та R. Для всіх i 1, n, k 1, n, i l k : d ik(l ) min{ d ik(l 1) , d il(l 1) d lk(l 1) } ; rik(l ) l , d ik(l 1) d il(l 1) d lk(l 1) і rlk(l 1) , якщо d (l 1) d (l 1) d (l 1) і ik il lk (l 1) ( l 1 ) ( l 1 ) dik dil dlk(l 1) . rik , rlk(l 1) l , rlk(l 1) l , d ik(l 1) , Отже, rik(l ) - номер вузла, який є перед вузлом k у поточному шляху з і до k. Розрахунки на цьому кроці доцільно виконувати з врахуванням викреслених рядків та стовпчиків. Викреслення полегшує розрахунки за вищенаведеними формулами та виключає непотрібні перерахунки значень. Порівнюємо кожен невикреслений елемент d ik(l ) та переписуємо перераховані значення в матриці наступної ітерації. Викреслені елементи переписуємо без змін. Переходимо до кроку 2. За допомогою матриці R (n ) найкоротший шлях між вузлами i та j визначають так. Нехай передостаннім вузлом цього шляху є вузол s, тобто rij( n) s . Тоді другий від кінця вузол на цьому шляху є передостаннім вузлом найкоротшого шляху з i до s, тобто збігається з ris(n) . Цю процедуру повторюємо доти, доки не буде пройдено у зворотному напрямі весь найкоротший шлях з вузла i до j. Матриця R (n ) відіграє ту ж роль, що і вектор вузлів в алгоритмі Дейкстри. Важливе практичне застосування цієї задачі, зокрема, таке. Нехай існують шляхи передачі інформації між відділами фірми і відомий час передачі одиниці інформації між кожною парою безпосередньо пов’язаних між собою пунктів. Визначити оптимальні шляхи передачі інформації для кожного з відділів можна, розв’язавши задачу методом Флойда. Приклад 4.6.1. Знайти найкоротші віддалі між всіма парами вузлів зваженого орграфа (рис. 4.11) за допомогою алгоритму Флойда: Рис. 4.11. Зважений орграф Розв’язання. Початкові присвоєння 0 2 3 3 0 1 1 1 2 (0) 0 ( 0) 2 0 2 2 D ,R . 0 3 3 3 0 3 4 5 5 0 4 4 4 0 1-а ітерація. Вузол l=1 є базовим. В матриці D(0) викреслюємо 1-й рядок і 1-й стовпець. Рядки 2, 3 мають у базовому стовпчику, і тому їх теж викреслюємо. ( 0) ( 0) ( 0) Залишаються елементи d 42 , d 43 , d 44 , діагональний не перераховуємо, тому (1) ( 0 ) (0 ) ( 0) d 42 min{ d 42 ; d 41 d12 } min{5;4 2} 2 , 5>2, (1) ( 0) ( 0) ( 0) d 43 min{ d 43 ; d 41 d13 } min{5;4 3} 5 . (1) Відповідно зміниться лише один елемент матриці R (1) : r42 1 . Отже: 0 1 1 1 0 2 3 3 2 (1) 2 0 2 2 (1) 0 D ,R . 3 3 0 3 0 3 4 2 5 0 4 1 4 0 2-а ітерація. Вузол l=2 є базовим. Викреслюємо з матриці D(1) 2-й рядок і 2-й стовпчик, а також 3-й рядок та 1-й та 4-й стовпець, оскільки їхні відповідні елементи в базових стовпчику і рядку рівні , та діагональні елементи. Отримаємо у результаті перерахунку: (2) (1) (1) (1) d13 min{ d13 ; d12 d 23 } min{3;2 2} 0 , 3>0, ( 2) ( 2) ( 2) (1) (1) (1) d 43 min{ d 43 ; d 42 d 23 } min{5;2 2} 4 , 5>4, r13 r43 2 (бо r23 не змінювався на першому кроці): 0 2 0 3 0 1 2 1 (2) 0 2 ( 2) 2 0 2 2 D ,R . 0 3 3 3 0 3 4 2 4 0 4 1 2 0 3-я ітерація. Вузол l=3 є базовим. Викреслюємо з матриці D(2) 3-й рядок і 3-й стовпчик, а також 1-й та 2-й стовпці, оскільки їх відповідні елементи в базовому рядку рівні , та діагональні елементи. Отримаємо у результаті перерахунку: (3) ( 2 ) ( 2) (2) d14 min{ d14 ; d13 d 34 } min{ 3;0 3} 3 , (3) ( 2) ( 2) ( 2) d 24 min{ d 24 ; d 23 d 34 } min{;2 (3)} 1 , 1 , ( 3) r24 3 (бо r34 не змінювався на першому та другому кроках). (3) Оскільки елемент d14 у результаті перерахунку зберіг попереднє значення, (3) значення r14 теж не зміниться: 0 1 2 1 0 3 2 0 2 3 2 1 ( 3 ) . , R 3 3 0 3 0 3 4 0 4 1 2 0 4-а ітерація. Вузол l=4 є базовим. Викреслюємо з матриці D(3) 4-й рядок і 4-й стовпчик. Отримаємо у результаті перерахунку: 0 2 (3) 0 D 4 2 (4) ( 3) (3) (3) d12 min{ d12 ; d14 d 42 } min{ 2;3 2} 2 , ( 4) (3) (3) ( 3) d13 min{ d13 ; d14 d 43 } min{0;3 4} 0 ( 4) (3) (3) (3) d 21 min{ d 21 ; d 24 d 41 } min{;1 4} 3 , 3 , ( 4) ( 3) (3) (3) d 23 min{ d 23 ; d 24 d 43 } min{ 2;1 4} 2 , (4) ( 3) ( 3) (3) d 31 min{ d 31 ; d 34 d 41 } min{ ;3 4} 1 , 1 , ( 4) ( 3) (3) (3) d 32 min{ d 32 ; d 34 d 42 } min{;3 2} 1 , 1 , ( 4) ( 4) r21 4 , r31 4 (бо r41 не змінювався на першому, другому та третьому кроках); ( 4) (1) (4) r32 1 , бо r32 1 (ми не можемо присвоїти r32 4 , бо r42 змінювався на першому кроці, тому присвоюємо його значення). ( 4) ( 4) ( 4 ) Оскільки елементи d12 , d13 , d 23 у результаті перерахунку зберігають попередні ( 4) ( 4) ( 4) значення, відповідні значення r12 , r13 , r23 не зміняться: 0 2 0 3 0 1 2 1 (4) 3 0 2 1 ( 4) 4 0 2 3 D ,R . 1 1 0 3 4 1 0 3 4 2 4 0 4 1 2 0 Розглянемо найкоротший шлях з вузла 2 до вузла 1: ( 4) його довжина становить d 21 3; за допомогою матриці R(4) визначаємо проміжні вузли. Випишемо в оберненому порядку вузли, через які він проходить. Кінцевий вузол ( 4) ( 4) 1; оскільки r21 4 , то в нього потрапляємо з вузла 4. Далі r24 3 і у вузол 4 ( 4) потрапляємо з 3. Нарешті, r23 2 – це початковий вузол і з нього потрапляємо у 3. Послідовність вузлів у зворотному порядку така: 1 4 3 2 , а найкоротший шлях від вузла 2 до вузла 1 такий: 2 3 4 1. Контрольні запитання до теми 4 1. 2. 3. 4. Які типи орієнтованих графів ви знаєте? Що називають шляхом і контуром в орграфі? Які орієнтовані графи є слабко зв’язними і які сильно зв’язними? Що називають ейлеровим шляхом (контуром) у слабко зв’язному орієнтованому мультиграфі? 5. Сформулюйте необхідні і достатні умови існування ейлерового контуру в слабко зв’язному орієнтованому мультиграфі. 6. Що називають гамільтоновим шляхом (контуром) у слабко зв’язному орієнтованому мультиграфі? 7. Що моделюють системою ПЕРТ? 8. Опишіть алгоритм топологічного сортування. Для чого його використовують? 9. Які способи подання орієнтованих графів ви знаєте? Перерахуйте їхні переваги і недоліки. 10.Що називають матрицею досяжності графа? Замиканням якого відношення на вершинах графа вона є? 11.Опишіть алгоритм Воршелла. Для чого його використовують? 12.Як будують вагову матрицю графа? 13.Опишіть алгоритм Дейкстри. Для чого його використовують і у яких графах? 14.Опишіть алгоритм Флойда. Для чого його використовують і у яких графах? 15.Як будують матриці віддалей і шляхів у алгоритмі Флойда? Що вони описують? 5.1. Вільні дерева У цій темі ми познайомимось з класом графів, названих деревами. Дерева заслуговують окремого і детального розгляду з двох причин. Вони є в деякому сенсі найпростішим класом графів і для них виконуються багато тверджень, які не завжди виконуються для графів у загальному випадку. Стосовно дерев багато доведень і міркувань виявляються набагато простішими. Висуваючи якісь гіпотези при розв’язуванні задач теорії графів, доцільно спочатку перевіряти їх на деревах. Дерева є найрозповсюдженішим класом графів, які застосовують у програмуванні, причому в найрізноманітніших ситуаціях. У цьому розділі ми розглянемо конкретні застосування дерев у програмуванні. Отже, дерева – природна модель, яка подає дані, організовані в ієрархічну систему. Пошук по дереву для виділення окремих предметів і сортування даних в дереві є важливими задачами в інформатиці. Означення 5.1.1. Лісом називають неорієнтований граф G=(V, E), якщо він ациклічний. Деревом (вільним деревом) називають неорієнтований граф G=(V, E), якщо він зв’язний і ациклічний. Іншими словами, деревом називають зв’язний ліс. Зауважимо, що прикметник «вільне» використовують тоді, коли треба підкреслити відмінність дерев від інших об’єктів, споріднених деревам: орієнтованих дерев, впорядкованих дерев і т.д. Назви підібрані природно: ліс є об’єднанням дерев. Теорема 5.1. Нехай G=(V, E) – граф з п вершинами і т ребрами. Необхідними і достатніми умовами, при яких він є деревом, є такі: будь-яка пара вершин в G з’єднана єдиним шляхом; G зв’язний і т=п-1; G зв’язний, і кожне його ребро є мостом (видалення хоч би одного його ребра порушує його зв’язність); G ациклічний, але якщо додати хоч би одне ребро, то в ньому з’явиться цикл. Еквівалентність більшості з цих умов встановлюється легко. Найскладніше зрозуміти другу з них. Приклад 5.1.1. Доведемо за допомогою індукції за кількістю вершин, що для дерева Т з п вершинами і т ребрами виконується співвідношення: т=п-1. Розв’язання. Оскільки дерево з єдиною вершиною взагалі не має ребер, то вказане твердження справедливе при п=1. Розглянемо дерево з п вершинами (і т ребрами), де п>1 і допустимо, що будь-яке дерево з k<n вершинами має k-1 ребро. Видалимо ребро з Т. За 3-ою властивістю дерево після цієї процедури перетвориться в незв’язний граф. Отримаємо дві компоненти зв’язності, жодна з яких не має циклів (інакше вихідний граф теж мав би цикли і не міг би бути деревом). Тому отримані компоненти зв’язності теж дерева. Позначимо їх через Т1 і Т2. Нехай п1, п2 – кількість вершин у деревах Т1, Т2 відповідно. Оскільки п1+п2=k+1, то п1< k+1 і п2< k+1. За допущенням індукції дерева Т1 і Т2 мають п1-1 та п2-1 ребер відповідно. Тому вихідне дерево мало (з урахуванням видаленого) (п1-1)+(п2-1)+1= k+1-1=k ребро, що і треба було довести. ▲ Нескладно довести, що в будь-якому зв’язному графі знайдеться підграф, який є деревом. Означення 5.1.2. Остовним (кістяковим) деревом називають підграф в G, який є деревом і включає в себе всі вершини G. Остовним (кістяковим) лісом називають підграф в G, який є лісом і включає в себе всі вершини G. Будують остовне дерево просто: вибирають довільне ребро графа і послідовно додають інші ребра, не утворюючи циклів, доти, поки не можна буде додати жодного ребра, не одержавши при цьому циклу. Завдяки прикладу 5.1.1, ми знаємо, що для побудови остовного дерева в графі з п вершин необхідно вибрати п-1 ребро. Остовний ліс утвориться, коли провести таку процедуру до кожної компоненти зв’язності незв’язного графа. Приклад 5.1.2. Знайдемо два різних остовних дерева в графі, зображеному на рис. 5.1. Рис. 5.1. Зв’язний граф Розв’язання. У цьому графі існує декілька остовних дерев. Одне отримуємо послідовним вибором ребер: a, b, d і f, інше – b, c, e і g (рис. 5.2). ▲ Рис. 5.2. Остовні дерева графа з рис. 5.1 Означення 5.1.3. Кількість ребер графа G=(V, E), невикористаних при побудові кістякового лісу, називають циклічним рангом (цикломатичним числом, числом Бетті вимірності 1) і позначають через (G ) : (G ) | E | | V | c(G ) , де |E|, |V| – це потужності множин ребер і вершин, с(G) – кількість компонент зв’язності графа. Коциклічним рангом називають число (G ) | V | c(G ) , яке дорівнює кількості ребер в остовному лісі, тобто (G ) (G ) | E | . 5.2 Пошук мінімального остовного дерева Означення 5.2.1. Мінімальним остовним деревом (МОД) називають остовне дерево з найменною загальною вагою. Остовні дерева будують, розв’язуючи задачу пошуку найкоротшого з’єднання: треба побудувати залізничну мережу, яка зв’язує деяку кількість міст. Відома вартість будівництва відрізків шляхів між будь-якою парою міст. Знайти мережу мінімальної вартості. На мові теорії графів нам треба у зваженому графі знайти МОД. На відміну від задачі комівояжера тут є ефективний алгоритм. Алгоритм пошуку мінімального остовного дерева (алгоритм Краскала) Алгоритм будує МОД у зваженому графі G=(V, E), послідовно вибираючи ребра найменшої можливої ваги до утворення остовного дерева. МОД зберігається в пам’яті комп’ютера як множина Т ребер. Розглянемо одну з можливих реалізацій алгоритму Краскала. Крок 1. Упорядкувати множину ребер у порядку зростання ваг: е1, е2,..., ет. Крок 2. Утворити розбиття множини вершин на одноелементні підмножини: {{v1}, {v2}, …, {vn}}. Крок 3. Вибирати таке чергове ребро з упорядкованої послідовності ребер, що його кінці містяться в різних множинах розбиття (це забезпечить відсутність простих циклів). Якщо вибрано ребро еі={vi, vj}, то множини розбиття об’єднати в одну множину. Крок 4. Якщо вже вибрано (п-1) ребро (у такому разі всі підмножини розбиття виявляться об’єднаними в одну), то зупинитися, бо вибрані ребра утворюють мінімальний остов. Інакше перейти до кроку 3. Алгоритм Краскала належить до жадібних алгоритмів. Так називають алгоритми оптимізації, які на кожному кроці вибирають найкращий із можливих варіантів. Приклад 5.2.1. В табл. 5.1 дана відстань в кілометрах між 5-ма селами A, B, C, D і E. Знайдемо мінімальне остовне дерево. Таблиця 5.1 A B C D E A - 13 3 9 9 B 13 - 11 11 13 C 3 11 - 9 7 D 9 11 9 - 2 E 9 13 7 2 - Розв’язання. Ребра вибираємо так: 1-е – ребро DE вагою 2, 2-е – ребро АС вагою 3, 3-є – СЕ вагою 7 (рис. 5.3). Рис. 5.3. Вигляд дерева після 3-х кроків Наступні по вазі ребра – AD, AE і CD, кожне з яких має вагу 9, однак яке б з них ми не додали, отримаємо цикл, тому перелічені ребра треба виключити з доступних для побудови дерева. Далі йдуть ребра BC і BD вагою 11, можна приєднати будь-яке з них, отримавши при цьому 2 різні МОД: {AC, BC, CE, DE} або {AC, BD, CE, DE} вагою 23 кожне. ▲ 5.3. Орієнтовані, впорядковані і бінарні дерева Орієнтовані та впорядковані дерева є абстракцією ієрархічних стосунків, які дуже часто зустрічаються як в практичному житті, так і в математиці й програмуванні. Орієнтоване дерево й ієрархія – це аналогічні поняття. 5.3.1. Орієнтоване (кореневе) дерево Переважно ми б хотіли мати дерева, які подають інформацію з урахуванням природної ієрархічної структури, такі, як, наприклад, генеалогічне дерево (рис. 5.4). На ньому показано деяких членів сім’ї Бернуллі, кожен з яких був відомим швейцарським математиком. Микола р. 1623 Якоб І р. 1654 Микола І р. 1662 Микола ІІ р. 1687 Йоганн І р. 1667 Микола ІІІ р. 1695 Даніель І р. 1700 Йоганн ІІ р. 1710 Рис. 5.4. Династія Бернуллі Означення 5.3.1. Орграф називають квазісильно зв’язним, якщо для довільної пари його вузлів w1 і w2 існує вузол v (який може збігатися з w1 чи w2), з якого існують шляхи до вузлів w1 і w2. Коренем називають вузол орграфа, якщо з нього існує шлях до кожного іншого вузла цього графа. Очевидно, що кожний сильно зв’язний граф є квазісильно зв’язний, але не навпаки. Кожен вузол сильно зв’язного орграфа є коренем. Також очевидно, що коли орграф має корінь, то він є квазісильно зв’язний; правильно і навпаки. Теорема 5.2. Орграф має корінь тоді і лише тоді, коли він квазісильно зв’язний. Означення 5.3.2. Орграф називають кореневим деревом (ордеревом), якщо він має корінь, і його основа є деревом. Вузли vi орграфа, для яких (vi ) 0 називають листками. Множину листків називають кроною, шлях з кореня до листка – гілкою. Висота ордерева – це довжина найдовшої гілки від кореня до листка. Рівнем вузла у ордереві називають довжину шляху від кореня дерева до нього. Сам корінь має рівень 0. Вузли одного рівня утворюють ярус ордерева. Глибина вузла кореневого дерева – це довжина єдиного шляху від неї до кореня дерева. Теорема 5.3. Нехай G=(V, E) – орграф з п>1 вузлами. Необхідними і достатніми умовами, при яких він є ордеревом, є такі: орграф має вузол w, з якого існує лише один шлях у кожен інший вузол орграфа; орграф є квазісильнозв’язним і втрачає цю властивість при вилученні будь-якої дуги; орграф є квазісильнозв’язним і має такий вузол w, для якого ( w) 0 і (v ) 1 для всіх інших вузлів орграфа; орграф має такий вузол w, для якого ( w) 0 і (v ) 1 для всіх інших вузлів цього орграфа, а основа орграфа не має циклів; орграф є квазісильнозв’язним, і основа його не має циклів. Означення 5.3.3. Остовним (кістяковим) ордеревом називають підграф в G, який є ордеревом і містить всі вузли G. Кожний зв’язний неорієнтований граф має остовне дерево. Виявляється, для орграфа справджується теорема, наведена нижче. Теорема 5.4. Орграф має остовне ордерево тоді і лише тоді, коли він квазісильно зв’язний. Доведення. Необхідність очевидна. Достатність. Нехай маємо орграф, який не є ордеревом. Вилучаючи з нього по одній дуги, які не руйнують його квазісильно зв’язності, отримаємо потрібне ордерево (див. теорему 5.3). Зобразимо генеалогічне дерево стисліше. Схема, наведена на рис. 5.5, є прикладом кореневого дерева. Загальновизнаною практикою при зображенні дерев є погодження про те, що корінь знаходиться вгорі і всі дуги орієнтовані згори до низу, тому стрілки можна не зображати, тобто подавати зв’язки ребрами. Рис. 5.5. Схема генеалогічного дерева Бернуллі Поряд з «рослинною» термінологією застосовують і «генеалогічну». Означення 5.3.4. Вузол v ордерева називають нащадком вузла u, якщо існує шлях з u в v (нащадки одного вузла утворюють піддерево); якщо ж довжина шляху з u в v дорівнює 1, то вузол v називають сином вузла u. Відповідно вузол u називають предком або батьком вузла v. Синів одного батька називають братами. Вузли, відмінні від листків, називають внутрішніми. Зрозуміло, що листки не мають синів (і знаходяться в самому низу ордерева). На рис. 5.6 зображено кореневе дерево висотою 3. Корінь дерева (предок для усіх), внутрішній вузол Батько (предок), внутрішній вузол Син (нащадок), внутрішній вузол Листки (нащадки) Рис. 5.6. Кореневе дерево висотою 3 Означення 5.3.5. Піддеревом ордерева називають вузол ордерева, розглянутий як корінь іншого ордерева, з відповідними ребрами. Кореневе дерево можна визначити рекурентним способом. Окремий вузол є кореневим деревом (він слугує і коренем такого дерева). Якщо Т1, Т2,..., Тk – незв’язні між собою дерева з коренями v1, v2,..., vk, то граф, який отримують приєднанням нового вузла v до кожного з вузлів v1, v2,..., vk окремою дугою, є деревом Т з коренем v. Вузли v1, v2,..., vk графа Т – це сини кореня v. Ми зображаємо таке дерево з коренем, розміщеним нагорі, і синами, розміщеними нижче, безпосередньо під коренем (рис. 5.7). Рис. 5.7. Еквівалентне означення ордерева 5.3.2. Упорядковані дерева Якщо відносний порядок піддерев Т1,...,Тk ордерева фіксований, то ордерево називають упорядкованим. Означення 5.3.6. Кореневе дерево, у якому сини кожного внутрішнього вузла впорядковано, називають упорядкованим. Таке ордерево зображають так, щоб сини кожного вузла були розміщені зліва направо. Орієнтовані і упорядковані орієнтовані дерева інтенсивно використовують у програмуванні. 1. Для подання виразів мов програмування, як правило, використовують упорядковані орієнтовані дерева. Приклад подання виразу a+b*c показаний на рис. 5.8, а. 2. 3. 4. 5. Для подання блочної структури програми і зв’язаної з нею структури областей визначення ідентифікаторів часто використовують орієнтоване дерево (може бути невпорядковане, бо порядок визначення змінних в блоці у більшості мов програмування вважається неістотним). На рис. 5.8, б показана структура областей визначення ідентифікаторів а, b, c, d, e, причому для відображення ієрархії використані вкладені області. Для подання ієрархічної структури вкладеності елементів даних і/чи операторів керування часто використовують техніку відступів, показану на рис. 5.8, в. Структура вкладеності каталогів і файлів у сучасних операційних системах є упорядкованим орієнтованим деревом. Переважно для зображення таких дерев застосовують спосіб, показаний на рис. 5.8, г. Різні «правильні дужкові структури» (наприклад, а(b(c(d(e)))) є упорядкованими орієнтованими деревами. а) б) в) г) Рис. 5.8. Приклади зображення дерев у програмуванні Той факт, що більшість систем керування файлами використовує орієнтовані дерева, відображається навіть в термінології, наприклад, «кореневий каталог диска». Оскільки у деревах зв’язки подають ребрами, графічні подання вільних, орієнтованих і упорядкованих дерев виявляються нерозрізняльними і потрібні уточнення, дерево якого класу зображено. У більшості випадків це ясно з контексту. Приклад 5.3.1. На рис. 5.9 подано три дерева, які зовні виглядають відмінними. Як упорядковані дерева вони дійсно всі різні: перше не дорівнює другому, друге – третьому, третє – першому. Як орієнтовані дерева перше дорівнює другому, але друге не дорівнює третьому. Як вільні дерева вони всі ізоморфні. 1 2 Рис. 5.9. Зображення дерев 3 5.3.3. k-арні дерева Означення 5.3.7. Кореневе дерево називають k-арним деревом, якщо кожний його внутрішній вузол має не більше, ніж k синів. Кореневе дерево називають повним k-арним, якщо кожен його внутрішній вузол має точно k синів. Теорема 5.5. Повне k-арне дерево з v внутрішніми вузлами містить n=k·v+1 вузлів. Використовують кореневі дерева у інформатиці, біології, менеджменті. Для застосування в інформатиці найважливіші є так звані двійкові (бінарні) дерева, тобто такі ордерева, в яких кожний внутрішній вузол має не більше двох синів. У ньому вниз від кожного вузла йде не більше, ніж два ребра. Означення 5.3.7. Збалансованим називають k-арне дерево висотою h, у якого усі листки розміщені на рівнях h або h-1. Ордерево називають ідеально збалансованим, якщо рівень всіх його листків є однаковим. Завершеним називають повне k-арне дерево, у якого усі листки розміщені на одному рівні. На рис. 5.10 та 5.11 зображено 3-арні та бінарні дерева. а) б) Рис. 5.10. 3-арні дерева: а) ідеально збалансоване; б) завершене а) б) Рис. 5.11. Збалансоване (а) та завершене (б) бінарні дерева Теорема 5.6. Якщо на кожному рівні r завершеного k-арного дерева міститься kr вузлів, то у ньому є kh листків, h kr r 0 внутрішніх вузлів, де h – висота ордерева. k h 1 1 всіх вузлів та k 1 h 1 kr r 0 k h 1 k 1 Якщо внутрішній вузол упорядкованого бінарного дерева має двох синів, то першого називають лівим, а другого – правим. Піддерево з коренем у вузлі, який є лівим сином вузла v, називають лівим піддеревом у цьому вузлі. Якщо корінь піддерева – правий син вузла v, то таке піддерево називають правим піддеревом у цьому вузлі (рис. 5.12). Праве піддерево Ліве піддерево Рис. 5.12. Упорядковане бінарне дерево Якщо виявилось, що якийсь вузол не має сина зліва, то його ліве піддерево називають нульовим деревом (тобто нульове дерево – це дерево без жодного вузла). Аналогічно, якщо у вузла відсутній правий син, то його праве піддерево буде нульовим. Приклад 5.3.2. Нехай Т – двійкове дерево, зображене на рис. 5.13, а. а) б) Рис. 5.13. Двійкові дерева Т і T Визначимо а) корінь Т; б) корінь лівого піддерева вузла В; в) листки Т; г) синів вузла С. Нарисуємо двійкове дерево T , отримане з Т переставленням лівих і правих піддерев у кожному вузлі. Розв’язання. а) А; б) D; в) G, H, I , J та Е; г) F. Двійкове дерево T подано на рис. 5.13, б. ▲ 5.4. Способи подання дерев Для дерев, так само як і для графів, найзрозумілішим і найпростішим для людини є графічний спосіб подання, хоч він непридатний для їх опрацювання на комп’ютері. Зазвичай кореневі дерева на рисунку зображають у вигляді сукупності точок, з’єднаних між собою лініями, причому корінь є найвищим вузлом на рисунку, його сини знаходяться нижче від нього, сини синів – ще нижче, і т.д. За графічного відображення бінарних дерев (k-арних рідко) має значення положення вузла, щоб відрізняти лівого та правого сина. Наприклад, бінарні дерева, зображені на рис. 5.14, є різними, оскільки у першому випадку (зліва) маємо справу з деревом, корінь якого має нульове праве піддерево, а у другому (справа) – ліве. Рис. 5.14. Відображення двох різних бінарних дерев, для яких порядок синів має значення Деревовидну структуру можна подавати іншими способами (рис. 5.15). Дерево можна зображати у вигляді, подібному до алгебраїчної формули, за допомогою дужок. Цей метод схожий з методом відображення за допомогою вкладених множин, якщо літери, які позначають множини, виписати в один ряд. Наприклад, дерево з рис. 5.15 можна подати у вигляді (A(B(E, F), C(D))). Нумерація розділів у книжці чи дослідницькій роботі також є одним із способів подання деревовидної структури. Її називають десятковою системою Д’юї за аналогією з класичною схемою у бібліотеках. Для цього ж дерева вона матиме такий вигляд: 1 A; 1.1 B, 1.1.1 E, 1.1.2 F; 1.2 С; 1.2.1 D. a) б) Рис. 5.15. Графічні способи подання дерева: а) вкладеними множинами; б) з використанням відступу Розглянуті способи можна застосовувати і до лісу дерев, а не лише одного дерева. Оскільки дерево є графом, то для нього можна застосовувати способи зберігання графів. Але матриці інцидентності та суміжності дерева будуть заповнені в основному нулями, тому ці способи для них є малоефективними. Cписки суміжності та дуг (ребер) є ефективними, причому за використання першого з них дерево вважають орієнтованим графом, у якому дуги спрямовані від кореня до листків. Розглянемо список суміжності дерева з рис. 5.15: Батько Сини A B,C B E,F C D Легко зауважити, що список у лівій частині буде містити батька, у правій – його синів. Очевидно, що права частина міститиме список елементів, довжина якого наперед невідома, окрім випадку заданого обмеження на кількість синів у внутрішніх вузлах дерева. Цю проблему можна вирішити, якщо розглядати дерево як орієнтований граф від листків до батька, тоді ми отримаємо наступний список суміжності: Син Батько B A C A E B F B D C Такий спосіб зручний для табличного подання інформації і часто використовується у базах даних. Існує інший спосіб, який надає змогу подавати k-арні дерева у вигляді бінарних. Інформацію у дереві записують за допомогою таблиці із трьох колонок – Вузол, Лівий син, Правий брат. Приклад 5.4.1. Приведемо ліс з двох ордерев (рис. 5.16) до бінарного вигляду. Рис. 5.16. Ліс Розв’язання. Переставимо зв’язки між вузлами, залишивши лише зв’язки між батьком та лівим сином і правим братом. Можна корені двох поданих ордерев вважати синами вузла з порожньою назвою (рис. 5.17, а). а) б) Рис. 5.17. Бінарне дерево Таким чином, результуюче дерево буде бінарним, і його можна відредагувати, нахиливши під кутом 45 градусів (рис. 5.17, б). Інформацію можна подати за допомогою табл. 5.2. ▲ Таблиця 5.2 Вузол Лівий син Правий брат A B D B C C K D E E H F F J G Ще одною причиною для приведення k-арного до бінарного є простий рекурсивний вигляд бінарного дерева, кожен вузол якого задається таким самим об’єктом у пам’яті комп’ютера, що зумовлює зручну обробку дерев. Наприклад, бінарне дерево (рис. 5.18) можна задати відповідною списковою структурою об’єктів (рис. 5.19). Рис. 5.15. Бінарне дерево Рис. 5.19. Спискова структура об’єктів Кожен з об’єктів містить дані (в нашому випадку назву вузлів), а також посилання на синів. Бінарні дерева також можуть бути збережені в запакованому масиві. Такий метод є ефективний щодо економії пам’яті і швидкості доступу. Якщо вузол має порядковий номер l, то його діти знаходяться за індексами 2l+1 та 2l+2, а батьківський вузол – за індексом [(l-1)/2]. Корінь дерева завжди поміщають на початок масиву і присвоюють нульовий індекс. Для дерева висотою h максимальна кількість елементів у масиві буде рівна 2h-1. Приклад 5.4.2. Запишемо бінарне дерево, зображене на рис. 5.20, як запакований масив елементів. Рис. 5.20. Бінарне дерево Розв’язання. Запакований масив елементів у ордереві подано в табл. 5.3. 0 a 1 b 2 c 3 4 f 5 d 6 e 7 8 9 10 11 k 12 j Таблиця 5.3 13 14 m Пояснення порожніх клітинок: 3 – немає лівого сина у b; 7, 8 – немає синів у відсутнього лівого сина; 9, 10 – немає синів у f; 13 – немає лівого сина у е. Частина елементів масиву буде порожньою, але, незважаючи на це, економія відбудеться за рахунок того, що ми зберігаємо лише дані масиву, а зв’язки між елементами обчислюємо за допомогою індексів і не потребуємо їх зберігати. ▲ 5.5. Обхід ордерев Означення 5.5.1. Об’єкт називають рекурсивним, якщо він містить сам себе чи його означено за допомогою самого себе. Означення повного бінарного дерева через рекурсію таке: а) ізольований вузол R – повне бінарне дерево; б) якщо А та В – повні бінарні дерева, то конструкція, зображена на рис. 5.21, – повне бінарне дерево. Рис. 5.21. Схема рекурсії Рекурсивне означення функції п! для невід’ємних цілих чисел має такий вигляд: а) 0!=1; б) якщо п > 0, то п!=п(п-1)!. Важливість рекурсії пов’язана з тим, що вона дає змогу означити нескінченну множину об’єктів за допомогою скінченного висловлювання. Проте найдоцільніше використовувати рекурсивні алгоритми тоді, коли розв’язувану задачу, обчислювану функцію чи оброблювані дані задано за допомогою рекурсії. Чимало задач можна моделювати з використанням кореневих дерев. Поширене таке загальне формулювання задачі: виконати задану операцію D з кожним вузлом ордерева. Тут D – параметр загальнішої задачі відвідування всіх вузлів або так званого обходу ордерева. Розглядаючи розв’язування цієї задачі як єдиний послідовний процес відвідування вузлів ордерева в певному порядку, можна вважати їх розміщеними один за одним. Опис багатьох алгоритмів істотно спрощується, якщо можна говорити про наступний вузол ордерева, маючи на увазі якесь упорядкування. Є три принципи впорядкування вузлів, які природно випливають зі структури ордерева. Як і саму деревоподібну структуру, їх зручно формулювати за допомогою рекурсії. Звертаючись до бінарного дерева, де R – корінь, А та В – ліве та праве піддерева (рис. 5.21), можна означити такі впорядкування: 1. Обхід у прямому порядку (preorder) або зверху вниз: R, А, В: a) відвідати корінь; b) відвідати ліве піддерево; c) відвідати праве піддерево. У такому порядку обходу кожен вузол відвідується до того, як будуть відвідані його сини (рис. 5.22, а). 2. Обхід у внутрішньому (симетричному) порядку (inorder) або зліва направо: А, R, В: a) відвідати ліве піддерево; b) відвідати корінь; c) відвідати праве піддерево. Кожен вузол відвідується між відвіданням лівого та правого сина. Такий порядок особливо часто застосовуються в бінарних деревах пошуку (розглянемо в 5.9), бо він дає можливість обходу вузлів за збільшенням їхніх порядкових номерів (рис. 5.22, б). 3. Обхід у зворотному порядку (postorder) або знизу вверх: А, В, R: a) відвідати ліве піддерево; b) відвідати праве піддерево; c) відвідати корінь. Кожен вузол відвідується лише після того, як будуть відвідані його сини (рис. 5.22, с). а) б) с) Рис. 5.22. Обходи ордерева: прямий (а), внутрішній (б), зворотний (с) На рис. 5.23 наведено прямий та зворотний порядки обходу ордерева. а) б) Рис. 5.23. Прямий (а) та зворотний (б) порядки обходу бінарного дерева Порядок обходу бінарного дерева можна зберегти безпосередньо в структурі даних. Для цього достатньо ввести додаткове поле в елементі спискової структури і зберегти в ньому вказівник на вузол, наступний за даним вузлом при обході ордерева. Подання ордерев у вигляді запакованих масивів також допускає зберігання порядку їх проходження (рис. 5.24). Для цього вводять додатковий масив, в який записують адресу вузла в основному масиві, наступного за даним вузлом. Такі структури даних отримали назву прошитих бінарних дерев, при цьому відповідно до порядку проходження вузлів розрізняють вправо прошиті, вліво прошиті і симетрично прошиті бінарні дерева. Вказівники або адреси, що визначають порядок обходу, називають нитками. Клітинку з адресою останнього вузла повного ордерева відзначають спеціальним символом, як і закінчення списку. Рис. 5.24. Подання симетрично прошитого бінарного дерева у вигляді масивів, номери 8-13 відсутні, бо вершини с, d і f не мають синів. 5.6. Математичні дерева. Польські вирази Поява мов програмування високого рівня була спричинена необхідністю розв’язувати задачі, що потребували значних рутинних обчислень. До них висунули вимоги максимального наближення форми запису обчислень до природної мови математики. Розглянемо зіставлення виразів (арифметичних, логічних тощо) ордеревам і побудову на цій основі різних форм їх запису. Приклад 5.6.1. Подамо у вигляді математичного дерева арифметичний вираз: b a * d e * f . c Розв’язання. Послідовність дій відтворено на рис. 5.25. Останнім зображено математичне дерево, яке подає заданий арифметичний вираз, його внутрішнім вузлам відповідають символи операцій, а листкам – операнди. Рис. 5.25. Подання арифметичного виразу за допомогою математичного дерева Обійдемо це ордерево, записуючи символи у вузлах у тому порядку, у якому вони зустрічаються за заданого способу обходу. Отримаємо такі три послідовності: у разі обходу у прямому порядку – префіксний (польський) запис *+а/bc-d*ef; у разі обходу у внутрішньому порядку – інфіксний запис а+b/с*d-e*f; у разі обходу у зворотному порядку – постфіксний (зворотний польський) запис abс/+def*-*. ▲ Зупинимось на інфіксній формі запису виразу. Без дужок вона неоднозначна: один запис може відповідати різним ордеревам. Наприклад, ордереву, зображеному на рис. 5.26, у разі обходу зліва направо відповідає той самий вираз а+b/с*d-e*f, що й ордереву на рис. 5.25, хоча на цих рисунках зображено різні ордерева. Щоб уникнути неоднозначності інфіксної форми, використовують круглі дужки щоразу, коли зустрічають операцію. Вираз з дужками, одержаний під час обходу ордерева у внутрішньому порядку, називають інфіксною формою запису. Отже, для ордерева з рис. 5.25 інфіксна форма така: ((а+(b/c))*(d-(e*f))), а для ордерева, зображеного на рис. 5.26, вона має вигляд: (a+(((b/(c*d))-e)*f)). Рис. 5.26. Подання виразу ордеревом Наведені міркування свідчать, що інфіксна форма запису виразів незручна. На практиці використовують префіксну та постфіксну форми, бо вони однозначно відповідають виразу й не потребують дужок. Ці форми запису називають польськими записами (другий – зі словом зворотний) на честь польського математика й логіка Яна Лукасевича. Приклад 5.6.2. Розглянемо логічний вираз p q ~ p q . Послідовні етапи побудови відповідного бінарного дерева зображено на рис. 5.27. Форми запису виразу наступні: інфіксна форма запису: (((pq)¬)~((p¬)(q¬))); польський запис: ~¬pq¬p¬q; зворотний польський запис: pq¬р¬q¬~. p Рис. 5.27. Побудова математичного дерева Правило 5.6.1. Для обчислення значення виразу в польському записі його проглядають справа наліво та знаходять два операнди разом зі знаком операції перед ними. Ці операнди та знак операції вилучають із запису, виконують операцію, а її результат записують на їхнє місце. Приклад 5.6.3. Обчислимо значення виразу в польському записі (стрілка означає піднесення до степеня) +–*235/234. Розв’язання. За сформульованим правилом 5.6.1 на першому кроці виділимо 23, ці символи вилучимо й обчислимо 23=8; результат запишемо на їхнє місце: +–*235/84. Продовжимо обчислення. Динаміку процесу відображено в табл. 5.4. ▲ Таблиця 5.4 Вираз Крок 1 Виділені символи Виконання операції +–*235/234 23 23=8 +–*235/84 /84 8/4=2 *23 2*3=6 –65 6–5=1 +12 1+2=3 2 3 +–*2352 4 +–652 5 +12 3 6 Правило 5.6.2. Для обчислення значення виразу в зворотному польському записі його проглядають зліва направо та виділяють два операнди разом зі знаком операції після них. Ці операнди та знак операції вилучають із запису, виконують операцію, а її результат записують на їхнє місце. Приклад 5.6.4. Обчислимо значення виразу в зворотному польському записі 723*–493/+. Розв’язання. Динаміку обчислень відображено в табл. 5.5. ▲ Таблиця 5.5 Крок Вираз Виділені символи Виконання операції 1 723*–493/+ 23* 2*3=6 2 76–493/+ 76– 7–6=1 3 4 5 6 1493/+ 193/+ 13+ 4 14 93/ 13+ 14=1 9/3=3 1+3=4 5.7. Бектрекінг Опишемо загальний метод, який дає змогу значно зменшити обсяг обчислень в алгоритмах типу повного перебору всіх можливостей. Щоб застосувати цей метод, розв’язок задачі повинен мати вигляд скінченної послідовності (х1, …, хп). Головна ідея методу полягає в тому, що розв’язок будують поступово, починаючи з порожньої послідовності λ (довжини 0). Загалом, якщо є частковий (неповний) розв’язок (х1, …, хі), де і<п, то намагаємося знайти таке допустиме значення хі+1, щоб можна було продовжувати (х1,…, хі, хі+1) до одержання повного розв’язку. Якщо це допустимо, але ще невикористане значення хі+1 існує, то долучаємо цю нову компоненту до часткового розв’язку та продовжуємо процес для послідовності (х1, ..., xi, xi+1). Якщо такого значення хі+1 немає, то повертаємося до попередньої послідовності (х1, ..., xi-1) і продовжуємо процес, шукаючи нове, ще невикористане, значення хі. Тому процес називають бектрекінгом (англ. backtracking – пошук із поверненнями). Роботу алгоритму можна інтерпретувати як процес обходу якогось ордерева. Кожен його вузол відповідає якійсь послідовності (х1, ..., xi), причому вузли, які відповідають послідовностям вигляду (х1, ..., хi, у ) – сини цього вузла. Корінь ордерева відповідає порожній послідовності. Виконується обхід ордерева пошуком углиб. Окрім того, задають предикат Р, означений на всіх його вузлах. Якщо P(v)=FALSE(F), то вузли піддерева з коренем у вузлі v не розглядають, і обсяг перебору зменшується. Предикат P(v) набуває значення F тоді, коли стає зрозумілим, що послідовність (х1,…, хi), яка відповідає вершині v, ніяк не можна добудувати до повного розв’язку. Проілюструємо застосування алгоритму бектрекінг на конкретних прикладах. Задача 5.1. Побудова гамільтонових циклів у графі. Починаємо з довільного вершини. Будуємо маршрут без повторення вершин, доки це можливо. Якщо вдалося пройти всі вершини, то перевіряємо, чи існує ребро, що з’єднує останню й початкову вершини цього маршруту. Якщо описаний процес у певний момент неможливо продовжити, то повертаємося на одну вершину назад і намагаємося продовжити побудову маршруту (без повторення вершин) іншим способом. Пошук усіх гамільтонових циклів у графі з п’ятьма вершинами (рис. 5.28, а) можна проілюструвати за допомогою дерева. Роботу алгоритму почато з одноелементної послідовності, бо в циклі вибір першої вершини неістотний. До розв’язків задачі у прямокутних рамках приписано відповідні гамільтонові цикли (рис. 5.28, б). Отже, замість побудови й аналізу 5! = 120 послідовностей довжиною 5, які проходять через вершини графа, ми розглянули лише 26 послідовностей довжиною від 1 до 5 (це кількість дуг у ордереві). а) б) Рис. 5.28. Побудова гамільтонових циклів у графі Задача 5.2. Розфарбовування графа в n кольорів. Нехай вершини графа позначено як а, b, с, ... . Спочатку розфарбуємо вершину а в колір 1, потім вершину b в той самий колір, якщо вона не суміжна з вершиною а, у протилежному випадку розфарбуємо вершину b в колір 2. Перейдемо до третьої вершини с. Використаємо для вершини с колір 1, якщо це можливо, якщо ні, то колір 2, якщо це можливо. Тільки якщо жоден із кольорів 1 і 2 не можна використовувати, розфарбуємо вершину с в колір 3. Рис. 5.29. Розфарбування графа в n кольорів Продовжимо цей процес, доки це можливо, використовуючи один з п кольорів для кожної нової вершини, причому завжди братимемо перший можливий колір зі списку кольорів. Досягнувши вершини, яку не можна розфарбувати в жоден з п кольорів, повертаємося до останньої розфарбованої, відміняємо її колір і присвоюємо наступний можливий колір зі списку. Якщо й це неможливо, то ще раз повертаємося до попередньої вершини, відміняємо її колір і намагаємося присвоїти новий колір, наступний можливий зі списку. Цей процес продовжуємо. Якщо розфарбування в п кольорів існує, то така процедура дає змогу знайти його. На рис. 5.29 зображено граф і процес присвоювання трьох кольорів вершинам із використанням алгоритму бектрекінг. Задача 5.3. Задача про п ферзів. Як п ферзів можна розмістити на шахівниці пxn, щоб жодні два ферзі не били один одного? Для розв’язання цієї задачі потрібно визначити n позицій на шахівниці так, щоб жодні дві позиції не були в одному рядку, в одному стовпці та на одній діагоналі. Діагональ містить усі позиції з координатами такі, що і+j=m для якогось т, або i-j=m (тут і – номер рядка, j – номер стовпця, m – ціле число). Починаємо з порожньої шахівниці. На (k+1)-у кроці намагаємося розмістити нового ферзя в (k+1)-у стовпці, причому в перших k стовпцях уже є ферзі. Перевіряємо клітинки в (k+1)-у стовпці, починаючи з верхньої. Шукаємо таку позицію для ферзя, щоб він не був у рядку та на діагоналі з тими ферзями, які вже є на шахівниці. Якщо це неможливо, то повертаємося до місця ферзя на попередньому k-у кроці та розміщаємо цього ферзя на наступному можливому рядку в цьому k-у стовпці, якщо такий рядок є, а якщо нема, то повертаємося до ферзя в (k-1)-у стовпці. Рис. 5.30. Задача про п ферзів Алгоритм бектрекінг для N=4 проілюстровано на рис. 5.30. Кожному вузлу ордерева на рис. 9.30 відповідає послідовність довжиною від 0 до 4. Її k-й член дорівнює номеру клітинки з ферзем у k-у стовпці. Наприклад, вузлам шляху, який веде до розв’язку, відповідають такі послідовності: λ, (2), (2, 4), (2, 4, 1), (2, 4, 1, 3). Задача 5.4. Сума елементів підмножин. Задано множину натуральних чисел (х1, х2,…, хn). Потрібно знайти її підмножину, сума елементів якої дорівнює заданому числу М. Починаємо з порожньої множини. Нагромаджуємо суму, послідовно добираючи доданки. Число з послідовності (х1, х2,…,хn) долучають до суми, якщо сума після додавання цього числа не перевищує М. Якщо сума настільки велика, що додавання будь-якого нового числа перевищує М, то повертаємось і змінюємо останній доданок у сумі. На рис. 5.31 проілюстровано алгоритм бектрекінг для задачі відшукання підмножини множини {31, 27, 15, 11, 7, 5} із сумою 39. Рис. 5.31. Сума елементів підмножин 5.8. Бінарні дерева пошуку Бінарне дерево пошуку забезпечує дуже зручний метод організації даних, який дозволяє легко знайти будь-які конкретні дані або виявити, що їх нема. Воно дозволяє уникнути послідовного перегляду усіх даних. У бінарному дереві пошуку кожному вузлу присвоєно значення, яке називають ключем. Ключ – це елемент якоїсь множини, на якій задано лінійний порядок, наприклад, алфавітний або числовий. Під час побудови бінарного дерева пошуку використовують його рекурсивну властивість, яку можна описати так. Кожен вузол розбиває дерево на два піддерева. Ліве дерево містить лише ключі, менші від ключа цього вузла, а праве – більші. Ця властивість повторюється для кожного вузла. Бінарні дерева пошуку є структурами даних, що підтримують більшість операцій з динамічними множинами: пошук елементів мінімального та максимального значення, попереднього та наступного елементу, додавання та видалення. 5.8.1. Алгоритм додавання елемента до бінарного дерева пошуку Для опису алгоритму додавання нового об’єкту до бінарного дерева пошуку вважають, що дерево містить один вузол – корінь. Якщо цього вузла не існує, тоді коренем буде перший елемент. Щоб додати новий об’єкт, необхідно виконати таку послідовність кроків: Крок 1. Почати з кореня. Крок 2. Якщо об’єкт менший, ніж ключ у вузлі, то перейти до лівого сина. Крок 3. Якщо об’єкт більший, ніж ключ у вузлі, то перейти до правого сина. Крок 4. Повторювати кроки 2 та 3, доки не досягнемо вузла, який не визначено (тобто його немає). Крок 5. Якщо досягнуто невизначеного вузла, то додати вузол з новим об’єктом як ключем. Приклад 5.8.1. Наведемо послідовні кроки додавання до бінарного дерева пошуку елементів: 21, 59, 35, 7, 15, 12, 5, 1, 70. Розв’язання. Послідовність кроків подана на рис. 5.32. а) б) в) г) д) е) є) ж) з) Рис. 5.32. Додавання елементів до бінарного дерева пошуку ▲ Приклад 5.8.2. Додамо елементи, що є рядками даними, до бінарного дерева пошуку: кава, лате, сік, лайм, гриб, чай, джем. Розв’язання. Послідовність кроків подана на рис. 5.33. а) б) в) г) д) е) є) Рис. 5.33. Додавання елементів до бінарного дерева пошуку ▲ 5.8.2. Алгоритм пошуку елемента в бінарному дереві пошуку Найпоширенішою операцією, яку виконуються з бінарним деревом пошуку, є пошук в ньому певного ключа. Окрім цього, ці дерева забезпечують пошук мінімального та максимального елементів. Щоб здійснити пошук вузла зі значенням z, необхідно виконати таку послідовність кроків: Крок 1. Почати з кореня. Крок 2. Якщо z дорівнює значенню вузла, що розглядається, то алгоритм завершено і елемент знайдено. Крок 3. Якщо z менше за значення вузла, що розглядається, то переходимо у його ліве піддерево. Крок 4. Якщо z більше за значення вузла, що розглядається, то переходимо у його праве піддерево. Крок 5. Повторювати кроки 2-4, доки не досягнемо вузла з відповідним значенням z або покажемо, що його не існує. Приклад 5.8.3. Наведемо приклад пошуку вузла зі значенням 13 у дереві, зображеному на рис. 5.34. Розв’язання. 1. Розпочинаємо з кореня. Оскільки 13<15, то переходимо у ліве піддерево. 2. 13>6, переходимо у праве піддерево. 3. 13>7, переходимо у праве піддерево. 4. 13=13, тобто елемент знайдений. Отже, для пошуку елемента 13 у бінарному дереві, зображеному на рис. 5.37, необхідно пройти такий шлях: 15-6-7-13. ▲ Рис. 5.34. Бінарне дерево пошуку 5.8.3. Алгоритм видалення елемента з бінарного дерева пошуку При видаленні вершини із бінарного дерева пошуку можлива одна з трьох ситуацій. Випадок 1. Якщо у вузла z немає синів, то необхідно його видалити, не змінюючи структури дерева (рис. 5.35, а). Випадок 2. Якщо у вузла z є лише один син, то необхідно видалити цей вузол, зв’язавши його батька з його сином (рис. 5.35, б). Випадок 3. Якщо у вузла z є два сини, ми шукаємо або найбільший елемент у його лівому піддереві, або найменший елемент у його правому піддереві і переміщаємо його значення у вузол, який видаляємо. Потім ми видаляємо вузол, з якого копіювали значення. Ці два підходи рівнозначні, зокрема, у другому необхідно знайти наступний за z вузол y, у якого нема лівого сина. Видалити вузол y з позиції, де він перебував раніше, шляхом створення нового зв’язку між його батьком і сином. Замінити вершину z на y (рис. 5.35, в). а) б) в) Рис. 5.35. Видалення елемента в бінарному дереві пошуку Приклад 5.8.4. Видалити із бінарних дерев пошуку, зображених на рис. 5.36, а, та на рис. 5.36, б, вузли 4 та 5 відповідно. а) б) Рис. 5.36. Бінарне дерево пошуку Розв’язання. Вилучення вузла 4 із ордерева, зображеного на рис. 5.36, а, відповідає випадку 2 із алгоритму видалення елемента в бінарному дереві пошуку, тому замінюємо вузол 4 на вузол 2 (рис. 5.37, а). Вилучення вузла 5 з ордерева, зображеного на рис. 5.36, б, відповідає випадку 3 із цього ж алгоритму, тому замінюємо вузол 5 на вузол 7 (він не має лівого сина, рис. 5.37, б). ▲ а) б) Рис. 5.37. Видалення вузлів бінарного дерева пошуку Варто зауважити, що всі базові операції у бінарному дереві пошуку виконуються за один й той самий час – O(h), де h – висота дерева. 5.9. AVL-дерева Збалансоване бінарне дерево пошуку може розбалансуватись унаслідок додавання нових об’єктів. Проте процедура ребалансування (додавання об’єкта для відновлення збалансованості) не завжди доцільна, оскілька ця операція є доволі складною. Тому розглядають збалансованість з дещо послабленими вимогами, зокрема, означають AVL-дерево – бінарне дерево, у якому висоти двох піддерев кожного з його вузлів відрізняються не більше, ніж на одиницю. Винахідниками AVL-дерев (1962) є два радянські математики, Адельсон-Вельський і Ландіс, на честь яких ці дерева одержали свою назву. Для AVL-дерев існує дуже ефективна процедура ребалансування. Зазначимо, що висота AVL-дерева незалежно від кількості вузлів ніколи не перевищує висоту збалансованого дерева більше, ніж на 45%. Г.М. Адельсон-Вельський і Є.М. Ландіс довели теорему, згідно з якою висота h AVL-дерева з n ключами лежить в діапазоні від log2(n + 1) до 1.44 log2(n + 2) - 0.325. А оскільки основні операції над двійковими деревами пошуку (пошук, додавання і видалення вершин) лінійно залежать від його висоти, то отримуємо гарантовану логарифмічну залежність часу роботи цих алгоритмів від кількості ключів, що зберігаються в дереві. 5.9.1. Балансування AVL-дерева Означення 5.9.1. Балансуванням вузла називають операцію, яка при різниці висот лівого і правого піддерев рівній 2, змінює зв’язку батько-син у піддереві даного вузла так, що ця різниця стає <=1, в інакшому випадку нічого не змінює. Зазначений результат виходить обертаннями піддерев даного вузла. Використовують 4 типи обертань: мале ліве обертання використовують тоді, коли праве піддерево b переважує (різниця між висотами піддерев b і L рівна 2) і висота його лівого сина С менша або рівна висоті правого сина R (рис. 9.38, а); тоді батька а обертають вліво; мале праве обертання використовують тоді, коли ліве піддерево b переважує (різниця між висотами піддерев b і R рівна 2) і висота його правого сина С менша або рівна висоті лівого сина L (рис. 9.38, б); тоді батька а обертають вправо; велике ліве (подвійне право-ліве) обертання використовують тоді, коли праве піддерево b переважує (різниця між висотами піддерев b і L рівна 2) і висота його лівого сина С більша за висоту правого сина R (рис. 9.39, а); тоді лівого сина с правого сина b обертають вправо, потім батька a вліво, у результаті c стає батьком дідуся і свого батька; а) б) Рис. 9.38. Малі ліве та праве обертання велике праве (подвійне ліво-праве) обертання використовують тоді, коли ліве піддерево b переважує (різниця між висотами піддерев b і R рівна 2) і висота його правого сина С більша за висоту лівого сина L (рис. 9.39, б); тоді правого сина с лівого сина b обертають вліво, потім батька a вправо, у результаті c стає батьком дідуся і свого батька. а) б) Рис. 9.39. Великі ліве та праве обертання У кожному випадку доволі просто довести, що операція приводить до потрібного результату і що повна висота зменшується не більше ніж на 1 і не може збільшитися. Також можна помітити, що кожне велике обертання є комбінацією двох малих обертань. Через умови балансування висота дерева О(log2 п), де п – кількість вузлів, тому додавання елемента вимагає O(log2 п) операцій. 5.9.2. Додавання та видалення вузлів Після додавання вузла в дерево деякі вузли можуть переважувати вправо чи вліво або стати чи залишатись повністю збалансованими. Проходження дерева в симетричному порядку має бути таким же, як і для початкового дерева. Дерево після перетворення має бути збалансованим. Алгоритм додавання вузла в AVL-дерево 1. Йти по шляху пошуку, поки не виявиться, що вузла немає в дереві. 2. Включити новий вузол і визначити показник збалансованості. 3. Пройти назад по шляху пошуку, визначаючи збалансованість. Якщо додаємо в ліве піддерево, то маємо 3 випадки: - якщо праве піддерево було довше, то стало збалансованим; - якщо був баланс, то ліве піддерево виросло, і потрібно перевірити балансування вище; - якщо ліве піддерево було довше, то маємо розбалансування. Якщо додаємо в праве піддерево, то маємо 3 випадки: - якщо ліве піддерево було довше, то стало збалансованим; - якщо був баланс, то праве піддерево виросло, і потрібно перевірити балансування вище; - якщо праве піддерево було довше, то маємо розбалансування. Алгоритм видалення вузла з AVL-дерева 1. Йти по шляху пошуку, поки не знайдемо вузол у дереві. 2. Видалити вузол і визначити показник збалансованості. 3. Пройти назад по шляху пошуку, визначаючи збалансованість. Ребалансування після видалення елемента схоже з ребалансуванням після додавання елемента і підпорядковується законам логіки (якщо ліве піддерево було довше, а ми видалили з правого, то це призведе до розбалансування і потрібно повернути піддерево вправо). 5.10. Червоно-чорні дерева Означення 5.10.1. Червоно-чорне (RB) дерево – це різновид бінарного дерева пошуку, вузли якого мають додаткові властивості (RB-властивості), зокрема, колір (червоний або чорний). Означення 5.10.2. Кількість чорних вузлів дерева від кореня до листка називають чорною висотою дерева. Червоно-чорні дерева (рис. 5.40) – різновид збалансованих дерев, в яких за допомогою спеціальних трансформацій гарантується, що висота дерева h не буде перевищувати O(log2n). Зважаючи на те, що час виконання основних операцій на бінарних деревах (пошук, видалення, додавання елемента) є O(h), ці структури даних на практиці є набагато ефективнішими, аніж звичайні бінарні дерева пошуку. У червоно-чорних деревах червоні і чорні вузли необов’язково чергуються. Рис. 5.40. Червоно-чорне дерево 5.10.1. Властивості. Застосування 1) 2) 3) 4) 5) Бінарне дерево є червоно-чорним, якщо воно має такі властивості: кожен вузол або червоний, або чорний; корінь дерева чорний; кожний листок (NIL) чорний; якщо вузол червоний, обидва його сини чорні; усі шляхи від кореня до листків мають однакову кількість чорних вузлів. Такі властивості надають червоно-чорному дереву додаткового обмеження: найдовший шлях з кореня до будь-якого листка перевищує найкоротший шлях не більше, ніж вдвічі. В цьому сенсі таке дерево можна назвати збалансованим. Зважаючи на те, що час виконання основних операцій з бінарними деревами пошуку залежить від висоти, таке обмеження гарантує їхню ефективність в найгіршому випадку, чого звичайні бінарні дерева гарантувати не можуть. Для того, щоб зрозуміти, чому перелічені властивості забезпечують існування такого обмеження, зазначимо, що в червоно-чорному дереві, відповідно до властивості 4 не існує такого шляху, на якому б зустрілись два червоні вузли поспіль. Найкоротший шлях складається з усіх чорних вузлів, а в найдовшому червоні та чорні вузли чергуються. З урахуванням властивості 5 отримуємо, що рівень будь-яких двох листків відрізняється не більше ніж удвічі. У деяких зображеннях червоно-чорних дерев, NIL-листки не наводяться, тому що вони не містять корисної інформації, але їхнє існування необхідне для забезпечення усіх властивостей. Всі операції над деревом, зокрема, додавання і видалення елемента, повинні зберігати перераховані властивості. Червоно-чорні дерева найбільш активно використовують на практиці як самобалансовані дерева пошуку. Зокрема, контейнери set і map в більшості реалізацій бібліотеки STL мови C++, клас TreeMap мови Java та багато інших реалізацій асоціативного масиву в різних бібліотеках основані на червоно-чорних деревах. Популярність червоно-чорних дерев пов’язана з тим, що на них часто досягається оптимальний баланс між ступенем збалансованості і складністю підтримки збалансованості. Зокрема, при порівнянні з ідеально збалансованими деревами часто виявляється, що останні мають занадто жорстку умову збалансованості і при виконанні операцій видалення з дерева багато часу витрачається на підтримання необхідної збалансованості. 5.10.2. Порівняння зі збалансованим AVL-деревом Нехай висота дерева h, мінімальна кількість вузлів п. Тоді: для AVL-дерева n(h)=n(h-1)+n(h-2)+1; оскільки n(0)=0, n(1)=1, п(h) росте як послідовність Фібоначі, то п(h)=О( h ); h для червоно-чорного дерева n(h) 2( h 1) / 2 O ( 2 ) . Отже, при тій же кількості листків червоно-чорне дерево може бути вищим за AVL-дерево, не більше ніж в log /log 2 1.388 разів. Оскільки червоно-чорне дерево, в гіршому разі, вище, пошук у ньому повільніший, але програш за часом не перевищує 39%. Додавання вимагає до 2-х обертань в обох видах дерев, однак через більшу висоту червоно-чорного дерева воно може займати більше часу. Видалення з червоно-чорного дерева вимагає до 3-х обертань, в AVL-дереві воно може потребувати кількості обертань до висоти дерева (до кореня), тому видалення з червоно-чорного дерева відбувається швидше, ніж з AVL-дерева. AVL-дерево в кожному вузлі зберігає різницю висот (ціле число від -1 до +1, для кодування потрібно 2 біта), а червоно-чорне дерево – колір (1 біт), тому останнє може бути економніше. Однак якщо враховувати, що в сучасних обчислювальних системах пам’ять виділяється кратною байтам, то дерева абсолютно однакові. На практиці в обох типах дерев використовують цілі числа, бо робота з бітами вимагає додаткових процесорних обчислень (однієї команди асемблера and % al 0x10000000). Проте є реалізації червоно-чорного дерева, які зберігають значення кольору в біті, наприклад Boost Multiindex. Мета зберігання кольору в біті – зменшення споживання пам’яті червоно-чорним деревом (оrdered indices node compression). Біт кольору в такій реалізації зберігається не в окремій змінній, а в одному з вказівників вузла дерева (цей прийом небезпечний виходом за межі доступної пам’яті) . 5.10.3. Основні операції Операції, які не пов’язані з модифікацією RB-дерева, не потребують коректив і повністю аналогічні відповідним операціям для бінарних дерев пошуку. Разом з тим, додавання або видалення елементу з червоно-чорного дерева може призвести до порушення RB-властивостей. Відновлення цих властивостей після модифікації дерева потребує порівняно невеликої кількості (O(log2 n)) операцій зі зміни кольору вершин та не більше як три операції обертання (дві при додаванні елементу). Це залишає часові параметри операцій додавання та видалення в межах O(log2 n), але ускладнює відповідні алгоритми. Додавання елемента Процедура починається аналогічно додаванню вузла в бінарне дерево пошуку та з фарбування його у червоний колір. Але якщо в бінарному дереві пошуку ми завжди додаємо листок, то в червоно-чорному дереві листки не містять даних, тому ми додаємо червоний внутрішній вузол з двома чорними синами на місце чорного листка. Подальші дії залежать від кольорів сусідніх вузлів. Зазначимо, що: властивість 2 (корінь дерева чорний) завжди зберігається; властивість 3 (усі листки чорні) порушується лише при додаванні червоного вузла, перефарбуванні чорного вузла в червоний або обертанні; властивість 4 (обидва сини будь-якого червоного вузла чорні) порушується лише при додаванні чорного вуза, перефарбуванні червоного вузла в чорний або обертанні; властивість 5 (всі шляхи від будь-якої вершини до листків містять однакову кількість чорних вузлів) може порушитися тільки при додаванні чорного вузла, перефарбуванні червоного в чорний (або навпаки) або при обертанні. На допоміжних діаграмах вузол, який додаємо, позначено N, первісного батька цього вузла позначено P, батька вузла P ("дідуся" N) позначено G. "Дядько" N (тобто вузол, який має спільного з P батька – G) позначено як U. Розглянемо такі випадки: Випадок 1. Новий вузол знаходиться в корені дерева. Тоді його необхідно пофарбувати в чорний колір для забезпечення властивості 2, його синів перефарбувати в червоний, внуків – в чорний і т.д. Очевидно, що властивість 5 при цьому залишається справедливою. Випадок 2. Новий вузол додають на місце чорного листка, а батько нового вузла є чорним. Тоді його фарбують у червоний колір, додають нові чорні листки. Властивість 3 не порушена, дерево є коректним. Властивість 5 також зберігається, бо додавання не змінює кількості чорних вузлів на цьому шляху. Випадок 3. Новий вузол додають на місце чорного листка, а батько та дядько доданого вузла є червоними. Тоді ми можемо перефарбувати їх обох в чорні, а також перефарбувати дідуся в червоний (рис. 5.41). Тепер наш червоний вузол має чорного батька. Завдяки тому, що будь-який шлях через батька чи дядька повинен проходити і через дідуся, кількість чорних вузлів на шляху залишається незмінною. Однак батько дідуся (тобто прадідусь) може бути червоним вузлом, як тепер і дідусь. Якщо це так, слід повторити цю операцію рекурсивно. Рис. 5.41. Додавання елемента у випадку 3 Зауваження: В наступних випадках ми припускаємо, що вузол P є лівим сином G. Якщо P – правий син, то слова ліво та право в аналізі наступних випадків слід поміняти місцями. Випадок 4. Новий вузол додають на місце чорного листка, батько є червоним, але дядько чорним. До того ж, новий вузол – правий син свого батька, а батько, своєю чергою, лівий син свого батька. Тоді ми можемо провести ліве обертання (переставляння вліво правого піддерева у цьому вузлі), внаслідок якого новий вузол та його батько поміняються ролями (рис. 5.42). Подальші дії з колишнім батьком проводять відповідно до випадку 5. Зважаючи на те, що новий вузол та його батько є червоними, операція обертання змінює умову 4. Рис. 5.42. Додавання елемента у випадку 4 Випадок 5. Батько є червоним, але дядько чорним. До того ж, новий червоний вузол – лівий син свого батька, і батько є лівим сином свого батька. Тоді ми проводимо праве обертання навколо дідуся. В результаті колишній батько стає батьком і нового вузла, і свого колишнього батька (колишнього дідуся). Ми знаємо, що колишній дідусь є чорним, інакше батько не був би червоним. Щоб зберегти властивість 4, треба поміняти місцями кольори колишніх батька та дідуся (рис. 5.43). Легко бачити, що властивість 3 також виконується. Рис. 5.43. Додавання елемента у випадку 5 Метод видалення аналогічний. При видаленні вузла з двома листковими синами, як і в звичайному двійковому дереві пошуку, ми шукаємо або найбільший елемент у його лівому піддереві, або найменший елемент у його правому піддереві і переміщаємо його значення у вузол, який видаляємо. Потім ми видаляємо вузол, з якого копіювали значення. Одна з основних переваг червоно-чорних дерев полягає в тому, що процедуру балансування практично завжди можна виконувати паралельно з процедурами пошуку, бо алгоритм пошуку не залежить від атрибута кольору вузлів. Обертання піддерев не може виконуватись одночасно з пошуком, але при додаванні виконується не більше O(1) обертань. 5.11. В-дерева Розглянемо величезну базу даних, представлену у вигляді збалансованого ордерева. Очевидно, що ми не можемо зберігати все це ордерево в оперативній пам’яті, тому в ній зберігаємо лише частину інформації, а решту – на сторонньому носії (припустимо, на диску, швидкість доступу до якого набагато повільніша). Такі ордерева вимагатимуть від нас log2n звернень до стороннього носія, що при великих n дуже багато. Якраз цю проблему і покликані вирішити B-дерева. В-дерева – це один з видів збалансованих ордерев, що забезпечують ефективне збереження інформації на магнітних дисках та інших пристроях з прямим доступом. Структуру В-дерева застосовують для організації індексів у багатьох сучасних системах керування базами даних та для структурування (індексування) інформації на жорсткому диску (як правило, метаданих). Час доступу до довільного блоку на жорсткому диску дуже великий (порядку мілісекунд), бо він визначається швидкістю обертання диска і переміщення головок. Тому важливо зменшити кількість вузлів, які розглядають при кожній операції. Використання пошуку по списку кожного разу для знаходження випадкового блоку могло б привести до надмірної кількості звертань до диска внаслідок необхідності здійснення послідовного проходу по всіх його елементах, попередніх заданому, тоді як пошук у В-дереві, завдяки властивостям збалансованості та високої розгалуженості (можливості кожного вузла дерева посилатися на більшу кількість вузлів-нащадків), дозволяє значно скоротиити кількість таких операцій. Відносно проста реалізіція алгоритмів і існування готових бібліотек (в тому числі і для С++) для роботи зі структурою В-дерева забезпечують популярність застосування такої організації пам’яті в найрізноманітніших програмах, які працюють з великими об’ємами даних. В-дерева схожі на червоно-чорні, різниця в тому, що у В-дереві вузол може мати багато синів, на практиці до тисячі, залежно від характеристик використовуваного диска. B-дерево було розроблене у 1972 році Рудольфом Байером та Едвардом МакКрейтом. Воно є ідеально збалансованим, тобто рівень всіх його листків є однаковим. В-дерево володіє такими властивостями (рис. 5.44): кожен внутрішній вузол, крім кореня, містить не менше t-1 ключів і має принаймні t синів; якщо дерево не є порожнім, корінь повинен містити хоча б один елемент (t називають мінімальним ступенем, цей параметр є не меншим 2, а переважно приймає значення від 50 до 2000); t – найменша кількість синів серед усіх внутрішніх вузлів, крім кореня; кожен внутрішній вузол, крім кореня, містить не більше ніж 2t-1 ключів і 2t синів у внутрішніх вузлах; корінь містить від 1 до 2t-1 ключів (якщо дерево не порожнє) і від 2 до 2t синів при висоті дерева більшій 1; ключі в кожному вузлі впорядковані у неспадному порядку для швидкого доступу до них; всі листки знаходяться на одному рівні, яка і є висотою дерева. У листків нащадків нема. Будь-який вузол, який містить ключі k1,…, kn, містить п+1 нащадків, при цьому перший син і всі його нащадки містять ключі з інтервалу (-∞, k1); для 2 i n і-й син і всі його нащадки містять ключі з інтервалу (kі-1, kі); (п+1)-й син і всі його нащадки містять ключі з інтервалу (kп, ∞). Таким чином, ключі вузла задають діапазон для ключів його нащадків. Рис. 5.44. В-дерево Означення 5.11.1. Висота h B-дерева з n≥1 вузлами і мінімальним ступенем t≥2 не перевищує log t (( n 1) / 2) , тобто h ≤ log t (( n 1) / 2) . 5.11.1. Пошук у B-дереві Пошук в B-дереві дуже схожий з пошуком в бінарному дереві, тільки тут ми повинні зробити вибір шляху до сина не з двох варіантів, а з декількох. В іншому нема жодних відмінностей. Нехай ми шукаємо значення х у В-дереві. Алгоритм пошуку буде таким: 1. Починаємо з кореня. 2. Якщо х – один з ключів даного вузла, то ключ знайдено, завершуємо пошук. Інакше знаходимо пару ключів z та y, таких, що x лежить в інтервалі від z до y. 3. Ідемо до сина між z та y. 4. Повертаємось до кроку 2. 5. Якщо ми дійшли до листка і х немає серед ключів, то такого значення в дереві не міститься, завершуємо пошук. На рис. 5.45 показано пошук ключа 27 у В-дереві (t=3). Пояснимо ілюстрацію (і відповідно стандартний алгоритм пошуку): 1. Йдемо по ключах кореня, поки вони менші необхідного – дійшли до 31. 2. Спускаємося до сина, який знаходиться лівіше цього ключа. 3. Йдемо по ключах нової вершини, поки вони менші 27 – знайшли 27 і зупинилися. Рис. 5.45. Пошук ключа у В-дереві (t=3) 5.11.2. Додавання ключа На відміну від пошуку, операція додавання істотно складніша, ніж в бінарному дереві, оскільки просто створити новий листок і вставити туди ключ не можна, бо порушаться властивості B-дерева. Також вставити ключ у вже заповнений листок неможливо, тому необхідна операція розбиття вузла на два. Алгоритм додавання ключа 1. Знаходимо у дереві листок, в якому мав би знаходитись даний ключ. 2. Якщо у вузлі менше 2t-1 ключів, то додаємо ключ в даний вузол. 3. У протилежному випадку (якщо листок був заповнений, тобто в ньому знаходилося 2t-1 ключів) – знаходимо медіану у ключах, медіану додаємо до батьківського вузла, з чисел зліва та справа від медіани створюємо два нові вузли. 4. Якщо у батьківському вузлі кількість ключів перевищує 2t-1, повторюємо крок 3 аж до кореня (якщо розбивається корінь, то з’являється новий корінь, і висота дерева збільшується). Нехай треба додати послідовність елементів 1, 2, 3, 4, 5, 6, 7 у В-дерево з максимальною кількістю ключів у вузлі, рівною 2. Червоним кольором на рис. 5.46 виділяємо елементи, які додаємо на поточному кроці. Додавання елемента 3 створить переповнення, тому елемент з середньої позиції (2) піднімається догори і створює новий вузол – корінь В-дерева, якому підпорядковуються два листки. Додавання елемента 5 знову створить переповнення, тому елемент з середньої позиції (4) піднімається догори у батьківський вузол. Додавання елемента 7 теж створить переповнення, тому елемент з середньої позиції (6) піднімається догори у батьківський вузол, з якого внаслідок переповнення виділяється ключ 4 і створює новий вузол – корінь В-дерева. Як і у випадку звичайних бінарних дерев, додавання здійснюється за один прохід від кореня до листка. На кожній ітерації (в пошуках позиції для нового ключа від кореня до листа) ми розбиваємо всі заповнені вузли, через які проходимо (у тому числі листок). Таким чином, якщо в результаті для додавання потрібно розбити якийсь вузол, то ми впевнені, що його батько не заповнений! При додаванні елементів В-дерево росте догори – з’являється новий корінь, хоч новий елемент додають у листок дерева. Рис. 5.46. Додавання ключа до В-дерева На рис. 5.47 проілюстровано, як у дерево з рис. 5.45 додаємо ключ 15. У пошуках позиції для нового ключа ми наштовхуємося на заповнений вузол (7, 9, 11, 13, 16) (рис. 5.47, а). За алгоритмом розбиваємо його на два нові, при цьому 11 переходить у батьківський вузол. Далі ключ 15 вставляємо в другий з нових вузлів (рис. 5.47, б). Всі властивості B-дерева зберігаються! а) б) Рис. 5.47. Додавання ключа до В-дерева з рис. 5.45 5.12.3. Видалення ключа Видалення ключа з B-дерева ще громіздкіший і складніший процес, ніж додавання. Це пов’язано з тим, що видалення з внутрішнього вузла вимагає перебудови дерева в цілому, тобто певної перебудови вузлів-синів. Аналогічно додаванню необхідно перевіряти, що ми зберігаємо властивості B-дерева, тільки в даному випадку потрібно відстежувати, чи ключів є t-1 (тобто якщо з цього вузла видалити ключ, то він не зможе існувати). Алгоритм видалення ключа з листка Спочатку необхідно перевірити, скільки ключів знаходиться у листку (рис. 5.48). P CGM AB DEF JKL TX NO QRS UV YZ Рис. 5.48. Початкове В-дерево (t=3) а) Якщо в листку є більше за t-1 ключ, то видаляємо вказаний ключ і більше нічого робити не потрібно (рис. 5.49, а). б) Якщо в листку є рівно t-1 ключ, то перевіряємо, чи сусідні листки мають більше за t1 ключ. Якщо правий листок-сусід має більше за t-1 ключ, то видаляємо вказаний ключ, вибираємо у цьому листку-сусіді найменший ключ і переміщаємо його у батьківський вузол, а ключ, менший за нього, з вузла-батька переміщаємо на місце видаленого (рис. 5.49, б). Якщо лівий листок-сусід має більше за t-1 ключ, то видаляємо вказаний ключ, вибираємо у цьому листку-сусіді найбільший ключ і переміщаємо його у батьківський вузол, а ключ, більший за нього, з вузла-батька переміщаємо на місце видаленого. в) Якщо ж два листки-сусіди вихідного вузла-листка мають рівно по t-1 ключу, то видаляємо вказаний ключ і об’єднуємо вихідний вузол-листок з правим або лівим сусідом. Той ключ з вузла-батька, який розділяв двох колишніх сусідів, перемістимо в новоутворений вузол, очевидно, він буде в ньому медіаною (рис. 5.49, в). P CGM AB DE JKL TX NO QRS UV YZ а) видалення ключа F з листка В-дерева з рис. 5.50, у якого ключів більше за t-1=2 P CJM AB DG KL TX NO QRS UV YZ б) видалення ключа Е з листка попереднього В-дерева, у якого ключів рівно t-1=2, а правий сусід якого має ключів більше за t-1 (J переміщаємо у батьківський вузол, а G – на місце видаленого) P CM AB DJKL TX NO QRS UV YZ в) видалення ключа G з листка попереднього В-дерева, сусіди якого мають ключів рівно t- 1=2 (D об’єднуємо з KL, J переміщаємо в новоутворений вузол) Рис. 5.49. Видалення ключа з листка На рис. 5.50 показано видалення ключа 9 з В-дерева, зображеного на рис. 5.45 (випадок б). Рис. 5.50. Видалення ключа з листка у В-дереві з рис. 5.45 Алгоритм видалення ключа з внутрішнього вузла Якщо син, що передує ключу k, містить більше t-1 ключів, то знаходимо k1 – попередника k в піддереві внутрішнього вузла. Видаляємо його з вузла-сина і замінюємо k у батьківському вихідному вузлі на k1. Поступаємо аналогічно, якщо син, наступний за ключем k, має більше t-1 ключів (рис. 5.51, а, в). Якщо обидва (наступний і попередній) сини мають рівно по t-1 ключів, то об’єднуємо їх і видаляємо k з батьківського вузла (рис. 5.51, б). Якщо об’єднують два останніх сини кореня, то вони стають коренем, а попередній корінь звільняється. P CGL AB DE JK TX NO QRS UV YZ а) видалення ключа М з внутрішнього вузла В-дерева з рис. 5.51, а, один син якого (той, що передує ключу) має більше за t-1=2 ключів (М замінюємо на L – його попередника) P CL AB DEJK TX NO QRS UV YZ б) видалення ключа G з внутрішнього вузла попереднього В-дерева, два сини якого (попередній та наступний) мають рівно по t-1 ключу(об’єднуємо DE і IK) в) видалення ключа 11 з кореня В-дерева з рис. 5.47, наступний син якого має більше за t-1 ключів Рис. 5.51. Видалення ключа з внутрішнього вузла Застосування B-дерев має такі переваги. У всіх випадках використання простору вторинної пам’яті становить понад 50%. Із зростанням ступеня використання цієї пам’яті не відбувається зниження якості обслуговування. Довільний доступ до запису реалізують за допомогою малої кількості підоперацій (звернення до фізичних блоків). У середньому досить ефективно реалізують операції додавання та видалення записів; при цьому зберігається природний порядок ключів з метою послідовної обробки, а також відповідний баланс дерева для забезпечення швидкої довільної вибірки. Зауважимо, що дерево не потрібно додатково балансувати, оскільки забезпечується автоматична підтримка властивості збалансованості. Незмінна впорядкованість по ключу забезпечує можливість ефективної пакетної обробки. Основний недолік В-дерев – відсутність для них ефективних засобів вибірки даних (тобто методів обходу дерева), впорядкованих за відмінним від вибраного ключа. 5.11.4. Порівняння з червоно-чорними деревами Червоно-чорне дерево ізометричне 2-3-4 B-дереву 4-го порядку – В-дереву з мінімальним ступенем 2, в якому кожен вузол може мати від 1 до 3 значень і, відповідно, від 2 до 4 вказівників на синів. Кожен чорний вузол можна об’єднати з його червоними синами; результуючий вузол буде мати від одного до трьох ключів і від двох до чотирьох вказівників на синів. У такому В-дереві кожен вузол буде містити тільки одне значення, яке відповідає значенню чорного вузла червоно-чорного дерева з необов’язковим значеннями до і (або) після нього в тому ж вузлі, обидва з яких відповідають еквівалентним червоним вузлам червоно-чорного дерева. Один із способів побачити цю еквівалентність – «підняти» червоні вузли в графічному поданні червоно-чорного дерева так, щоб вони опинилися на одному рівні по горизонталі зі своїми батьками (чорними вузлами), утворюючи сторінку. У Вдереві (або в модифікованому графічному поданні червоно-чорного дерева) у всіх листкових вузлів рівень однаковий. Такий тип В-дерева є більш загальним, ніж червоно-чорне дерево, хоча, як видно, з одного такого В-дерева 4-го порядку можна отримати декілька червоно-чорних дерев. Якщо сторінка В-дерева містить тільки одне значення, даний вузол чорний і має двох синів. Якщо вона містить три значення, то центральний вузол є чорним, а кожен його сусід – червоним. Однак, якщо сторінка містить два значення, будь-який вузол може стати чорним в червоно-чорному дереві (і тоді другий буде червоним). 5.12. Подання дерев в програмах Подаючи дерева в програмах, можна використати розглянуте нами подання неорієнтованих та орієнтованих графів (див. п. 4.4). Крім того, варто підкреслити, що подавати дерева в програмах потрібно набагато частіше, ніж графи загального вигляду, а тому методи розв’язування такої задачі набагато більше впливають на практику програмування. 5.12.1. Подання вільних дерев Враховуючи особливі властивості дерев, можна запропонувати істотно ефективніші подання, ніж для графів загального вигляду. Означення 5.12.1. Нехай X = {1, 2, . . . , n} − множина вершин дерева. Для будьякого дерева T, побудованого на X введемо деякий код, який характеризує його однозначно. Позначимо через b1 першу висячу вершину в послiдовностi Х, а через w1 = (a1, b1) інцидентне їй ребро. Викреслимо з T ребро w1 i вершину b1. Отримаємо нове дерево T1. У T1 розглянемо першу висячу вершину b2 у послiдовностi Х та інцидентне їй ребро w2=(a2, b2). Викреслимо з T1 вершину b2 i ребро w2. Отримаємо дерево T2. Продовжуємо процедуру далi, поки не залишиться одне ребро (an−1, bn−1), яке сполучає двi вершини, що залишились. Тодi набiр σ(T) = [a1, a2, . . . , an−2] однозначно визначається за деревом T. I навпаки, за цим набором можна однозначно вiдновити дерево T. Набiр σ(T) називають кодом Прюфера дерева T. Зауважити, що існує всього одне дерево з двома вершинами – K 2 , тому інформацію про останнє ребро можна не зберігати, вона відновлюється однозначно. Отже, код Прюфера – це спосіб взаємно однозначного кодування помічених дерев з n вузлами за допомогою послідовності n-2 цілих чисел. Його запропонував німецький математик Хайнц Прюфер у 1918 році. Хайнц Прюфер (нім. Ernst Paul Heinz Prüfer; 1896 – 1934) – німецький математик, який працював в теорії абелевих групп, алгебраїчної теорії чисел, теорії вузлів і теорії Штурма-Ліувілля. Помер від раку легень. Розглянемо алгоритм побудови коду Прюфера для заданого дерева з n вершинами. На вхід подається список ребер. Вибирається листок дерева з найменшим номером, потім його видаляють з дерева, і до коду Прюфера додають номер вершини, зв’язаної з цим листком. Таку процедуру повторюють n-2 рази. В решті решт, у дереві залишиться лише 2 вершини, і алгоритм на цьому завершується. Номери останніх двох вершин в код не записують. Таким чином, код Прюфера для заданого дерева – це послідовність з n-2 чисел, де кожне число – номер вершини, зв’язаної з найменшим на той момент листком – тобто це число у відрізку [1, n]. Побудуємо послідовність int А[n-1] відповідно до алгоритму 5.1. Алгоритм 5.1. Побудова коду Прюфера дерева Вхід: Дерево Т(V, E) у будь-якому поданні, вершини дерева пронумеровані числами 1...n довільним чином. Вихід: Масив int А[n-1] – код Прюфера дерева Т. for (i=1; i<=n-1; i++) { v=min (kV && d (k ) 1); /*вибираємо вершину v – висячу вершину з найменшим номером */ А[i]=Г(v); // заносимо в код номер єдиної вершини, суміжної з v; V=V-v; // вилучаємо вершину v з дерева } За побудованим кодом можна відновити вихідне дерево (алгоритм 5.2). Крім коду нам потрібен список всіх вершин дерева. Ми знаємо, що код Прюфера складається з n-2 вершин, де n – число вершин у дереві. Тому ми можемо за розміром коду визначити кількість вершин у закодованому дереві. У результаті, на початку роботи алгоритма ми маємо код Прюфера розміром n-2 і масив всіх вершин дерева: [1, …, n]. Далі n-2 рази повторюємо таку процедуру: беремо перший елемент коду Прюфера, і в масиві з вершинами шукаємо найменшу вершину, якої нема в коді. Знайдена вершина і поточний елемент коду Прюфера складають ребро дерева. Дані вершини видаляємо з відповідних масивів і повторюємо описану вище процедуру, поки в коді не закінчаться елементи. В кінці роботи алгоритму в масиві з вершинами залишиться дві вершини, вони складуть останнє ребро дерева. Так отримаємо список всіх ребер закодованого дерева. Запишемо два набори σ(T) = [a1, a2, . . . , an−2] та X = {1, 2, . . . , n}. Беремо в Х першу вершину b1, якої немає в σ(T), розглядаємо ребро (a1, b1). Викреслюємо iз σ(T) a1, а iз Х – b1. Обираємо b2, тодi рисуємо ребро (a2, b2). Далi обираємо вершини і ребра, поки у σ(T) не залишиться жодної вершини. Алгоритм 5.2. Розпакування коду Прюфера дерева Вхід: Масив int А[n-1] of 1..n - код Прюфера дерева Т. Вихід: Дерево Т(V, Е), задане множиною ребер Е, вершини дерева пронумеровані числами 1..n. E= ; // спочатку множина ребер порожня; B=1..n; // множина невикористаних номерів вершин; for (i=1; i<=n-1; i++) { v=min (k B && j i : k! A[ j ]) ; /* вибираємо вершину v – невикористану вершину з найменшим номером, який не зустрічається в коді Прюфера */; E=E+(v, A[i]); // додаємо ребро (v, A[i]); B=B-v; // вилучаємо вершину v зі списку невикористаних; } Приклад 5.12.1. Записати для дерева, поданого на рис. 5.52 (числа у вершинах – це їх номери), код Прюфера. Розв’язання Першою висячою вершиною у множині вершин {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} є b1 = 3. Викреслимо з T вершину 3 i ребро (7, 3). Динаміку побудови коду Прюфера показано в табл. 5.6. Таблиця 5.6 № Вибрана Викрес Х σ(T) кро- висяча лене ку вершина ребро в вХ дереві 0 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, [] 12} 1 3 (7,3) {1, 2, 4, 5, 6, 7, 8, 9, 10, 11, [7] 12} 2 4 (9,4) {1, 2, 5, 6, 7, 8, 9, 10, 11, 12} [7, 9] 3 6 (1,6) {1, 2, 5, 7, 8, 9, 10, 11, 12} [7, 9, 1] 4 8 (7,8) {1, 2, 5, 7, 9, 10, 11, 12} [7, 9, 1, 7] 5 9 (2, 9) {1, 2, 5, 7, 10, 11, 12} [7, 9, 1, 7, 2] 6 10 (2, 10) {1, 2, 5, 7, 11, 12} [7, 9, 1, 7, 2, 2] 7 11 (7, 11) {1, 2, 5, 7, 12} [7, 9, 1, 7, 2, 2, 7] 8 7 (1,7) {1, 2, 5, 12} [7, 9, 1, 7, 2, 2, 7, 1] 9 1 (2,1) {2, 5, 12} [7, 9, 1, 7, 2, 2, 7, 1, 2] 10 2 (5,2) {5, 12} [7, 9, 1, 7, 2, 2, 7, 1, 2, 5] Залишилось останнє ребро (12, 5), інформацію про яке можна не зберігати, оскільки вона відновлюється однозначно. На рисунку числа на ребрах вказують порядок, в якому вибирають висячі вершини і вилучають ребра при побудові коду Прюфера. Рис. 5.52. Побудова коду Прюфера Код Прюфера – найекономніше щодо пам’яті подання дерева. Приклад 5.12.2. Відновити дерево, подане кодом Прюфера σ(T) = [7, 9, 1, 7, 2, 2, 7, 1, 2, 5]. Розв’язання Запишемо два набори σ(T) = [7, 9, 1, 7, 2, 2, 7, 1, 2, 5]; X = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}. Беремо в Х першу вершину b1 = 3, якої немає в σ(T), розглядаємо ребро (a1, b1) = (7, 3). Викреслюємо iз σ(T) a1 = 7, а iз Х – b1 = 3. Обираємо b2 = 4, тодi (a2, b2) = (9, 4), викреслюємо iз σ(T) a2 = 9, а iз Х – b2 = 4. Динаміку побудови дерева показано в табл. 5.7. Таблиця 5.7 № Вер- Верши- σ(T) Х кро- шина на в ку вХ σ(T) 0 [7, 9, 1, 7, 2, 2, 7, 1, 2, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5] 12} 1 3 7 [9, 1, 7, 2, 2, 7, 1, 2, 5] {1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12} 2 4 9 [1, 7, 2, 2, 7, 1, 2, 5] {1, 2, 5, 6, 7, 8, 9, 10, 11, 12} 3 6 1 [7, 2, 2, 7, 1, 2, 5] {1, 2, 5, 7, 8, 9, 10, 11, 12} 4 8 7 [2, 2, 7, 1, 2, 5] {1, 2, 5, 7, 9, 10, 11, 12} 5 9 2 [2, 7, 1, 2, 5] {1, 2, 5, 7, 10, 11, 12} 6 10 2 [7, 1, 2, 5] {1, 2, 5, 7, 11, 12} 7 11 7 [1, 2, 5] {1, 2, 5, 7, 12} 8 7 1 [2, 5] {1, 2, 5, 12} 9 1 2 [5] {2, 5, 12} 10 2 5 {5, 12} У множині Х залишилось останнє ребро (12, 5). 5.12.2. Подання впорядкованих орієнтованих дерев Будь-яке вільне дерево можна орієнтувати, призначивши один з вузлів коренем. Будь-яке ордерево можна впорядкувати. Для нащадків одного вузла (братів) упорядкованого дерева визначено відношення старший-молодший (лівий-правий). Будь-яке впорядковане дерево можна подати бінарним деревом, наприклад, провівши правий зв’язок до старшого брата, а лівий – до молодшого сина. Таким чином, достатньо розглянути подання в програмі бінарних дерев. Це спостереження пояснює, чому поданню бінарних дерев у програмах традиційно приділяється особлива увага при вивченні програмування. Позначимо через O(n) обсяг пам’яті, який займає подання бінарного дерева, де n – кількість вузлів. Найчастіше використовують такі подання бінарних дерев. 1. Спискові структури: кожен вузол подають записом типу N, який містить два поля (l і r) з вказівниками на адреси лівого і правого вузлів і ще одне поле і для зберігання вказівника на інформацію про цей вузол. Якщо вузол не має якогось сина, то в поля l чи r записуємо 0. Дерево подається вказівником на корінь, для цього подання O(n)=3n. Оскільки в бінарному дереві, як і в будь-якому іншому, m=n-1, то з 2n вказівників, які відводять для зберігання ребер, n+1 завжди зберігають значення 0, тобто половина зв’язків не використовується. 2. Прошиті бінарні дерева: кожен вузол і розміщується в масиві, так що всі вузли піддерева даного вузла записують після цього вузла. Разом з кожним вузлом зберігають індекс k вузла, який є першим вузлом правого піддерева даного вузла, для цього подання O(n)=2n. 3. Польський запис: аналогічно, але замість зв’язків фіксують «помічений степінь» d кожного і-го вузла (наприклад, 0 означає, що це листок, 1 – є лівий зв’язок, але нема правого, 2 – є правий зв’язок, але нема лівого, 3 – є обидва зв’язки). Для цього подання O(n)=2n. Якщо степінь вузла відомий з інформації, збереженої у самому вузлі, то його можна теж не зберігати. Такий спосіб переважно використовують для подання виразів. У цьому випадку O(n)=n. Приклад 5.12.3. Покажемо, як виглядають в пам’яті бінарні дерева в різних поданнях. У наведених нижче таблицях перша група стовпців відповідає полям спискових структур, друга – прошитим бінарним деревам, третя – польському запису з поміченими степенями. Умовні адреси – це цілі числа, порожній вказівник – 0, нумерація вузлів відповідає обходу у прямому порядку. 1. Бінарні дерева на рис. 5.14 зліва та справа. Вважаємо, що верхній вузол містить а, нижній b. Спискові структури Адреса 1 2 i a b l 2 0 r 0 0 Прошиті бінарні дерева i k a 0 b 0 1 2 a b 0 0 2 0 a b 2 0 Польський запис з поміченими степенями i d a 1 b 0 a b 2 0 2. Бінарне дерево на рис. 5.8, a. Спискові структури Адреса 1 2 3 4 5 i + a * b c l 2 0 4 0 0 r 3 0 5 0 0 3. Бінарне дерево на рис. 5.53. Спискові структури Адреса 1 2 3 4 5 6 7 8 9 i a b d e c f g h i l 2 3 0 0 6 0 0 9 0 r 0 5 4 0 0 7 8 0 0 Прошиті бінарні дерева i k + 3 a 0 * 5 b 0 c 0 Польський запис з поміченими степенями i d + 3 a 0 * 3 b 0 c 0 Прошиті бінарні дерева i k a 0 b 5 d 4 e 0 c 0 f 7 g 8 h 0 i 0 Польський запис з поміченими степенями i d a 1 b 3 d 2 e 0 c 1 f 2 g 2 h 1 i 0 Рис. 5.53. Упорядковане ордерево Контрольні запитання до теми 5 1. 2. 3. 4. 5. 6. 7. 8. 9. Який граф називають деревом, а який – лісом? Яке співвідношення між вершинами і ребрами у дереві? Яке співвідношення між вершинами, компонентами зв’яності та ребрами у лісі? Яке дерево називають остовним? Опишіть алгоритм пошуку мінімального остовного дерева. Які вершини кореневого дерева називають нащадками, синами? Які вершини кореневого дерева називають внутрішніми, листками? Яке дерево називають k-арним, повним k-арним? Яке k-арне дерево називають збалансованим, ідеально збалансованим, завершеним? 10.Як знаходять кількість листків та всіх вершин у завершеному дереві висотою h? 11.Які способи подання дерев ви знаєте? Порівняйте їхню ефективність. 12. Як подають k-арні дерева у вигляді бінарних? З якою метою це здійснюють? 13.Дайте означення рекурсії. 14.Які обходи дерев ви знаєте? 15.Які структури даних отримали назву прошитих бінарних дерев? 16.Як називають запис, отриманий при обході математичного дерева в прямому порядку? 17.Як називають запис, отриманий при обході математичного дерева у внутрішньому порядку? 18.Як називають запис, отриманий при обході математичного дерева в зворотному порядку? 19.Чому інфіксну форму запису арифметичного виразу використовують рідко? 20.Сформулюйте правила, за якими обчислюють значення виразів, поданих у польському та зворотному польському записах. 21.У чому полягає головна ідея методу бектрекінгу? 22.Як знаходять гамільтонові циклі у графі за допомогою алгоритму бектрекінгу? 23.Як розфарбовують граф у п кольорів за допомогою алгоритму бектрекінгу? 24.Як розв’язують задачу про п ферзів за допомогою алгоритму бектрекінгу? 25.Як знаходять суму елементів підмножин за допомогою алгоритму бектрекінгу? 26.Опишіть алгоритм додавання елемента до бінарного дерева пошуку. 27.Опишіть алгоритм пошуку елемента в бінарному дереві пошуку. 28.Опишіть алгоритм видалення елемента з бінарного дерева пошуку. 29.Які властивості має AVL-дерево? 30.Як здійснюють балансування вершини в AVL-дереві? 31.Опишіть алгоритм додавання елемента в AVL-дерево. 32.Опишіть алгоритм видалення елемента з AVL-дерева. 33.Яке дерево називають червоно-чорним? Які воно має властивості? 34.Де використовують червоно-чорні дерева? Які переваги вони мають? 35.Порівняйте червоно-чорне і AVL-дерева. 36.Опишіть алгоритм додавання елемента в червоно-чорне дерево. 37.Що називають В-деревами? Для чого вони служать? Які мають властивості? 38.Опишіть алгоритм пошуку ключа в В-дереві. 39.Опишіть алгоритм додавання ключа до В-дерева. 40.Опишіть алгоритм видалення ключа з листка В-дерева. 41.Опишіть алгоритм видалення ключа з внутрішнього вузла В-дерева. 42.Назвіть переваги застосування В-дерева. 43.Порівняйте червоно-чорне дерево і В-дерево. 6.1. Упорядковані набори елементів Коли йде мова про родинні стосунки двох людей – Василя і Анни – то розуміють, що вони є членами якоїсь сім’ї. Впорядкована пара (Василь, Анна) відрізняється від інших впорядкованих пар людей тим, що між Василем і Анною є якісь родинні відношення (батько, двоюрідний брат і т.п.). У математиці серед усіх упорядкованих пар прямого добутку A B двох множин А і В теж виділяються деякі пари у зв’язку з тим, що між їхніми компонентами є деякі «родинні» відношення, яких нема в інших. Як приклад розглянемо множину S студентів якогось інституту і множину K курсів, які там читають. У прямому добутку S K можна виділити велику підмножину впорядкованих пар (s, k), які володіють властивістю: студент s слухає курс k. Побудована підмножина відображає відношення «... слухає ...», яке природно виникає між множинами студентів і курсів. Для строгого математичного опису будь-яких зв’язків між елементами двох множин ми введемо поняття бінарного відношення. В цьому розділі ми розглянемо різні шляхи визначення відношень і обговоримо деякі їхні властивості. Зокрема, розглянемо два важливі спеціальні типи відношень, які часто з’являються в математиці та інформатиці: еквівалентності та часткового порядку. Також вивчимо два найважливіші способи побудови нових бінарних відношень з існуючих, основані на обчисленні оберненого відношення і визначенні композиції відношень. Відношення між елементами декількох множин задають у вигляді таблиць даних. Ми покажемо, як такі п-арні відношення застосовують для опису простої системи управління базами даних. Функції відіграють центральну роль в математиці, де їх використовують для опису процесів, за яких елементи однієї множини якимось чином переходять в елементи іншої. Як ми побачимо, функції є спеціальним типом бінарних відношень. Дамо означення функції і обговоримо деякі їхні властивості. Сформулюємо закон, відомий як принцип Діріхле, за допомогою якого зможемо розв’язувати задачі, явно не зв’язані одна з одною. При роботі зі скінченними множинами порядок, в якому перераховують їх елементи, не має значення. Однак часом необхідно працювати з упорядкованими наборами. Означення 6.1.1. Кортеж – це упорядкований набір елементів. Кортеж довжини 2 (запис (a, b)) називають упорядкованою парою, тут а, b – елементи деяких множин А і В відповідно. Компоненти кортежу – елементи, що утворюють кортеж. На відміну від множини, компоненти кортежу можуть повторюватись. Кортеж записують у круглих дужках, наприклад, (a, b, c, a, d, k) – кортеж довжиною 6. Найбільш природним поданням в програмах упорядкованого набору з п елементів (п-ки) з множини А є масив A[n]. Означення 6.1.2. Два кортежі називаються рівними, якщо вони мають однакову довжину та їхні відповідні компоненти рівні. Тобто, кортежі (a1 , a2 ,..., an ) та (b1 , b2 ,..., bm ) рівні, якщо m=n, а також a1 b1 , a2 b2 , ..., an bm . Означення 6.1.3. Прямим добутком довільного числа множин А1, А2, ..., Ап називають множину A1 A2 ... An {( a1 , a 2 ,..., a n ) : a i Ai , i 1, 2 ,..., n} . У тому випадку, коли кожна з множин А1, А2, ..., Ап співпадає з множиною А, пишуть Ап для n A A ... A і кажуть про n-й позначення прямого добутку п екземплярів А A n разів степінь множини A. Елементами A n є послідовності (набори, вектори, рядки) ( a1 , a2 ,..., an ) довжиною n. Елементи прямого добутку – скінченні впорядковані набори, об’єкти, з якими працюють всі мови програмування. Підмножини прямих добутків також є об’єктами обробки в базах даних. Операція прямого добутку має практичне значення, оскільки підводить нас до понять «відношення» і «функція», які відіграють помітну роль в інформатиці і є предметом вивчення цього розділу. Означення 6.1.4. Множину всіх упорядкованих пар називають декартовим (прямим) добутком множин А і В та позначають A B . Отже, A B {(a , b) : (a A) (b B )} . Якщо A=B, то такий добуток називають декартовим квадратом множини А: A2 A A {(a, b) | a A, b A}. Розглянемо прямий добуток множини дійсних чисел на саму себе. Множину 2 , складену зі всіх упорядкованих пар дійсних чисел (х,у), називають декартовою площиною (рис. 6.1), звідси і назва «декартовий добуток». Рис. 6.1. Декартова площина Приклад 6.1.1. Нехай A={x, y} і B={1, 2, 3}. Знайдемо декартові добутки B A і A B , BB. Розв’язання. A B {( x ,1), ( x , 2 ), ( x , 3 ), ( y ,1 ), ( y , 2 ), ( y , 3 )} , B A {( 1, x ), (1, y ), ( 2 , x ), ( 2 , y ), ( 3 , x ), ( 3 , y )} , B B {( 1,1), (1, 2 ), (1, 3 ), ( 2 ,1), ( 2 , 2 ), ( 2 , 3 ), ( 3 ,1 ), ( 3 , 2 ), ( 3 , 3 )} Зауважимо, що множини A B і B A . різні! ▲ Грунтуючись на останньому прикладі, можна допустити, що потужність прямого добутку скінченних множин А і В дорівнює | A B | mn , якщо | A | m і | B | n . Це дійсно так, оскільки кожен елемент множини А (їх є т) бере участь в п різних впорядкованих парах. Якщо ж одне з них або обидва нескінченні, то і добуток буде мати нескінченну кількість впорядкованих пар. Як і у випадку попередніх операцій над множинами, ми можемо нарисувати діаграму Ейлера-Венна, яка ілюструє прямий добуток. Зокрема, для попереднього прикладу вона має вигляд (рис. 6.2): Рис. 6.2. Діаграма Ейлера-Венна прямого добутку A B 6.2. Поняття відношення. Бінарні відношення. Способи задання відношень Фундаментальним поняттям дискретної математики є відношення, яке використовують для позначення зв’язку між деякими об’єктами чи поняттями. Означення 6.2.1. Відношенням R на множині X1 X 2 ... X n називають деяку підмножину R прямого добутку X 1 X 2 ... X n , тобто R X 1 X 2 ... X n . Іншими словами, якщо відношення R складається з сукупності ( x1 ,x 2 ,..., x n ) , то очевидно x1 X 1 , x2 X 2 ,..., xn X n . Відношення використовують для позначення властивостей певних груп об’єктів, чисел чи сутностей. Якщо елемент ( x1 , x2 ,..., xn ) належить відношенню R, що має деякі властивості, то він володіє властивостями цього відношення. Приклад 6.2.1. Нехай відношення V є підмножиною декартового простору 2 (V 2), і володіє властивістю V ( x, y ) x y 2. Тоді, якщо пара (a,b) V , то точка (a,b) лежить на прямій x y 2 . ▲ Якщо відношення задано на прямому добутку двох множин, то воно називається бінарним, трьох множин – триарним, n множин – n-арним. Бінарні відношення R АхВ здебільшого розглядають за умови А=В і говорять про відношення V на А. Означення 6.2.2. Відношенням R на множині А називають підмножину декартового квадрату множини А, тобто R А2, використовують запис аRb, якщо (а, b) R, та запис а R b, якщо (а, b) R. Одиничним (тотожним) відношенням I A та універсальним відношенням U A на непорожній множині А називають відношення: I A {(a, a ) : a A}; U A {(a , b) : a A b A}. Оскільки А2, то називають порожнім відношенням на А. Приклад 6.2.2. Нехай A={0, 1, 2}, В={а, b} та задано відношення R={(0,а), (0,b), (1,а), (2,b)}. Отже, 0Ra, оскільки (0,а) R, але 1 R b, оскільки (1,b) R. ▲ Найзручніший спосіб задати зв’язок між елементами двох множин – записати властивість, притаманну цьому відношенню. Інший спосіб задати зв’язок між елементами двох множин – записати впорядковані пари елементів, що перебувають у цьому зв’язку. Приклад 6.2.3. Множина R={(x, y): x – дільник у} визначає відношення на множині А={1, 2, 3, 4, 5, 6}. Знайдемо всі впорядковані пари, що належать йому. Розв’язання. R складається з пар: (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 4), (2, 6), (3, 3), (3, 6), (4, 4), (5, 5), (6, 6). У цьому прикладі предикат «х – дільник у» дає ясний словесний опис відношення. Інший предикат «х – сестра у» визначає відношення на множині всіх людей. Приклад 6.2.4. Випишемо впорядковані пари, які належать таким бінарним відношенням на множинах А={1, 3, 5, 7} і В={2, 4, 6}: 1) U={(x, y): x+y=9}; 2) V={(x, y): x<y}. Розв’язання. 1) U складається з пар: (3, 6), (5, 4) і (7, 2); 2) V={(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (5, 6)}. Познайомимось ще з двома зручнішими способами (третім і четвертим) перерахування впорядкованих пар, що належать даному відношенню. Третій грунтується на понятті «орграф», четвертий спирається на булеві матриці. Означення 6.2.3. Нехай А і В – дві скінченні множини і V – бінарне відношення між ними. Ми зобразимо елементи цих множин точками на площині. Для кожної впорядкованої пари відношення V нарисуємо дугу, яка з’єднує точки, що зображають компоненти пари. Як приклад розглянемо відношення V між множинами А={1, 3, 5, 7} і В={2, 4, 6} з прикладу 6.2.4. Відповідний орграф показаний на рис. 6.3. Рис. 6.3. Відношення V між A і B Для ілюстрації відношення на окремій множині А ми креслимо орграф, вузли якого відповідають лише множині А, а дуги зазвичай з’єднують елементи впорядкованих пар, що знаходяться у відношенні. Приклад 6.2.5. Зобразимо граф, який подає відношення R із прикладу 6.2.3. Розв’язання. Оскільки R – відношення на множині А={1, 2, 3, 4, 5, 6}, то орграф буде мати 6 вузлів (рис. 6.4). Рис. 6.4. Відношення R на множині А Четвертий спосіб задання бінарного відношення на скінченних множинах оснований на використанні булевих матриць. Допустимо, що ми хочемо визначити бінарне відношення R між множинами A і B. Необхідно позначити елементи множин і виписати їх в якому-небудь порядку. Зробимо це так: А={а1, а2, ..., ап}, В={b1, b2, ..., bm}. Для визначення відношення R заповнимо прямокутну матрицю М з п рядками та т стовпцями – її називають п х т матрицею. Щоб краще зрозуміти такий спосіб задання відношень, перенумеруємо рядки елементами множини А, а стовпці – елементами множини В відповідно з порядком, в якому ми виписали елементи (в загальному випадку це робити необов’язково). Комірку матриці, яка знаходиться на перетині і-го рядка і j-го стовпця, позначимо Mij і заповнимо так: Mij =Т (1), якщо (аі, bj) R , Mij =F (0), якщо (аі, bj) R . (6.1) У цих термінах відношення U з прикладу 6.2.4 за допомогою булевої матриці задають так: 2 4 6 1 F F F 3 5 F F F T T F 7 T F F . Приклад 6.2.6. Відношення R на множині А={a, b, c, d} задано матрицею: F F F T T T F T T T F F F T, F T порядок рядків і стовпців у якій відповідає порядку виписаних елементів множини А. Назвіть упорядковані пари, що належать R. Розв’язання. Відношення R містить упорядковані пари (a, b), (a, с), (b, c), (b, d), (с, b), (d, a), (d, b) і (d, d). Приклад 6.2.7. Випишемо матрицю, яка зображає відношення R з прикладу 6.2.3. Розв’язання. Матриця відношення R має вигляд: T F F F F F T T T T T F F T T F F F F F F F F F T F F F T F T T T. F F T Приклад 6.2.8. Відношення R на множині А={1, 2, 3, 4} подано орграфом на рис. 6.5. Перерахуємо впорядковані пари, що належать R, випишемо відповідну матрицю і визначимо це відношення за допомогою предикату. Рис. 6.5. Відношення R на множині А Розв’язання. У термінах впорядкованих пар R={(2,1), (3,2), (4,3)}. Матриця (відносно даного в умові порядку елементів множини) має вигляд: F T F F F F F F T F F T F F. F F За допомогою предикату дане відношення може бути описане як: х-у=1. Ще два способи задання бінарних відношень: таблиця фактів і матриця взаємин є зручними, коли необхідно подати одразу кілька відношень, визначених на тій самій множині. Приклад 6.2.9. Розглянемо відношення R: “X одногрупник Y” і відношення S: “X подобається Y”, визначені на множині студентів {Володя, Ігор, Степан, Наталя, Олена, Оксана}. Відомо, що Володя і Наталя вчаться у групі ПЗ-11, а Степан і Олена у групі у групі ПЗ-12, Наталя подобається Володі і Степану, а Володя подобається Наталі і Олені. Подамо відношення між ними у вигляді таблиці фактів. Розв’язання. Таблиця фактів має вигляд (табл. 6.1). Таблиця 6.1. X Y Відношення Володя Володя Наталя Наталя Олена Степан Наталя Олена Володя Степан Степан Олена одногрупник, подобається Подобається одногрупник, подобається Подобається Одногрупник Одногрупник Матриця взаємин (матриця відношень) будується подібно до булевої матриці, тільки її елементами у i-му рядку та j-му стовбці будуть відношення, у які входять ці елементи. Приклад 6.2.10. Побудуємо матрицю взаємин для відношення у попередньому прикладі. Розв’язання. Матриця взаємин має вигляд (табл. 6.2). Володя Володя Наталя Наталя одногрупник, подобається Олена подобається одногрупник, подобається Олена Степан Таблиця 6.2 Степан Подобається Одногрупник одногрупник Якщо розглядати матрицю взаємин і таблицю фактів лише для одного відношення, то вони будуть фактично ідентичні булевій матриці і списку впорядкованих пар, але займатимуть більше місця у пам’яті комп’ютера. Отже, бінарне відношення між скінченними множинами може бути задано одним з шести способів: словами (за допомогою предикатів); множиною впорядкованих пар; орграфом; булевою матрицею; таблицею фактів; матрицею взаємин. 6.3. Властивості відношень Очевидно, що відношення як підмножини декартового добутку множин є доволі загальними поняттями. Якщо відношення задовольняють деякі додаткові умови, то можна визначити певні типи відношень. Розглянемо деякі з таких відношень, при цьому обмежимось бінарними відношеннями, заданими на одній множині, і введемо деякий набір їхніх властивостей. Означення 6.3.1. Кажуть, що відношення R на множині А рефлексивне, якщо для всіх х А (хRх), тобто кожен елемент х знаходиться у відношенні R до самого себе; антирефлексивне (іррефлексивне), якщо для всіх х А (х R х); симетричне, якщо для всіх х і у з А (хRу уRх), тобто для будь-якої пари R виконується або в обидва боки, або не виконується взагалі; антисиметричне, якщо (хRу уRх х=у) для кожної пари х і у з А; асиметричне (кососиметричне), якщо (хRу x y транзитивне, якщо (хRу уRz у R х) для всіх х і у з А; хRz) для будь-якої трійки елементів х, у, z А; антитранзитивне, якщо (хRу уRz х R z) для будь-якої трійки елементів х, у, z А; лінійне, якщо для всіх х і у з А (x=y xRy yRx). У термінах впорядкованих пар ці властивості визначають так. Означення 6.3.2. Відношення R: рефлексивне, якщо (х, х) R для будь-якого можливого значення змінної х; антирефлексивне, якщо (х, х) R для будь-якого можливого значення змінної х; симетричне, якщо з умови (х, у) R випливає, що (у, х) R для будь-яких можливих значень змінних х та у; антисиметричне, якщо з умови (х, у) R (у, х) R випливає, що х=у для будь-яких можливих значень змінних х та у. Іншими словами, відношення антисиметричне, якщо в разі х у воно не містить пар (х, у) та (у, х) одночасно; асиметричне, якщо з допущень (х, у) R і x y випливає, що (у, х) R для будь-яких можливих значень змінних х та у, тобто для будь-якої пари R або виконується в один бік, або не виконується взагалі; транзитивне, якщо з допущень (х, у) R (у, z) R випливає, що (х, z) R для будь- яких можливих значень змінних х, у та z; антитранзитивне, якщо з допущень (х, у) R (у, z) R випливає, що (х, z) R для будь-яких можливих значень змінних х, у та z; лінійне, якщо для всіх х і у з А виконується x=y (х, у) R (у, х) R . Означення 6.3.6. Орієнтований граф, який зображає: рефлексивне відношення – в кожному вузлі має петлю, тобто дугу, що починається і закінчується у тому самому вузлі (рис. 6.6, а); антирефлексивне відношення – у жодному вузлі не має петлі; симетричне відношення – разом із кожною дугою з вузла х до вузла у має дугу, спрямовану у зворотний бік з у до х (рис. 6.7, а); антисиметричне відношення – у випадку присутності дуги з вузла х до відмінного від нього вузла у, не матиме дуги з у до х (може мати петлі у вузлах), тобто граф не містить протилежно спрямованих дуг між жодною парою різних вузлів; асиметричне відношення – аналогічний до попереднього, але не має петель; транзитивне відношення – побудований так, що разом з дугами з вузла х до у та з у до z матиме також дугу з х до z (рис. 6.8, а); антитранзитивне відношення – побудований так, що поряд з дугами з вузла х до у та з у до z не матиме дуги з х до z; лінійне відношення – для двох різних вузлів має або дугу з вузла х до у, або спрямовану у зворотний бік з у до х, може мати петлі. Перерахуємо властивості матриць, які задають відношення. Перш за все зауважимо, що матриця відношення на окремій множині буде квадратною (тобто кількість її рядків буде дорівнювати кількості стовпців). Означення 6.3.4. У матриці, що задає: рефлексивне відношення – всі діагональні елементи рівні Т, тобто Mii=T (1) (рис. 6.6, б); антирефлексивне відношення – всі діагональні елементи рівні F, тобто Mii=F (0); симетричне відношення – Mij= Mjі, тобто вона буде симетричною (рис. 6.7, б); антисиметричне відношення – немає жодної пари одиниць на місцях, симетричних відносно головної діагоналі, тобто якщо i j, то з Mij=Т випливає Mji=F (але може бути Mij=Mji=F); асиметричне відношення – виконується умова (Mij=Т i j) Mjі=F, тобто матриця має таку ж властивість, як і попередня, до того ж усі елементи її головної діагоналі – нулі. транзитивне відношення – якщо Mjі=Т і Mkj=Т, то Mki=Т (рис. 6.8, б); антитранзитивне відношення – якщо Mjі=Т і Mkj=Т, то Mki=F; лінійне відношення – якщо Mjі=Т, то Mіj= F і навпаки, при цьому Mіi=Т або F, Mjj=Т або F. а б Рис. 6.6. Граф і матриця рефлексивного відношення Відношення та < на множині дійсних чисел є рефлексивним та антирефлексивним відповідно. Відношення «бути сином» на множині людей – антирефлексивне. Відношення «бути симетричним відносно вісі Х на множині точок координатної площини» не є ні рефлексивним, ні антирефлексивним: точка площини симетрична сама собі, якщо вона лежить на вісі Х, і несиметрична сама до себе в протилежному випадку. Відношення «бути симетричним відносно осі Х на множині точок координатної площини» є симетричним: якщо перша точка симетрична другій, тоі друга симетрична першій. Відношення на множині дійсних чисел є антисиметричним: якщо a b і b a , то а=b. Відношення < на множині дійсних чисел є асиметричним: якщо a b , то b a не виконується. а б Рис. 6.7. Граф і матриця симетричного відношення Важливо зазначити, що властивості симетричності й антисиметричності не є антагоністичними: існують відношення, які одночасно мають ці властивості. Наприклад, відношення R = на множині А={а} одночасно й симетричне, і антисиметричне. Є також відношення, які не мають жодної із цих двох властивостей. Зрозуміло, що будь-яке асиметричне відношення повинно бути й антисиметричним. Обернене твердження неправильне. Відношення та < на множині дійсних чисел транзитивні: якщо a b і b c , то a c. а б Рис. 6.8. Граф і матриця транзитивного відношення Відношення «рівність», задане на множині цілих чисел, та «жити в одному місті», задане на множині людей, – транзитивні. Відношення «бути сином» – антитранзитивне. Приклад 6.3.1. Розглянемо шість відношень на множині A={1, 2, 3, 4}: R1 = {(1,1), (1,2), (2,1), (2,2), (3,4), (4,1), (4,4)}; R2 = {(1,1), (1,2), (2,1)}; R3 = {(1,1), (1,2), (1,4), (2,1), (2,2), (3,3), (4,1), (4,4)}; R4 = {(2,1), (3,1), (3,2), (4,1), (4,2), (4,3)}; R5 = {(1,1), (1,2), (1,3), (1,4), (2,2), (2,3), (2,4), (3,3), (3,4), (4,4)}; R6 = {(3,4)}. Знайти властивості цих відношень. Відношення R3 та R5 – рефлексивні, оскільки вони містять усі пари вигляду (а,а), тобто (1,1), (2,2), (3,3), (4,4). Решта відношень не є рефлексивними, зокрема, R1 , R2 , R4 , R6 не містять пари (3,3). Відношення R4 та R6 – антирефлексивні, оскільки вони не містять жодної пари вигляду (а,а), тобто (1,1), (2,2), (3,3), (4,4). Зауважимо, що R1 , R2 не є ні рефлексивними, ані іррефлексивними. Лише відношення R2 та R3 симетричні, тому що містять тільки симетричні елементи. Лише відношення R4 , R5 , R6 є антисиметричними. У кожному із цих відношень немає таких пар елементів а та b (а b), що одночасно (а, b) R та (b, а) R . Є також відношення, які не є ні симетричними, а ні антисиметричними. Прикладом такого відношення є R1 . Відношення R 5 є антисиметричним відношенням, яке не є асиметричним через те, що воно містить пари (1,1), (2,2), (3,3) та (4,4). Відношення R4 , R5 , R 6 є транзитивними. Для кожного з них можна пересвідчитись, що якщо пари (а, b) та (b ,с) належать цим відношенням, то й пара (а, с) теж їм належить. Відношення R1 , R2 , R3 є антитранзитивними: (3,4) R1 , (4,1) R1 , але (3,1) R1 ; (2,1) R2 , (1,2) R2 , але (2,2) R2 ; (2,1) R3 , (1,4) R3 , але (2,4) R3 . ▲ Приклад 6.3.2. Що можна сказати про властивості наступних відношень: 1) «х є дільником у» на множині натуральних чисел; 2) « x y » на множині цілих чисел; 3) «кількість років х збігається з віком у» на множині всіх людей. Розв’язання. 1) Оскільки х завжди є своїм дільником, то це відношення рефлексивне. Воно антисиметричне, оскільки, наприклад, 2 є дільником 6, але не навпаки: 6 не є дільником 2, та асиметричне, бо з допущень: х є дільником у і у є дільником х зразу випливає, що у=х. Припустимо, що х є дільником у, а у, своєю чергою є дільником z. Тоді з першого допущення випливає, що у=тх для деякого натурального числа т, а з другого – z=пу, де п – натуральне число. Отже, z=пу=(пт)х, тобто х є дільником z. Тому дане відношення транзитивне. 2) Оскільки висловлювання x x хибне, то це відношення іррефлексивне. Воно симетричне, бо x y тоді і лише тоді , коли y x . Воно не транзитивне, бо, наприклад, 23 і 3 2 , але 2=2. Воно не асиметричне, бо з умов x y і y x не можна зробити висновок, що х=у. 3) Відношення цього пункту рефлексивне, бо вік будь-якої людини збігається з кількістю прожитих нею років. Воно симетричне, бо висловлювання «кількість років х збігаєтьсяє з віком у» рівносильне висловлюванню «кількість років у збігається з віком х». Воно транзитивне, бо якщо знайдуться такі три людини х, у і z, що «кількість років х збігається з віком у», а «кількість років у збігається з віком z», то всі троє будуть однакового віку. Оскільки ми можемо знайти багато ровесників, то це відношення не асиметричне. ▲ 6.4. Відношення еквівалентності Означення 6.4.1. Рефлексивне, симетричне і транзитивне бінарне відношення на множині А називають відношенням еквівалентності. Воно в деякому сенсі узагальнює поняття рівності. Еквівалентні елементи (тобто ті, що знаходять у відношенні еквівалентності) володіють якимись загальними ознаками. Наведемо приклади еквівалентності. Відношення «... має такі ж кути, що і ...» на множині всіх трикутників. Очевидно, трикутними еквівалентні щодо цього відношення тоді і лише тоді, коли вони подібні. Відношення R, задане умовою: хRу на множині ненульових цілих чисел є відношенням еквівалентності у тому і лише в тому випадку, коли ху>0. Тоді «еквівалентні» числа мають однаковий знак. Відношення «... має такий же вік, що і ...» на множині всіх людей. «Еквівалентні» люди належать до однієї і тієї ж вікової групи. Приклад 6.4.1. Нехай R – відношення на множині цілих чисел таке, що а R b тоді й тільки тоді, коли вони рівні за модулем a b . Покажемо, що воно є відношенням еквівалентності. Розв’язання. Це відношення має властивості: рефлективності: a a ; симетричності: якщо a b , то b a ; транзитивності: якщо a b і b c , то a c . Отже, воно є відношенням еквівалентності. ▲ Приклад 6.4.2 (конгруентність за модулем т). Покажемо, що відношення R ={(a, b)| а b(mоd т)} є відношенням еквівалентності на множині цілих чисел, де т – натуральне число і т > 1. Розв’язання. З означення а b(mоd т) випливає, що т націло ділить (а-b). Оскільки а а(mоd т), бо а-а=0, а 0 націло ділиться на m. Отже, відношення рефлексивне. Далі, а b(mоd т), якщо а-b=kт, де k – ціле. Отже, b-а=(-k)т, тобто b а(mоd т), відношення симетричне. Нарешті, нехай а b(mоd т), b с(mоd т). Це означає, що а-b=kт, b-с=lт, де k,l – цілі. Додамо останні дві рівності: а-b+b-с = (k+l)т, тобто а-с=(k+l)т. Отже, а с(mоd т), відношення транзитивне. Таким чином, конгруентність за модулем т є відношенням еквівалентності на множині цілих чисел. ▲ Якщо на множині задано відношення еквівалентності, то всі її елементи можна природнім чином розбити на підмножини, що не перетинаються. Всі елементи у будьякій з таких підмножин еквівалентні один одному у найзвичнішому сенсі. Наявність такого розбиття – рушійна сила будь-якої класифікаційної системи. Означення 6.4.2. Розбиттям множини А називають сукупність непорожніх підмножин А1, А2, ..., Ап множини А, які задовольняють таким вимогам: A A1 A2 ... An ; Ai A j при i j. Підмножини Аі називають блоками розбиття. Діаграма Ейлера-Венна розбиття множини А на 5 блоків показана на рис. 6.9. Блоки не заходять один на інший, бо вони не можуть мати спільних елементів. Рис. 6.9. Діаграма Ейлера-Венна розбиття множини на блоки Означення 6.4.6. Визначимо клас еквівалентності (КЕ) довільного елемента x A як підмножину E x [ x ] R { z A : zRx } , тобто це множина всіх елементів, які еквівалентні до елемента x A . Якщо b [х]R, то b називають представником цього класу еквівалентності. Далі доведемо теорему. Теорема 6.2. Нехай R – відношення еквівалентності на непорожній множині А. Тоді різні класи еквівалентності визначають розбиття А. Доведення. Доведення складається з чотирьох частин. Спочатку покажемо, що КЕ є непорожньою множиною в А. За означенням, Ех – підмножина в А. Крім того, R – рефлексивне відношення, тобто xRx. Отже, x Ex і Ех – непорожня множина. Далі перевіримо, що з xRу випливає рівність Ех= Еу. Допустимо, що xRу і візьмемо довільний z Ex . Тоді zRx і xRу. Оскільки R – транзитивне відношення, ми одержали, що zRу. Іншими словами, E y Ex , z Ey . Отже, Ex Ey . Аналогічно можна показати, що звідки випливає Ех= Еу. Тепер ми покажимо, що КЕ задовольняють першій властивості розбиття, а саме, що А є об’єднанням всіх КЕ. У першій частині доведення ми показали, що Ех – підмножина в А і тому об’єднання всіх КЕ теж буде підмножиною в А. З другого боку, якщо x A , то x Ex . Зокрема, х належить об’єднанню КЕ. Отже, і А є підмножиною цього об’єднання. Тому А збігається з об’єднанням КЕ. В останній частині ми покажемо, що два різні КЕ не перетинаються, тобто задовольняють другій властивості протилежного». Допустимо, що належить перетину Ex E y . розбиття. Ex E y . Скористаємось методом «від Тоді знайдеться елемент z в А, що Отже, zRx і zRу. Оскільки R – симетричне відношення, можна твердити, що xRz і zRy, звідки, враховуючи транзитивність R, маємо хRу. Згідно другої частини доведення Ех= Еу. Отже, ми допустили, що різні КЕ Ех і Еу перетинаються і довели, що насправді вони збігаються. Отримане протиріччя доводить останню частину наших міркувань і теорему загалом. Зазначимо, що при доведенні цієї теореми ми використали всі визначальні властивості відношення еквівалентності: рефлексивність, симетричність і транзитивність. Приклад 6.4.3. Відношення R на дійсній прямій задано умовою: хRу тоді і лише тоді, коли х-у – ціле число. Доведемо, що R – відношення еквівалентності і опишемо КЕ, які містять 0, ½ і 2 . Розв’язання. Оскільки х-х=0 Z для будь-якого дійсного числа х, відношення R рефлексивне. Якщо х-у є цілим числом, то і протилежне до нього у-х=-(х-у) є цілим. Отже, R – симетричне відношення. Нехай х-у і у-z – цілі числа. Тоді х-z=(х-у)+(у-z) – сума цілих чисел, тобто ціле число. Це означає, що R – транзитивне відношення. Тому R – відношення еквівалентності. КЕ Ех довільного дійсного числа х визначають за формулою: Ех={ z : z x – ціле число}. Тому Е0=Z; E 1 ={ z : z 1 – ціле число}={…, 1 1 , 1 , 1 , 1 1 , 2 1 ,... }; 2 2 2 2 2 2 2 E 2 ={ z : z 2 – ціле число}={…, 1 2 , 2 ,1 2,2 2 ,... }. ▲ Приклад 6.4.4. Знайдемо КЕ еквівалентності відношення із прикладу 6.4.1. Розв’язання. Оскільки ціле еквівалентне само собі та протилежному числу, то КЕ за цим відношенням такі: [а]={-а, а}, а 0 та [0]={0}.▲ Приклад 6.4.5. Знайдемо КЕ елементів 0 та 1 для відношення конгруентності за mod 4 (див. приклад 6.4.2). Розв’язання. З означення а b(mоd 4) випливає, що 4 націло ділить (а-b), тобто (а-b) ділиться на 4 без остачі. КЕ елемента 0 містить усі цілі b такі, що 0 b(mod 4). Цілі в цьому класі, очевидно, такі, що діляться на 4. КЕ елемента 1 містить усі цілі b такі, що 1 b(mod 4), тобто (1-b) ділиться на 4 без остачі. Такі класи еквівалентності називають класами конгруентності за модулем т і позначають [х]т. Отже, [0]4={..., -8, -4, 0, 4, 8, ...}, [1]4={...,-7, -3, 1, 5, 9, ...}. Відзначимо, що відношення конгруентності за mod 4 породжує розбиття множини Z цілих чисел на 4 класи: [0]4, [1]4, [2]4 та [3]4. Ці класи попарно не перетинаються, а їхнє об’єднання дорівнює множині Z. ▲ Матриця відношення еквівалентності (ВЕ). Нехай ВЕ задано в множині A. Елементи, що належать одному КЕ, попарно еквівалентні між собою. Отже, стовпці матриці ВЕ для елементів одного КЕ однакові та містять одиниці у всіх рядках, які відповідають цим елементам. Оскільки КЕ не перетинаються, у стовпцях, які відповідають елементам різних класів, не буде одиниць в одних і тих самих рядках. Приклад 6.4.6. Побудувати матрицю відношення еквівалентності, заданого класами еквівалентності A1 {a1 , a2 , a3}; A2 {a4 , a5 }; A3 {a6 , a7 , a8 , a9 }. Розв’язання. При побудові матриці ВЕ розташуємо елементи множини так, щоб ті елементи, які належать одному КЕ, були поруч. Тоді одиничні елементи матриці ВЕ утворять неперетинальні квадрати, діагоналі яких розташовуються на головній діагоналі матриці: a1 a2 a3 a4 a8 a5 a6 a7 a9 a1 1 1 1 0 0 0 0 0 0 a2 1 1 1 0 0 0 0 0 0 a3 1 1 1 0 0 0 0 0 0 a4 0 0 0 1 1 0 0 0 0 a5 0 0 0 1 1 0 0 0 0 a6 0 0 0 0 0 1 1 1 1 a7 0 0 0 0 0 1 1 1 1 a8 0 0 0 0 0 1 1 1 1 a9 0 0 0 0 0 1 1 1 1 6.5. Відношення порядку: нестрогого та строгого, часткового та лінійного. Відношення толерантності Як ми показали в попередньому підрозділі відношення рівності (наприклад, між числами) є частковим випадком відношення еквівалентності. Тому постає закономірне запитання: якими властивостями володіють відношення, аналогічні відношенню нерівності між числами? Означення 6.5.1. Транзитивне і антисиметричне відношення R на множині А називають відношенням порядку. Воно може бути рефлексивним, і тоді його називають відношенням нестрогого порядку. Воно може бути антирефлексивним, і тоді його називають відношенням строгого порядку. Відношення порядку може бути лінійним, і тоді його називають відношенням лінійного (повного) порядку. Відношення порядку може не володіти властивістю лінійності, тоді його називають відношенням часткового порядку. Переважно відношення строгого (лінійного чи часткового) порядку позначають знаком <, відношення нестрого порядку – знаком , відношення порядку в загальному випадку – знаком . Отже, якщо у відношенні нестрогого порядку властивість антисиметричності замінити асиметричністю, то одержимо строгий порядок. Приклади. Відношення < на множині дійсних чисел є відношенням строгого лінійного порядку. Відношення на множині дійсних чисел є відношенням нестрогого лінійного порядку. Відношення на булеані 2М є відношенням несторогого часткового порядку. Частковий порядок є важливим у тих ситуаціях, коли ми хочемо якось охарактеризувати старшинство, тобто вирішити, за яких умов один елемент множини перевищує інший. Приклад 6.5.1. Нехай A={1, 2, 3, 4, 6, 8, 12}. Відношення R1 задамо так: (а, b) R1 тоді й тільки тоді, коли а є дільником b. Отже: R1 ={(1,1), (2,2), (3,3), (4,4), (6,6), (8,8), (12,12), (1,2), (1,3), (1,4), (1,5), (1,6), (1,8), (1,12), (2,4), (2,6), (2,8), (2,12), (3,6), (3,12), (4,8), (4,12), (6,12)}. Легко переконатись, що це відношення рефлексивне, антисиметричне й транзитивне й, отже, є відношенням нестрогого порядку на множині А. ▲ Означення 6.5.2. Множину А з частковим порядком R прийнято називати частково впорядкованою множиною і позначати (А, R). Множину А з лінійним порядком R прийнято називати лінійно (тотально, повністю) впорядкованою множиною (ланцюгом). Два елементи а та b частково впорядкованої множини (А, R) називають порівняльними, якщо а R b або b R а. Якщо а та b такі елементи, що ані а R b, ані b R а, то їх називають непорівняльними. Наприклад, елементи 3 та 4 множини (А, R1 ) з прикладу 6.5.1 – непорівняльні, сама ця множина є частково впорядкованою, але не лінійно впорядкованою. Множина дійсних чисел є лінійно впорядкованою, а булеан – частково впорядкований. Якщо у частково впорядкованій множині будь-які два елементи порівняльні, то вона є лінійно впорядкованою. Приклад 6.5.2. Нехай А= E2n – множина всіх булевих векторів довжиною п (див. 7.2). Визначимо частковий порядок на цій множині так: (а1,а2,..., аn)<(b1,b2,..., bn) тоді й тільки тоді, коли aі bі (i=1,2,.. .,п). Цей частковий порядок не є лінійним порядком. Наприклад, не можна порівняти вектори (010000) та (101000). ▲ Матриця відношення часткового порядку (ВЧП). Оскільки ВЧП є рефлексивним, головна діагональ матриці цього відношення містить одиниці. Через те, що воно є антисиметричним, жоден одиничний елемент не має симетричного собі відносно головної діагоналі. Оскільки це відношення є транзитивним, наявність одиниць на перетині i-го стовпця та j-го рядка й одиниці на перетині j-го стовпця і k-го рядка спричиняє наявність одиниці на перетині i-го стовпця та k-го рядка. Приклад 6.5.6. Для відношення часткового порядку R =“...ділиться націло на...” на множині A= {1, 2, 3, 4, 6, 7, 12, 14, 21, 28} матриця ВЧП має такий вигляд: 1 2 3 4 6 7 12 14 21 28 1 1 1 1 1 1 1 1 1 1 1 2 0 1 0 1 1 0 1 1 0 1 3 0 0 1 0 1 0 1 0 1 0 4 0 0 0 1 0 0 1 0 0 1 6 0 0 0 0 1 0 1 0 0 0 7 0 0 0 0 0 1 0 1 1 1 12 0 0 0 0 0 0 1 0 0 0 14 0 0 0 0 0 0 0 1 0 1 21 0 0 0 0 0 0 0 0 1 0 28 0 0 0 0 0 0 0 0 0 1 Означення 6.5.6. Якщо R – відношення часткового порядку на множині А, то при x y і хRу х називають попереднім елементом або попередником, а у – наступним. Якщо х передує у і не існує таких елементів z, для яких хRz і zRу, х називають безпосереднім попередником у і пишуть x y (інколи також кажуть, що у покриває х). Лінійним порядком на множині А називають відношення порядку, за якого з будьякої пари елементів можна виділити попередній і наступний. У довільно взятого елемента у може бути багато попередніх елементів. Приклад лінійного порядку: лексикографічне упорядкування слів у словнику. Означення 6.5.7. Діаграма Гассе – граф, вершини якого відповідають елементам частково впорядкованої множини А, і якщо x y , то вершину х поміщають нижче вершини у і з’єднують з нею ребром. З цієї діаграми можна отримати повну інформацію про частковий порядок, рухаючись знизу догори по всіх ланцюгах ребер. Приклад 6.5.4. Дано, що відношення «... є дільником ...» визначає частковий порядок на множині А={1, 2, 3, 6, 12, 18}. Складемо таблицю попередників і безпосередніх попередників та побудуємо відповідну діаграму Гассе. Розв’язання. Запишемо таблицю попередників і безпосередніх попередників (табл. 6.3) та побудуємо відповідну діаграму Гассе (рис. 6.10). Таблиця 6.3 Елемент 1 2 3 6 12 18 попередник нема 1 1 1, 2, 3 1, 2, 3, 6 1, 2, 3, 6 безпосередній попередник нема 1 1 2, 3 6 6 Рис. 6.10. Діаграма Гассе ▲ Різні процедури сортування в інформатиці вимагають, щоб елементи множин, які потрібно посортувати, були лінійно впорядкованими. Тоді вони зможуть видавати впорядкований список. Інші застосування використовують частковий порядок, допускаючи, що в будь-якій скінченній частково впорядкованій множині знайдеться мінімальний елемент (той, що не має попередників) і максимальний (той, за яким немає наступних елементів). Максимальні та мінімальні елементи легко визначити на діаграмі Гассе – це, відповідно, “верхні” (не мають висхідних ребер) і “нижні” (не мають низхідних ребер) її елементи. Останній приклад свідчить, що частково впорядкована множина може мати понад один максимальний або мінімальний елемент. Зокрема, вказана частково впорядкована множина має один мінімальний елемент (число 1) та два максимальні (12 і 18). У цій множині є декілька лінійно впорядкованих підмножин. Кожній з них відповідає ланцюг ребер на діаграмі Гассе. Зокрема, підмножина {1, 2, 6, 18} є лінійно впорядкованою щодо відношення «... є дільником ...». Означення 6.5.8. Рефлексивне, симетричне і антитранзитивне відношення R на множині А називають відношенням толерантності. Толерантність відображає формальне уявлення інтуїтивного поняття схожості. Схожість двох об’єктів не залежить від того, в якому порядку їх порівнюють, в цьому проявляється властивість симетричності. В той же час, якщо перший об’єкт схожий з другим, а другий з третім, то це не означає, що перший і третій об’єкти схожі, тобто властивість транзитивності може не виконуватись. Прикладом може служити ланцюжок слів, в якому кожне наступне відрізняється від попереднього однією буквою: муха-мука-рука. 6.6. Операції над відношеннями. Часткові випадки відношень. Композиція відношень Оскільки відношення є множиною, то усі операції над множинами можна робити і над відношеннями. Приклад 6.6.1. На декартовому добутку множин A={1, 2, 3} та В={1, 2, 3, 4} визначені відношення R1 та R2 з А в B: R1 ={(1,1), (2,2), (3,3)}, R 2={(1,1), (1,2), (1,3), (1,4)}. Запишемо R1 R2 , R1 R2 , R1 \ R2 , R2 \ R1 . Розв’язання. R1 R2 ={(1,1), (1,2), (1,3), (1,4), (2,2), (3,3)}, R1 R2 ={(1,1)}, R1 \ R2 ={(2,2), (3,3)}, R2 \ R1 ={(1,2), (1,3), (1,4)}. ▲ Означення 6.6.1. Часткові випадки відношень. Нехай R є відношенням між А і В: R A B . Уведемо поняття: обернене відношення: R 1 {( b , a ) : ( a , b ) R } B A ; доповнення відношення: R {( a , b ) : ( a , b ) R } A B універсальне (повне) відношення: порожнє відношення: ; U {( a , b ) : a A b B } A B ; R . Для п’ятиелементної множини А={a1, a2, a3, a4, a5} графи тотожнього, повного і порожнього відношень зображено на рис. 6.11. а б Рис. 6.11. Графи часткових випадків відношень: тотожнього (а), повного (б), порожнього (в) в Якщо повне відношення задане за допомогою матриці, то всі її елементи дорівнюють 1. Матриця порожнього відношення складається з нульових елементів. Очевидно, що (R-1)-1=R. Наприклад, оберненим щодо «… батько …» на множині всіх людей буде відношення «… дитина …», для відношення “… більше або дорівнює …” оберненим є відношення “… менше або дорівнює …”, для відношення “… ділиться на …” – відношення “… є дільником …”. Якщо в орграфі, який зображає вихідне відношення, обернути всі стрілки, отримаємо обернене відношення. Для бінарних відношень існує особлива операція, якої не визначено для множин – композиція. Означення 6.6.2. Нехай R – бінарне відношення між множинами А і В, а S – бінарне відношення між множинами В і C. Композицією відношень R і S називають бінарне відношення між А і С, яке складається зі всеможливих упорядкованих пар (а, с), де а А, с С, і для яких існує елемент b В такий, що (а, b) R , (b, с) S. Композицію відношень R та S позначають через S R : S R {(a , c) : a A, c C b B : aRb, bSc} . (6.2) Нове відношення встановлює зв’язок між елементами множин А і С, з використанням елементів з В як посередників. В загальному випадку композиція відношень не комутативна, тобто S R R S . Наприклад, на множині людей визначено два відношення: «… кровні родичі …» і «… подружжя …». Відношення «… кровні родичі подружжя …» і «… подружжя кровних родичів …» відмінні. Приклад 6.6.2. Нехай R – відношення «а – сестра b», а S – відношення «b – мати с» на множині всіх людей. Опишемо словами композиції S R і S S . Розв’язання. Якщо а – сестра b, а b – мати с, то а буде сестрою матері, тобто а є тіткою с. Тому відношення S R є «а – тітка с». Якщо с є дитиною b, а d є матір’ю b, то d є бабусею с. Тому відношення S S є «d – бабуся с». ▲ Приклад 6.6.6. Знайдемо композицію відношень R та S, де R – відношення із множини А={1, 2, 3} в множину В={1, 2, 3, 4}: R={(1,1), (1,4), (2,3), (3,1), (3,4)}; S – відношення із множини В у множину С={0, 1, 2}: S={( 1,0), (2,0), (3,1), (3,2), (4,1)}. Розв’язання. Композицію S R будують, використовуючи всі впорядковані пари з R та з S такі, що другий елемент пари з R збігається з першим елементом пари з S. Наприклад, пари (2,3) R та (3,1) S породжують пару (2,1) S R . Виконуючи описані дії, отримаємо: S R ={(1,0), (1,1), (2,1), (2,2), (3,0), (3,1)}. ▲ Приклад 6.6.4. Допустимо, що відношення R і S задані орграфами, зображеними на рис. 6.12. Знайдемо орграф, що відповідає композиції S R . Рис. 6.12. Орграфи відношень R і S Розв’язання. Використовуючи орграфи, випишемо впорядковані пари, що належать відношенням: R {(a,1), (a,2), (a ,3), (b,2)} , S {(1, y ), (2, x), (3, x)}. Застосуємо означення композиції відношень: aR1 1Sy (a, y ) S R; aR 2 2 Sx (a, x) S R; aR3 3Sx (a , x) S R; bR 2 2 Sx (b, x) S R. Тепер на рис. 6.13 зобразимо орграф композиції: Рис. 6.13. Орграф композиції R S ▲ Приклад 6.6.5. Відношення R на множині А={1, 2, 3, 4, 5} задано матрицею: F F F F F F T T T F F F F T F T F T F F F T F . F F Обчислимо матрицю композиції R R і пояснимо, чому відношення R не володіє властивістю транзитивності. Розв’язання. Матриця композиції є такою F F F F F F T T T F F F F F T T F T F F F F T F F F F F F F F T T T F F F F F T T F T F F F F T F F F F F F F F T T T F F F F Т F F T T F F F T F . F T Елементи композиції R R мають вигляд (x, z), де xRz та yRz для будь-якого y A . Тому у випадку транзитивності R композиція R R має бути підмножиною R. Однак із розміщення значення Т в матрицях, виписаних вище, видно, що R R містить пари, які не належать R. Тому відношення R антитранзитивне. ▲ Означення 6.6.6. Нехай R – відношення на множині А. Степенем п відношення R на множині А називають його п-кратну композицію з самим собою, позначають R n , n=1, 2,..., визначають рекурсивнo: R 0 І , R1 R , ..., R n 1 R n R . Отже, зокрема, R 2 R R , R 3 R 2 R ( R R) R . Теорема 6.1. Якщо якась пара (а, b) належить якомусь степеню відношення R на множині А потужності п, то ця пара належить і деякому степеню R не вище п-1. Приклад 6.6.6. Нехай на множині А={1, 2, 3, 4} задано відношення R ={(1,1), (2,1), (3,2), (4,3)}. Знайдемо R n , n=2,3,4,5. За означенням послідовно отримаємо: R 2 R R {(1,1), (2,1), (3,1), (4,2)}, R 3 R 2 R {(1,1), (2,1), (3,1), (4,1)}, R 4 R 3 R {(1,1), (2,1), (3,1), (4,1)}, тобто R 4 R 3 . Можна переконатись, R 5 R 4 . ▲ Теорема 6.2. Нехай 1. 2. 3. 4. 5. 6. 7. R A A – відношення на А. Тоді R рефлексивне I A R ; R симетричне R R 1 ; R транзитивне R R R ; R антисиметричне R R 1 I A ; R асиметричне R R 1 ; R антирефлексивне R I A ; R антитранзитивне R R R ; 1 8. R лінійне R I A R U . 6.7. Замикання відношення за властивістю Якщо відношення R на множині А не володіє тією чи іншою властивістю, то варто спробувати продовжити його до відношення R*, яке буде мати потрібну властивість. Під продовженням ми розуміємо приєднання деяких впорядкованих пар до підмножини R A A * так, що нова отримана множина R вже буде володіти потрібною * властивістю. Ясно, що вихідна множина R буде підмножиною в R . У тому випадку, * якщо R буде мінімальним серед всіх розширень R з виділеною властивістю, то кажуть, * що R є замиканням R за даною властивістю. Означення 6.7.1. R* називають замиканням відношення R за властивістю Р, якщо R* володіє властивістю Р; R R* ; R* є підмножиною будь-якого іншого відношення, яке містить R і володіє властивістю Р. На основі операції композиції введемо нову операцію – транзитивного замикання відношень. Означення 6.7.2. Нехай відношення R задано на множині A. Транзитивним замиканням R * називають відношення, що складається з кортежів (x,y), для яких виконується одна з умов: кортеж (x,y) R або знайдеться така скінченна послідовність елементів z1 , z2 ,....zn A , що всі кортежі x, z1 , z1, z2 ,...., zn , y належать відношенню R. Очевидно, що R R* . Приклад 6.7.1. Нехай визначено множину людей {Ігор, Павло, Марія, Олена, Оксана}, і відомі такі факти: Ігор є нащадком Павла, Марія є нащадком Павла, Олена є нащадком Марії, Оксана є нащадком Олени. Знайдемо транзитивне замикання відношення R *. Розв’язання. Задану інформацію можна подати у вигляді відношення R : “… є нащадком …”. Тоді факти можна представити таким чином: Ігор R Павло, Марія R Павло, Олена R Марія, Оксана R Олена. Знайдемо транзитивне замикання відношення R *. R* ={(Ігор, Павло), (Марія, Павло), (Олена, Марія), (Оксана, Олена), (Олена, Павло), (Оксана, Павло), (Оксана, Марія)}.▲ Приклад 6.7.2. Нехай А={1, 2, 3}, а відношення R на А задано впорядкованими парами: R={(1, 1), (1, 2), (1, 3), (3, 1), (2, 3)}. Воно не рефлексивне, не симетричне і не транзитивне. Знайдемо відповідні замикання. Розв’язання. Замикання за рефлексивністю має містити всі пари вигляду (х, х). Тому R r* ={(1, 1), (1, 2), (1, 3), (3, 1), (2, 3); (2, 2), (3, 3)}. Додані пари відділені від заданих крапкою з комою. Замикання за симетричністю має містити всі пари, симетричні заданим. Тому R s* ={(1, 1), (1, 2), (1, 3), (3, 1), (2, 3); (2, 1), (3, 2)}. Щоб знайти замикання за транзитивністю (транзитивне замикання), необхідно виконати декілька кроків. Оскільки R містить пари (3, 1) і (1, 2), замикання обов’язково має включати і пару (3, 2). Аналогічно, пари (2, 3) і (3, 1) додають пару (2, 1), а пари (3, 1) і (1, 3) – пару (3, 3). Спочатку додамо ці пари: R t* {(1, 1), (1, 2), (1, 3), (3, 1), (2, 3); (3, 2), (2, 1), (3,3)}. Тепер у нас виникло поєднання (2, 1) і (1, 2), тому замикання має містити пару (2, 2). Як бачимо, всі необхідні пари ми додали (хоч би тому, що ми перебрали всі пари з А2). Отже, Rt* {(1, 1), (1, 2), (1, 3), (3, 1), (2, 3); (3, 2), (2, 1), (3,3), (2,2)}. ▲ Метод, яким ми знайшли замикання за транзитивністю в останньому прикладі, досить специфічний. Нагадаємо, що у четвертому розділі ми розглянули більш систематичний підхід, який дозволяє за матрицею відношення обчислити матрицю замикання щодо транзитивності (алгоритм Воршелла). Замикання за транзитивністю має багато застосувань. Нехай заданий орграф відображає комунікаційну мережу. У цьому випадку матриця замикання за транзитивністю дозволить нам визначити, чи існує можливість передати повідомлення з одного місця в інше. 6.8. Функції. Ін’єкції, сюр’єкції, бієкції Відношення ефективно застосовують для опису зв’язків між парами елементів, вибраних з двох множин. Функції – це частковий випадок бінарних відношень, на які накладено додаткові обмеження. Означення 6.8.1. Функцією з множини А в множину В називають бінарне відношення, за допомогою якого кожен елемент множини А зв’язаний з єдиним елементом множини В. Іншими словами, для кожного a A існує лише одна пара з відношення вигляду (а, b). Функцію описано таким графом, у якого з кожної вершини, що зображає елементи множини А, виходить лише одна стрілка. Наприклад, на рис. 6.14 зображено граф, що подає функцію з множини {a, b, c} в множину {1, 2}, яка складається з пар (а, 1), (b, 1) і (с, 2): Рис. 6.14. Зображення функції графом Приклад 6.8.1. Визначимо, які з відношень між множинами А={a, b, c} і В={1, 2, 3} є функціями з множини А у множину В: 1) f={(a, 1), (a, 2), (b, 3), (c, 2)}, 2) g={(a, 1), (b, 2), (c, 1)}, 3) h={(a, 1), (c, 2)}. Розв’язання. 1) Відношення f – не функція, бо елементу а відповідають два різні елементи множини В: 1 і 2. 2) Відношення g є функцією. 3) Останнє відношення функцією не є, бо елементу b не відповідає жодного елемента. ▲ Приклад 6.8.2. Яке з відношень є функцією: 1) «х – брат або сестра у» на множині всіх людей; 2) на множині Z, задане парами: {(x, x2): x Z}; 3) на множині , задане парами: {(x, у): x =у2}? Розв’язання. 1) Це не функція, бо є люди з декількома братами і сестрами, а також бувають сім’ї з однією дитиною. 2) Це відношення є функцією, бо по кожному цілому числу його квадрат визначається однозначно. 3) Останнє відношення не є функцією, бо, наприклад, йому належать обидві впорядковані пари (2, 2 ) і (2, - 2 ). Крім того, в ньому відсутні пари (х, у) з від’ємними х. ▲ Означення 6.8.2. Нехай f – функція з множини А в множину В. Оскільки для кожного х А існує єдиним чином визначний у В, такий, що (х, у) f, ми будемо писати: у=f(x) або f : A B , і казати, що функція f відображає множину А в множину В, а f(x) називати образом х при відображенні f або значенням f, що відповідає аргументу х. Множину А називають областю визначення, а В – областю значень функції f. Множиною значень функції f називають підмножину в В, яка складається з образів всіх елементів х А. Її позначають символом f(A) і формально визначають так: f ( A) { f ( x) : x A} . Діаграма Ейлера-Венна на рис. 6.15 служить зручною ілюстрацією функції, визначеної на множині А зі значеннями в множині В. Рис. 6.15. Діаграма Ейлера-Венна функції f: A B Коли ми працюємо з функцією A B , де А і В – нескінченні множини, ми не можемо нарисувати граф цього відношення. Тоді треба звернутись до традиційної математичної ідеї графічного подання функції, а саме, її графіка. Перейдемо до деяких важливих властивостей функції. Означення 6.8.3. Функцію f: A B називають ін’єктивною (ін’єкцією, взаємно однозначною), якщо ( f (a1 ) f ( a2 )) (a1 a2 ) a1 A, a2 A. Це означення логічно еквівалентне тому, що (a1 a 2 ) ( f (a1 ) f ( a2 )), тобто у ін’єктивної функції нема значень, які повторюються. Функцію f: A B називають сюр’єктивною (сюр’єкцією, функцією «на»), якщо множина її значень співпадає з областю значень. Це означає, що для кожного b B знайдеться такий a A , що b=f(a). Отже, кожен елемент області значень є образом якогось елемента з області визначення функції f. Функцію f: A B називають бієктивною (бієкцією, взаємно однозначною з множини А на множину В), якщо вона і ін’єктивна, і сюр’єктивна. Зображена на рис. 6.16 функція є ін’єктивною, бо в кожній клітці розміщено не більше одного кролика (але можуть залишатись і порожні клітки). Зображена на рис. 6.17 функція є сюр’єктивною, бо всі клітки зайняті. Зображена на рис. 6.18 функція є бієктивною, бо в кожній клітці знаходиться точно по одному кролику і немає порожніх кліток. Рис. 6.16. Ін’єктивне відображення «кролики – клітки», |X|=6, |Y|=8 Рис. 6.17. Сюр’єктивне відображення «кролики – клітки», |X|=6, |Y|=4 Рис. 6.18. Бієктивне відображення «кролики – клітки», |X|=6, |Y|=6 Приклад 6.8.3. Визначимо, які з функцій, зображених на рис. 6.19, ін’єктивні, а які сюр’єктивні. Перерахуємо всі бієкції. Рис. 6.19. Функції Розв’язання а) ця функція не ін’єктивна, бо значення 1 відповідає і а, і b. Вона не є і сюр’єкцією, бо в елемент 2 нічого не переходить; б) ця функція ін’єктивна, бо не має повторюваних значень. Вона і сюр’єктивна, бо множина її значень збігається зі всією областю значень; в) значення 1 ця функція набуває і на а, і на b, тому вона не ін’єктивна. Однак вона сюр’єктивна, бо в її множину значень входять всі елементи області значень; г) остання функція ін’єктивна, але не сюр’єктивна. Тільки у випадку б) ми маємо бієкцію. ▲ Приклад 6.8.4. Покажемо, що функція k: , задана формулою k ( x) 4 x 3 , є бієкцією. Розв’язання. Допустимо, що k ( a1 ) k ( a2 ) , тобто 4a1 3 4a2 3 . З останньої рівності випливає, що 4a1 4a 2 , звідки a1 a2 . Отже, k – ін’єкція. Нехай b . Покажемо, що знайдеться таке дійсне число a , що k(a)=b. Ясно, 1 що за а можна взяти a (b 3) , тому k – сюр’єкція. 4 Оскільки k є одночасно і сюр’єкцією, і ін’єкцією, то вона є бієктивною функцією. ▲ 6.9. Обернені функції і композиція функцій Означення 6.9.1. Функцію відношення до функції f 1 : B A , побудовану як обернене бінарне f : A B , називають оберненою, а вихідну функцію оборотною. Функція f складається з пар вигляду (а, b), де b=f(a). Якщо f оборотна, то обернена функція f 1 складається з пар (b, а), де a f 1 (b). Отже, оборотна функція має задовольняти умові: якщо f(a)=b, то f 1 (b) a. Приклад 6.9.1. Які з функцій прикладу 6.8.3 оборотні? Розв’язання. Обернене відношення отримуємо простим обертанням стрілок в орграфі, що його зображає. Очевидно, що лише у випадку (б) ми маємо оборотну функцію. ▲ Як бачимо з прикладу, функція, яка володіє властивістю оборотності, була бієктивною. Це не випадкове співпадіння: оборотні лише бієкції. Доведемо це. Теорема 6.6. Функція f оборотна тоді і лише тоді, коли вона бієктивна. Доведення. Доведення складається з двох частин. Спочатку ми доведемо, що бієктивна функція є оборотною. Нехай f : A B – бієкція. Як відношення її можна визначити з допомогою предикатів: f {(a, b) : a A f (a) b}. Згідно означення оберненого відношення 6.6.1 маємо: f 1 {(b, a) : a A f ( a) b}. Оскільки f сюр’єктивна, то b B a A : f (a) b . Крім того, внаслідок ін’єктивності функції f такий елемент а визначається по b єдиним чином. Отже, всі 1 володіють тією властивістю, що кожен елемент множини В пари відношення f відповідає єдиному елементу множини А. А це, за означенням 6.9.1, свідчить, що f 1 є функцією, тобто, що f є оборотною. Тепер покажемо, що оборотна функція обов’язково є бієктивною. Допустимо, що обернене відношення f 1 є функцією. Тоді b B a A : (b, a ) f 1. Отже, (a, b) f , тобто b=f(a). Цим доведено сюр’єктивність f. Для перевірки ін’єктивності функції f допустимо, що f (a1 ) f (a 2 ). Тоді обидві пари ( f ( a1 ), a1 ) і ( f (a 2 ), a 2 ) лежать в f 1 . Оскільки f 1 є функцією, виконується рівність a1 a2 , так що f є ін’єктивною. Таким чином, f є бієкцією, що і треба було довести. Доведення проведено повністю. Означення 6.9.2. Якщо f : A B і g : B C – функції, то композиція g f : A C є функцією, яка діє за правилом: g f ( x) g ( f ( x)) . Покажемо це. Композиція відношень між А і С складається з пар вигляду (а, с), де для деякого b B пара (a, b) f і пара (b, c) g . Однак елемент b=f(a) однозначно визначається по а, оскільки f – функція. Більше того, елемент c=g(b) теж однозначно визначається по b (g теж функція). Отже, елемент с=g(f(a)) єдиним чином визначається елементом а, тому композиція функцій f і g є функцією. Приклад 6.9.2. Розглянемо дві функції: f : , f ( x) x 2 і g: , g ( x) 4 x 3 . Обчислимо g f , f g , f f і g g . Розв’язання. Всі чотири нові функції визначені на зі значеннями в : ( g f )( x) g ( f ( x)) g ( x 2 ) 4 x 2 3, ( f g )( x) f ( g ( x)) f (4 x 3) (4 x 3) 2 16x 2 24x 9, ( f f )( x) f ( f ( x)) f ( x 2 ) x 4 , ( g g )( x) g ( g ( x)) g (4 x 3) 4(4 x 3) 3 16x 15. ▲ У сучасних мовах програмування функції дуже поширені. Вони дають можливість виділити окремі обчислення в підпрограми. Більшість мов має спеціальні бібліотеки з функціями, які найчастіше застосовують, такими, як sin x, log x, |x| і т.п. Крім того, ці мови дозволяють легко створювати власні функції. В особливо потужних мовах, відомих як мови функціонального програмування, основні оператори визначені в термінах функцій. Головна особливість таких мов – можливість побудови нових, складніших операторів з основних. Щоб уміти це робити, необхідно досконало оволодіти композицією функцій. 6.10. Принцип Діріхле Нехай f : A B – функція, причому А і В – скінченні множини. Допустимо, що А складається з п елементів а1, а2,..., ап. Принцип Діріхле каже, що якщо |А|>|В|, то щонайменше одне значення f зустрінеться більше, ніж один раз, тобто знайдеться пара елементів ai a j , для якої f (ai ) f ( a j ) . Фразою, яка легко запам’ятовується, його можна переформулювати так: не можна розсадити 10 кроликів у 9 кліток так, щоб в кожній клітці сидів лише один кролик. Щоб переконатись в істинності принципу, допустимо, що для будь-якої пари різних індексів i j ми маємо: f (ai ) f ( a j ) . Тоді множина В містить щонайменше п різних елементів: f(а1), f(а2), ..., f(ап), тобто |В| п, що суперечить допущенню п=|А|>|В|. Отже, є хоча би два різні елементи аі, аj A, для яких f (ai ) f ( a j ) . Приклад 6.10.1. В автобусі їде 15 людей. Покажемо, що щонайменше у двох з них день народження в одному і тому ж місяці. Розв’язання. Множину людей позначимо буквою А, а множину всіх місяців – В. Розглянемо функцію f : A B , яка ставить у відповідність кожній людині з автобуса місяць її народження. Оскільки |А|=15, |В|=12, то |А|>|В|. Згідно принципу Діріхле функція повинна мати значення, що повторюються, тобто знайдуться дві людини з одним і тим самим місяцем народження. ▲ Приклад 6.10.2. Яке найменше число прізвищ має бути записано у телефонному довіднику, щоб гарантовано твердити, що хоч би два прізвища починаються з однієї і тієї ж літери і закінчуються однаковими літерами? Розв’язання. Нехай А – множина прізвищ у довіднику, В – множина пар букв, виписаних з алфавіту української мови, що нараховує 33 літери. Позначимо через f : A B функцію, яка кожному прізвищу довідника ставить у відповідність пару літер: першу і останню літери прізвища. Наприклад, f(Мельник)=(м,к). Множина В містить 31 33 1023 пар літер (очевидно, що прізвища не можуть починатися з літер «и» та «ь»). Принцип Діріхле гарантує нам, що якщо |А|>|В|=1023, то знайдеться щонайменше два прізвища, які починаються і закінчуться на однакові літери. Тому телефонний довідник має містити не менше 1024 прізвища. ▲ Принцип можна узагальнити так. Розглянемо функцію f : A B , де А і В – скінченні множини. Якщо |А|>k |В| для деякого натурального k, то знайдеться таке значення функції f, якого вона набуватиме щонайменше k+1 раз. Це твердження вірне тому, що якщо кожне значення функція f набуває не більше k разів, то вся множина А складається не більше, ніж з k |В| елементів. Приклад 6.10.6. Яке найменше число прізвищ має бути записано у телефонному довіднику, щоб гарантовано твердити, що хоч би п’ять прізвищ починаються з однієї і тієї ж літери і закінчуються однаковими літерами? Розв’язання. Нехай f : A B функція з прикладу 6.10.2. Як ми вже підрахували, В складається з 1023 елементів. Щоб щонайменше 5 прізвищ починались і закінчувались однаковими буквами, потрібно, щоб |А|>4 |В| = 4092. Отже, телефонний довідник має містити не менше, ніж 4093 абоненти. ▲ Принцип Діріхле використовують у задачах, в яких порівняно легко підрахувати кількість елементів у множинах А і В (що буває не завжди), при цьому пошук функції, яка підходить до розв’язання задачі, завжди є найтяжчою його частиною. У розділі 8 «Комбінаторний аналіз» ми розглянемо різні методи перерахунку, які дадуть нам можливість визначати потужності скінченних множин, елементи яких вибираються визначеними способами. 6.11. Подання відношень та функцій у програмах 2 Нехай R відношення на А, R А і |A|=n. Перенумеруємо елементи множини А, тоді це відношення можна подати булевою матрицею М. У підрозділі 4.5 ми розглянули операції множення і диз’юнкції над булевими матрицями: множення: (M N) [i] [j]= n k 1 (M[i] [k] && N[k][ j]); диз’юнкція: (M N) [i] [j] = M[i] [j] || N[i] [j]; тут уведемо ще й інші. Зокрема, якщо М і N – булеві матриці, то операції над ними визначають так: транспонування: MТ[i] [j]=M[j] [i]; віднімання: (M-N) [i] [j]=M[i] [j] && (1-N[i] [j]); інвертування: M[i ][ j ] 1 M[i ][ j ] ; кон’юнкція: (M N) [i] [j]= M[i] [j] && N[i] [j]; В усіх наступних твердженнях допускаємо, що всі розглянуті відношення визначені на множині А, причому |A|=n. В універсальне відношення U входять всі пари елементів, тому всі елементи матриці цього відношення рівні 1. T Теорема 6.4. M R1 ( M R ) . Доведення. (b, a ) R 1 (a, b) R M R [a ][b] 1 ( M R )T [b][a ] 1 . Теорема 6.5. M R MU M R . Доведення. ( a, b) R ( a , b) R M R [a ][b] 0 MU [a ][b] M R [a ][b] 1 (MU M R )[a ][b] 1. Наслідок. M R M R . Теорема 6.5. M R2 R1 M R1 M R2 . Доведення. ( a, b) R1 R2 b A ( aR1b bR1c ) b A ( M R1 [a ][b] 1 M R2 [b][c ] 1) b A ((M R1 [a ][b] M R2 [b][c ]) 1) ( kn1 M R1 [ a ][ k ] M R2 [ k ][ c ]) 1 M R1 M R2 [a ][b]) 1. Наслідок. M Rk (M R )k . Теорема 6.5. M R1R2 M R1 M R2 . Доведення. (a, b) R1 R2 aR1b aR2b M R1 [a ][b] 1 M R2 [a ][b] 1) (M R1 M R2 )[a ][b] 1). Теорема 6.8. M R1R2 M R1 M R2 . Доведення. (a, b) R1 R2 aR1b aR2b M R1 [a ][b] 1 M R2 [a ][b] 1) (M R1 M R2 )[a ][b] 1). Приклад 6.11.1. На множині А = {1, 4, 7} задано бінарні відношення: 1 1 1 0 0 0 R1 0 1 1 , R2 1 0 0 . 1 0 1 1 1 0 Знайдемо матриці об’єднання (S) та перетину (P) відношень R1 та R2. Запишемо матриці обернених відношень R11 , R21 . Розв’язання. M S M R1 R2 1 1 1 0 0 0 1 1 1 M R1 M R2 0 1 1 1 0 0 1 1 1 , 1 0 1 1 1 0 1 1 1 M P M R1R2 M R1 M R2 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 . 1 0 1 1 1 0 1 0 0 1 0 1 0 1 1 R11 1 1 0 , R21 0 0 1 , 1 1 1 0 0 0 Композицію бінарних відношень можна обчислити і за допомогою булевих матриць, що їх визначають. Розглянемо три множини: A={a1, a2, …, an}, B={b1, b2, …, bm}, C={c1, c2, …, cp}. Допустимо, що R – відношення між А і В, а S – відношення між В і C. Нагадаємо, що матрицю М відношення R визначають умовою (6.1): Мij =Т, якщо (аі, bj) R , Мij =F, якщо (аі, bj) R . Аналогічно, матрицю N відношення S визначають умовою Nij =Т, якщо (bі, cj) S, Nij =F, якщо (bі, cj) S. Якщо знайдеться такий елемент bk B, що aiRbk і bkSсj, то елемент Mik матриці М та елемент Nkj матриці N будуть рівними Т. З іншого боку, оскільки за означенням композиції відношень (6.2) aiS Rcj, то значення Pij логічної матриці Р композиції S R теж рівне Т. Якщо ж в і-у рядку матриці М нема значень Т, які відповідають таким же значенням в j-у стовпці матриці N, то Pij=F. Отже, логічну матрицю Р композиції S R заповнюємо так: Pij= (Mi1 N1j) (Mi2 N2j) … (Min Nnj). Матрицю композиції S R називають логічним або булевим добутком матриць і позначають P=M N. Приклад 6.11.2. Нехай R і S – відношення з прикладу 6.5.6. Обчислимо булеву матрицю композиції S R за допомогою добутку булевих матриць відношень R і S. Розв’язання. Відношення R між A={a, b} і B={1, 2, 3} задамо матрицею T T T M , F T F рядки і стовпці якої помічені елементами множин А і В у тому порядку, в якому вони виписані. Аналогічно, S – відношення між B={1, 2, 3} і С={х, у}, задане матрицею F T N T F . T F Отже, логічна матриця Р композиції S R дорівнює булевому добутку: F T T T T T T . P T F F T F T F T F Оскільки Т в диз’юнкції поглинає всі інші доданки, то, знайшовши при логічному множенні найперше Т, обчислення далі проводити не варто. ▲ Подання відношень за допомогою булевих матриць – це лише один з можливих способів подання відношень, інші варіанти ми розглянули при обговоренні подання неорієнтованих та орієнтованих графів у розділах 3 та 4. Нехай f : A B , множина А скінченна і не дуже велика, |A|=n. Найзагальнішим поданням такої функції є масив. Якщо середовище програмування допускає масиви лише з натуральними індексами, то елементи множини А нумерують (тобто А={ a1 , a2 ,....an }) і функцію подають за допомогою масиву A[n]. Функцію декількох аргументів подають багатовимірним масивом. Подання функцій за допомогою масиву є ефективним за часом, бо реалізація масивів у більшості випадків забезпечує обчислення значення функції для заданого значення аргумента (індекса) за постійний час, який не залежить від розміру масиву і значення індекса. Якщо множина А велика чи нескінченна, то використання масивів для подання функцій є неефективним з точки зору економії пам’яті. Тоді для подання функцій використовують особливий тип процедур, які повертають єдине значення аргумента (часто їх теж називають функціями). У деяких мовах програмування визначення функцій вводять ключовим словом function. Багатомісні функції подають за допомогою декількох формальних параметрів у визначенні функції. Властивість функціональності забезпечується оператором повернення (його часто позначають ключовим словом return), який припиняє виконання тіла функціїї і одночасно повертає значення. У мові програмування Фортран і в деяких інших мовах виклик функції і звертання до масиву синтаксично нерозрізняльні, що підкреслює спорідненість цих понять. Контрольні запитання до теми 6 1. Як означають декартовий добуток довільної кількості множин? 2. Що називають кортежем і коли два кортежі є рівними? 3. Що називають відношенням на множині? 4. Які способи задання відношень ви знаєте? 5. Охарактеризуйте властивості бінарних відношень у термінах впорядкованих пар, орієнтованих графів, матриць. 6. Як знайти булеві матриці об’єднання і перетину відношень? 7. Якими властивостями володіє відношення еквівалентності? Наведіть приклади таких відношень. 8. Як визначають клас еквівалентності? 9. Опишіть структуру матриці відношення еквівалентності. 10. Якими властивостями володіють відношення часткового та лінійного порядку? Наведіть приклади таких відношень. 11. Якими властивостями володіють відношення нестрогого та строгого порядку? Наведіть приклади таких відношень. 12. Опишіть структуру матриці відношення часткового порядку. 13. Для чого призначена діаграма Гассе і як її будують? 14. Якими властивостями володіє відношення толерантності? Наведіть приклади таких відношень. 15. Яке відношення називають оберненим? 16. Що називають композицією бінарних відношень? Як знаходять матрицю композиції відношень? 17. Як будують замикання відношення за властивостями рефлексивності, симетричності і транзитивності? 18. За допомогою яких операцій можна вибирати інформацію з баз даних? 19. Яке відношення називають функцією? 20. Яку функцію називають ін’єктивною, сюр’єктивною, бієктивною? 21. Які функції є оборотними? 22. Як визначають композицію функцій? 23. Сформулюйте принцип Діріхле. Для розв’язання яких задач його застосовують? 24. Як за допомогою простих базових функцій будують нові у мовах функціонального програмування? 7.1. Булеві функції від двох булевих аргументів Булева алгебра – це назва області математики, яка займається логічним аналізом. Її операції і закони застосовують до логічних символів так само, як звичайна алгебра оперує символами, що зображають числові величини. У цьому розділі ми вивчимо булеву алгебру, а саме множину {0,1} з визначеними на ній операціями диз’юнкції, кон’юнкції і заперечення. Проведемо паралель між нею та логікою висловлювань (тема 1), з одного боку. і алгеброю множин (тема 2) з іншого. Ми покажемо, як булеві вирази можуть бути записані в стандартних формах, що мають назву «досконалі диз’юнктивна та кон’юнктивна нормальні форми». Потім опишемо методи побудови мінімальних, скорочених та тупикових диз’юнктивних нормальних форм: карти Карно, методи Куайна, Мак-Класкі, Блейка, Петріка. Продемонструємо, як всю цю розвинуту теорію застосовують до конструювання і спрощення функціональних схем та завадостійкого кодування методом Геммінга. Означення 7.1.1. Змінні р і q, які набувають значень з двоелементної множини Е2={0, 1}, називають булевими. Булевими функціями називають бінарні функції Fi ( p , q ) , які теж набувають значень з множини Е2: Fi : E22 Е2 . Булеві функції – найпростіший і найважливіший клас функцій, які використовують для опису скінченних автоматів та інших пристроїв, призначених для оброблення дискретної інформації. Як модель засобів опрацювання такої інформації застосовують поняття автомата, для формального опису якого слугує відповідна алгебра логіки (алгебра Буля). Всіх булевих функцій від двох змінних є 24=16. Задамо їх таблицею, вказуючи значення функцій на всіх наборах змінних р і q (табл. 7.1). Таблиця 7.1 p q F1 F2 F3 F4 F5 F6 F7 F8 0 0 0 1 0 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 1 1 1 1 0 0 0 0 1 0 1 0 p q F9 F10 F11 F12 F13 F14 F15 F16 0 0 0 1 0 1 1 1 0 1 0 1 1 0 1 1 1 0 1 1 1 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 Майже всі функції мають спеціальні назви, зокрема, F1(p, q)=0 – тотожній нуль, F16(p, q)=1 – тотожня одиниця, є постійними. Функції F6 і F7, F8 і F9 є фактично унарними, тобто залежать від однієї змінної: F7(p, q)=p, F9(p, q)=q, F6(p, q)= p p – заперечення р, F8(p, q)= q q – заперечення q. Інші функції є бінарними: F5(p, q)= p q – кон’юнкція, F15(p, q)= p q – диз’юнкція, F13(p, q)= p q – імплікація, F14(p, q)= q p – імплікація, F10(p, q)= p q – еквівалентність, F11(p, q)= p q – альтернативне «або» (додавання за модулем 2), F2(p, q)= p q – стрілка Пірса, F12(p, q)= p | q – штрих Шеффера. Невизначеними залишились лише функції F3(p, q)= p q і F4(p, q)= p q . Проте їх аналоги (Q\P та P\Q) в розділі 2 грали значну роль. 7.2. Булеві функції від n змінних Найпростіша булева алгебра складається з множини Е2={0,1} разом з визначеними на ній операціями диз’юнкції ( ), кон’юнкції ( ) і заперечення (-). Дія цих операцій над символами 0 і 1 показана на рис. 7.1. 0 1, 1 0. 0 1 0 1 00 1 00 0 11 1 10 1 Рис. 7.1. Дія операцій булевої алгебри над символами Ми можемо, компонуючи булеві змінні (тобто змінні, які набувають значень 0 і 1) за допомогою вказаних операцій, отримувати булеві вирази, так само, як ми будували складні висловлювання з простих, використовуючи при цьому істиннісні значення 1 і 0 замість Т і F. Означення 7.2.1. Вектор (р1, р2,..., рп), координати якого набувають значень з множини Е2={0, 1}, називають булевим (двійковим) вектором довжини п. Множину всіх булевих векторів довжини п називають булевим (двійковим) п-мірним кубом n (позначають E 2 ). n Бачимо, що є рівно 2п різних булевих векторів, тобто множина E 2 складається з 2п елементів. Як вже ми говорили раніше (розділ 1), будемо впорядковувати булеві вектори в порядку зростання чисел, які вони зображають у двійковій системі числення. Означення 7.2.2. Булевою (перемикальною) функцією f від п змінних називають функцію, задану на множині булевих векторів (р1, р2,..., рп), яка приймає n значення з множини Е2: f : E2 Е 2 . Булеву функцію можна задати таблицею істинності: p1 ... p n 1 pn f ( p1 ,..., p n 1, p n ) 0 0 ... ... 0 0 0 1 f (0,..., 0,0) f (0,...,0,1) 0 ... 1 ... ... ... 1 ... 1 0 ... 1 f (0,...,0,1) ... f (1,...,1,1) . Для того, щоб задати булеву функцію, достатньо зазначити її значення на всіх n булевих векторах. А оскільки на множині E 2 ми задали відношення порядку, то булева функція сама однозначно задається як булевий вектор довжини 2п, тобто таблиця істинності має 2п рядків, які відповідають всім різним комбінаціям значень п 2 змінних. Тому існує 2 різних стовпців, кожен з яких визначає булеву функцію від п змінних. п Отже, є рівно 2 2 різних булевих функцій від п змінних, тобто їх кількість зі збільшенням п зростає дуже швидко. Якщо при п=2 в попередньому підрозділі ми всіх їх виписали, то для п=3 матимемо 256 функцій, для п=4 – 65536, а для п=5 – 232=4 294 967 296! Тому спокусу вивчати булеві функції, переглядаючи весь список, потрібно відразу відкинути. Якщо треба задати декілька (наприклад, k) булевих функцій від п змінних, то це зручно зробити за допомогою однієї таблиці, використавши декілька стовпців: p1 ... pn f1 ( p1 ,..., p n ) ... f k ( p1 ,..., p n ) 0 ... 0 f1 (0,...,0) ... f k ( 0,...,0) ... 1 ... ... ... 1 ... f1 (1,...,1) ... ... ... f k (1,...,1) . Така таблиця буде мати 2п рядків, п стовпців для значень змінних та k стовпців длля значень функцій. Загалом кажучи, значення змінних можна не зберігати, якщо погодитися перераховувати набори змінних у визначеному порядку, наприклад, лексикографічному, а кортежі булевих значень – в порядку зростання цілих чисел, заданих як двійкові. Такий порядок називають установленим. Якщо k>2п , то таблицю істинності можна «транспонувати», виписуючи набори значень в стовпцях, а значення функцій – у рядках. 7.3. Диз’юнктивні та кон’юнктивні нормальні форми Означення 7.3.1. Кон’юнкцію будь-якої кількості різних незалежних змінних (літер), що входять із запереченням або без нього, називають елементарною кон’юнкцією. Кількість змінних, що входять до складу елементарної кон’юнкції, називають її рангом. Диз’юнктивна нормальна форма (ДНФ) функції – її подання формулою у вигляді диз’юнкції елементарних кон’юнкцій. Наприклад, x y z та x y z є елементарними кон’юнкціями, а x y z – ні. Ранг обох наведених елементарних кон’юнкцій дорівнює 3; ДНФ функції: f ( x, y , z ) ( x y z ) ( x y z ) ( x z ) . Означення 7.3.2. Конституентою одиниці (мінтермом, імплікантою) назиДНвають булеву функцію, подану у вигляді елементарної кон’юнкції, яка набуває значення 1 тільки на одному з кортежів своїх змінних. Кількість різних конституент одиниці для функцій п аргументів дорівнює числу різних кортежів, тобто 2п. Досконалою диз’юнктивною нормальною формою (ДДНФ) булевої функції називають диз’юнкцію мінтермів, які перетворюються в 1 на тих самих наборах змінних, що й задана функція. Будь-яка булева функція має одну ДДНФ (кількість її членів дорівнює кількості одиничних значень функції) і кілька ДНФ. Будь-яка ДНФ утворюється внаслідок більшого або меншого скорочення ДДНФ, причому від будь-якої ДНФ можна перейти до ДДНФ – такий перехід називають розгортанням. Приклад 7.3.1. Розглянемо булеву функцію m(p,q,r) від булевих змінних p, q і r з такою таблицею істинності (рис. 7.2, а) і випишемо для неї елементарну кон’юнкцію. Розв’язання. Функція т – приклад мінтерма, тобто булевої функції, яка приймає значення 1 тільки на одному наборі значень аргументів. Оскільки m(p,q,r)=1 тільки, якщо p=0, q=1, r=1, то m(p,q,r)= p q r. Вираз p q r. є елементарною кон’юнкцією. Пояснимо, як будь-який мінтерм можна записати у вигляді елементарної кон’юнкції, тобто як кон’юнкцію змінних рі або їх заперечень. p 0 q r m 0 0 0 0 0 1 0 0 0 1 0 1 1 0 , 1 1 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0 p q r f 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 , 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 0 0 а) p 0 q 0 r 0 M 1 0 0 0 1 1 0 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 1 1 1 б) p q , в) r f 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0. 1 1 0 0 0 1 0 1 1 1 1 0 1 1 1 1 г) Рис. 7.2. Таблиці істинності мінтерма (а), макстерма (в), булевих функцій (б, г) Нехай т(р1, р2,..., рr) – мінтерм. Тоді в останньому стовпці таблиці істинності функції буде лише одна 1. Візьмемо рядок таблиці істинності, останній символ в якій – 1. Якщо в цій стрічці змінна рі=1, то в елементарній кон’юнкції, яка зображає функцію т, бере участь рі, а якщо рі=0 – pi . Тепер, використовуючи елементарні кон’юнкції, ми запишемо довільну булеву функцію як диз’юнкцію мінтермів. Такий запис (ДДНФ) для кожної фунції визначений єдиним чином з точністю до перестановки елементарних кон’юнкцій. Приклад 7.3.2. Розглянемо булеву фукцію трьох змінних f(p,q,r), задану таблицею істинності (рис. 7.2, б) і випишемо для неї ДДНФ. Розв’язання. Одиниці останнього стовпця в цій таблиці відповідають трьом мінтермам: p q r, p q r, p q r. Таблиця істинності функції f може бути одержана накладанням таблиць істинності виписаних мінтермів. Оскільки диз’юнкція «поглинає» всі нулі (іншими словами, f1 f2 ... fr рівна 1 тоді і лише тоді, коли серед значень fі знайдеться хоч би одна 1), то функція f дорівнює диз’юнкції трьох мінтермів: f(p,q,r)= ( p q r ) ( p q r ) ( p q r ). Це і є ДДНФ функції f. Очевидно, що в такій формі можна записати довільну булеву функцію з довільним числом змінних. Означення 7.3.3. Диз’юнкцію будь-якої кількості різних незалежних змінних (літер), що входять із запереченням або без нього, називають елементарною диз’юнкцією. Кількість змінних, що входять до складу елементарної диз’юнкції, називають її рангом. Кон’юнктивна нормальна форма (КНФ) функції – її подання формулою у вигляді кон’юнкції елементарних диз’юнкцій. Наприклад, x y та x y z є елементарними диз’юнкціями, а x y z – ні. Ранг першої з наведених елементарних диз’юнкцій дорівнює 2, другої – 3, КНФ функції: f ( x, y, z ) ( x y z ) ( x y z ) ( x z ) . Означення 7.3.4. Конституентою нуля (макстермом) називають булеву функцію, подану у вигляді елементарної диз’юнкції, яка набуває значення 0 тільки на одному з кортежів своїх змінних. Кількість різних конституент одиниці для функцій п аргументів дорівнює числу різних кортежів, тобто 2п. Досконалою кон’юнктивною нормальною формою (ДКНФ) булевої функції називають кон’юнкцію макстермів, які перетворюються в 0 на тих самих наборах змінних, що й задана функція. Також за аналогією з ДДНФ, будь-яка булева функція має одну ДКНФ (кількість її членів дорівнює кількості нульових значень функції) і декілька КНФ. Приклад 7.3.3. Розглянемо булеву фукнцію М(p,q,r) від булевих змінних p,q і r з такою таблицею істинності (рис. 7.2, в) і випишемо для неї елементарну диз’юнкцію. Розв’язання. Функція М – приклад макстерма, тобто булевої функції, яка приймає значення 0 тільки на одному наборі значень аргументів. Оскільки М(p,q,r)=0 тільки, якщо p=1, q=0, r=0, то М(p,q,r)= p q r. Вираз p q r. є елементарною диз’юнкцією. Пояснимо, як будь-який макстерм можна записати у вигляді елементарної диз’юнкції, тобто як диз’юнкцію змінних рі або їх заперечень. Нехай М(р1, р2,..., рr) – макстерм. Тоді в останньому стовпці таблиці істинності функції буде лише один 0. Візьмемо рядок таблиці істинності, останній символ в якій – 0. Якщо в цій стрічці змінна рі=0, то в елементарній диз’юнкції, яка зображає функцію М, бере участь рі, а якщо рі=1 – pi . Тепер, використовуючи елементарні диз’юнкції, ми запишемо довільну булеву функцію як кон’юнкцію макстермів. Такий запис (ДКНФ) для кожної фунції визначений єдиним чином з точністю до перестановки елементарних диз’юнкцій. Приклад 7.3.4. Розглянемо булеву фукцію трьох змінних f(p,q,r), задану таблицею істинності (рис. 7.2, г) і випишемо для неї ДКНФ. Розв’язання. Нулі останнього стовпця в цій таблиці відповідають трьом макстермам: p q r , p q r , p q r. Таблиця істинності функції f може бути одержана накладанням таблиць істинності виписаних макстермів. Оскільки кон’юнкція «поглинає» всі одиниці (іншими словами, f1 f2 ... fr рівна 0 тоді і лише тоді, коли серед значень fі знайдеться хоч би один 0), то функція f дорівнює кон’юнкції трьох макстермів: f(p,q,r)= ( p q r ) ( p q r ) ( p q r ). Це і є ДКНФ функції f. Очевидно, що в такій формі можна записати довільну булеву функцію з довільним числом змінних. Під час вибору досконалої форми запису булевої функції варто пам’ятати, що ДКНФ є доцільнішою, якщо число наборів, де функція дорівнює 1, перевищує число наборів, де функція дорівнює 0. У протилежному випадку варто розглядати ДДНФ. Досконалі форми мать такі властивості: будь-яка кон’юнктивна або диз’юнктивна нормальна форма не дає однозначного подання функції, яке буде лише у досконалих нормальних формах; у ДДНФ (ДКНФ) немає двох однакових мінтермів (макстермів); у ДДНФ (ДКНФ) жоден з мінтермів (макстермів) не містить двох однакових змінних; у ДДНФ (ДКНФ) жоден з мінтермів (макстермів) не містить разом зі змінною її заперечення. Теорема 7.1. Будь-яка функція алгебри логіки, крім абсолютно істинної й абсолютно хибної, може бути подана в ДКНФ і ДДНФ: f ( x1 , x 2 ,..., x n ) ( ~ x1 ~ x 2 ... ~ xn ) 0 f ( x1 , x 2 ,..., x n ) ( ~ x1 ~ x 2 ... ~ xn ) , 1 де , – символи узагальненої кон’юнкції та диз’юнкції конституент 0 й 1 відповідно, 0 1 а ~ xi – це xi або xi (і=1, 2, ..., п). Доведення. Як доведення подамо кроки алгебраїчних перетворень, які дозволять перетворити довільну функцію у ДДНФ та ДКНФ. Крок 1. Застосувати правила (1.1)-(1.3) (розділ 1) для усунення логічних операцій імплікації, еквівалентності та додавання за модулем 2. Крок 2. Застосувати закон подвійного заперечення та закони де Моргана для перенесення знака заперечення безпосередньо до змінних. Крок 3. Застосувати відповідні закони дистрибутивності. Щоб побудувати КНФ, потрібно використати дистрибутивний закон А для диз’юнкції щодо кон’юнкції (ліва колонка з табл. 1.8, розділ 1). Для побудови ДНФ слід застосувати дистрибутивний закон В для кон’юнкції щодо диз’юнкції (права колонка з табл. 1.8, розділ 1). Крок 4. Застосувати закони ідемпотентності для видалення повторних входжень змінних. Крок 5. За правилом розвинення у кожну кон’юнкцію (для ДДНФ) чи диз’юнкцію (для ДКНФ), які не містять всі змінні, додати ті, яких не вистачає. Крок 6. Застосувати закони комутативності для сортування змінних. Приклад 7.3.5. Побудуємо ДНФ формули (( p q ) r ) ( r s ) . Наведемо послідовність кроків та зазначимо застосовані закони булевої алгебри, які аналогічні законам логіки висловлювань. Розв’язання. (( p q ) r ) ( r s ) ( ( p q ) r ) ( r s )) усунення логічної операції « », (( p q ) r ) ( r s )) закон де Моргана А, (( p q ) r ) (r s )) закон подвійного заперечення, (( p q ) (r s )) (r (r s) закон дистрибутивності В, (( p q r ) ( p q s )) ((r r ) (r s )) закон дистрибутивності В, ( p q r ) ( p q s ) (r r ) (r s ) закон асоціативності А, ( p q r ) ( p q s ) r (r s ) закон ідемпотентності. Ми одержали ДНФ, її можна спростити, якщо двічі використати закон поглинання В: диз’юнктивний член r поглинає члени ( p q r ) і (r s ) . Отже, ( p q s) r – це інша ДНФ заданої формули. Останні міркування свідчать, що ДНФ, загалом кажучи, не єдина. ▲ Приклад 7.3.6. Побудуємо КНФ формули ( p ( q r )) s ) . Наведемо послідовність кроків і застосовані закони: Розв’язання. ( p ( q r )) s ) ( p ( q r )) s усунення логічної операції « », ( p ( q r )) s закон де Моргана В, p (q r ) s закон асоціативності А, p (q r ) s закон де Моргана А, p (q r ) s закон подвійного заперечення В, p s (q r ) закон комутативності А, ( p s ) (q r ) ( p q s) ( p r s) закон асоціативності А, закон дистрибутивності А. Ми одержали шукану КНФ. Ця форма також не єдина. ▲ Приклад 7.3.7. Побудуємо ДДНФ формули (( x y ) y ) ( y z ) за допомогою алгоритму, наведеного у теор. 7.1. Розв’язання. (( x y ) y ) ( y z ) 1 (( x y ) ( x y ) y ) ( y z ) 2 (( x y ) ( x y ) y ) ( y z ) 3 ( x y y z ) ( x y y z ) ( y y z ) 4 ( x y z ) (x 0 z ) ( y z ) 4 (x y z ) ( y z ) 4 ( x y z ) (( x x ) ( y z ))5 ( x y z ) ( x y z ) ( x y z ) 4 ( x y z ) ( x y z ). 7.4. Мінімізація булевих функцій Ми переконались на досвіді, що будь-яку булеву функцію можна єдиним чином подати у вигляді диз’юнкції мінтермів або кон’юнкції макстермів. Отже, кожна булева функція двох змінних може бути виражена через дві функції від двох аргументів: p q, p q і однієї функції однієї змінної p . Означення 7.4.1. Множину булевих функцій разом із введеними на ній операціями заперечення, диз’юнкції, та кон’юнкції називають алгеброю Буля. Множину функцій, через які можна виразити будь-яку булеву функцію, називають функціонально повною системою функцій. Отже, { p q, p q , p } – повна система функцій. Однак можна обмежитись і меншою кількістю функцій. Наприклад, за законом де Моргана p q p q . Тому p q p q . Отже, будь-яку булеву функцію можна записати лише з допомогою двох операцій: і -, тобто { p q , p } – теж повна система функцій. Платою за малу кількість операцій, за допомогою яких записують функцію, стає громіздкість формул. Означення 7.4.2. Мінімізацією булевої функції називають відшукання найпростішого її подання у вигляді суперпозиції функцій якоїсь функціонально повної системи. Мінімальною ДНФ (МДНФ) булевої функції називають ДНФ, складену з найменшої можливої кількості букв (при цьому кожну букву враховують стільки разів, скільки вона зустрічається в ДНФ). Розглянемо лише мінімізацію ДНФ. Зазначимо, що за принципом двоїстості з методів мінімізації ДНФ можна отримати методи мінімізації КНФ. Перш за все, записуючи функцію, ми будемо опускати символ кон’юнкції аналогічно тому, як в звичайній алгебрі опускають символ множення, наприклад, ДНФ pq pq pr складається з 6 букв. Означення 7.4.3. Простою імплікантою булевої функції f називають імпліканту k, якщо одержана з неї після вилучення довільної букви елементарна кон’юнкція (ЕК) не буде імплікантою. ДНФ, що складається з усіх простих імплікант, називають скороченою ДНФ (СДНФ). Зазначимо, що СДНФ є єдиною, бо множина всіх простих імплікант визначається однозначно, а СДНФ є диз’юнкцією їх усіх. Зв’язок між мінімальною і скороченою ДНФ виражає теорема: Теорема 7.2. Мінімальну ДНФ (МДНФ) можна одержати з її скороченої ДНФ вилучивши деякі елементарні кон’юнкції. Доведення. Потрібно довести, що МДНФ Dmin довільної булевої функції є диз’юнкцією простих імплікант (можливо, не всіх). Припустимо, що імпліканта k1 з Dmin не проста. Тоді з неї можна вилучити хоча б одну букву так, щоб отримана ЕК k2 також була імплікантою функції f. Окрім того, k2 набуває значення 1 на всіх тих наборах, на яких набуває значення 1 k1. Отже, у ДНФ k1 можна замінити на k2 і отримати нову ДНФ D*, яка також подає функцію f і має менше букв, ніж Dmin. Отримана суперечність доводить теорему. Означення 7.4.4. ДНФ булевої функції f називають тупиковою ДНФ, якщо кожна ЕК у ній є простою імплікантою, вилучення з неї довільного диз’юнктивного члена приводить до ДНФ, яка не відповідає f. Теорема 7.3. Мінімальна ДНФ булевої функції є її тупиковою. Доведення випливає безпосередньо з означення 7.2.3. Зазначимо, що існують тупикові, але не мінімальні ДНФ, одна й та ж функція може мати декілька різних мінімальних ДНФ. Знаходження мінімальної ДНФ можа поділити на два етапи: побудова СДНФ; побудова всіх тупикових ДНФ і вибір мінімальних. 7.5. Карта Карно Для відшукання мінімальних ДНФ функцій невеликої кількості змінних можна застосувати метод карти Карно. Метод полягає в мінімізації ДДНФ булевої функції. Мінімізуємо ДДНФ pq r pqr pq r ( prq prq ) pq r = (закон комутативності та асоціативності) pr ( q q ) pq r = (закон дистрибутивності) p r pq r (закон виключення третього). На першому кроці ми зробили перегрупування: переставили і взяли в дужки два мінтерми, які відрізнялися лише одним символом. Закон дистрибутивності дозволив нам на другому кроці винести один мінтерм за дужки, виключивши з нього булеву змінну q. Мінімізацію функцій можна робити за допомогою карти Карно, методу, винайденого в 1950-х роках для розроблення логічних схем. Вона призначена для знаходження пар мінтермів, які можна згрупувати і перетворити в один простий вираз. У випадку булевих функцій трьох змінних p, q і r карта Карно є таблицею з двома рядками і 4-ма стовпцями (рис. 7.3): pq pq pq pq r r Рис. 7.3. Карта Карно для функцій трьох змінних Мітки розставлені так, що від стовпця до стовпця зміна відбувається лише в одному символі. Комірки карти Карно відповідають 8-ми мінтермам, які можна побудувати з 3-х булевих змінних. Якщо нам дано булевий вираз з ДДНФ, то в комірки, що відповідають записаним мінтермам, вносимо цифру 1. Карта Карно булевого виразу pq r pqr pq r зображена на рис. 7.4. pq r r pq pq 1 1 pq 1 Рис. 7.4. Карта Карно виразу pq r pqr pq r Пропонується групувати пари сусідніх одиниць у карті Карно (схожі на виділену на рис. 7.4). У нашому прикладі така пара одна, вона відповідає тим мінтермам, які ми об’єднали в зроблених раніше алгебричних перетвореннях. Загалом кажучи, при якійсь розмітці карти Карно може виявитись, що можливість групування мінтермів буде схована, наприклад, на рис. 7.5 для виразу pqr pqr pq r не видно, що члени pqr і pq r можна згрупувати. pq r pq pq pq 1 1 1 r Рис. 7.5. Невдале позначення стовпців карти Карно виразу pqr pqr pq r Перепозначивши стовпці зі збереженням основної вимоги, ми отримаємо альтернативну карту Карно (рис. 7.6), де члени для групування вже стоять поряд. Тому уважають, що в карті Карно для трьох змінних ліва і права межі тотожні (карту згорнуто в циліндр). За такої домовленості всі сусідні конституенти містяться на карті в сусідніх комірках. pq pq r r pq pq 1 1 1 Рис. 7.6. Альтернативна карта Карно виразу pqr pqr pq r Отже, pqr pqr pq r pqr ( pq r pqr ) pqr pr (q q ) pqr pr . Блоку з двох сусідніх комірок відповідає ЕК, яка є спільною частиною двох конституент і містить на одну букву менше. Прямокутному блоку з чотирьох сусідніх комірок відповідає ЕК, яка є cпільною частиною відповідних 4-х конституент і містить на дві букви менше. Тому на карті Карно можна об’єднувати прямокутні блоки, які містять сусідні 2, 4 або у загальному випадку 2і одиниць. Приклад 7.5.1. Мінімізуємо булевий вираз pqr pq r pqr pqr pqr . Розв’язання. Зобразимо карту Карно (рис. 7.7) pq pq r 1 1 r 1 1 pq pq 1 Рис. 7.7. Карта Карно виразу pqr p q r pqr pqr pqr З неї випливає, що в цьому виразі є група з чотирьох мінтермів: pqr pqr pqr pqr , і друга група з двох мінтермів pqr pq r . Спочатку попрацюємо над першою групою: pqr p qr pq r pqr ( p p ) qr ( p p )qr qr qr q (r r ) q. Тепер займемося другою групою: pqr pq r ( q q ) pr pr . Отже, вираз спрощується до q pr . Зауважимо, що з мінтермом pqr ми працювали два рази, використавши закон ідемпотентності. Приклад 7.5.2. Мінімізуємо булеву функцію f ( p, q, r ) (( p q ) r ) ( q r ). Розв’язання. За таблицею істинності функції f (рис. 7.8, а) побудуємо ДДНФ pq r p q r pq r та карту Карно (рис. 7.9): p q r f 0 0 0 1 0 0 1 1 0 1 0 0 0 1 1 0, 1 0 0 1 1 1 0 1 1 0 0 0 1 1 1 0 а) Цифри w x 0 0 0 y z 0 0 f 0 1 2 0 0 0 0 0 1 1 0 0 0 3 4 0 0 0 1 1 1 0 0 0. 0 5 6 0 0 1 1 0 1 1 0 1 1 7 8 0 1 1 0 1 1 0 0 1 1 9 1 0 0 1 1 б) Рис. 7.8. Таблиці істинності функцій для прикладів 7.5.2 та 7.5.4 pq pq pq r 1 r 1 pq 1 Рис. 7.9. Карта Карно виразу pq r p q r pq r З карти Карно видно, що групувати будемо дві пари мінтермів: pq r pq r і pq r pq r . Після їх спрощення отримаємо вирази p q і q r , отже, вихідна функція зводиться до виразу p q q r . Приклад 7.5.3. Знайдемо мінімальну ДНФ булевої функції f ( w, x, y , z ) wxyz wxyz wx yz wx yz wx yz w xyz w xyz w xyz w xyz w x yz w x yz . Розв’язання. Карту Карно зображено на рис. 7.10. Блок з 8-ми елементів (2-й та 3-й рядки) дає z , блок з 4-х елементів (2-й стовпець) дає w x , блок з 2-х елементів (у 4-у стовпці 1-й та 2-й рядки) – wx y . wx yz wx wx 1 wx 1 yz 1 1 1 1 yz 1 1 1 1 yz 1 Рис. 7.10. Карта Карно функції f ( w, x, y , z ) Отже, f c ( w, x, y, z ) z w x wx y . Приклад 7.5.4. Подати булеву функцію чотирьох змінних, визначену на наборах, які відповідають двійковому коду десяткових цифр 0, 1, 2, ..., 9, диз’юнктивною нормальною формою, що містить найменшу кількість букв. Значення функції дорівнює 1, якщо набір відповідає цифрам, що більші або дорівнюють 5, і дорівнює 0, якщо набір відповідає цифрам, меншим за 7. Розв’язування. Шукану функцію f ( w, x, y , z ) задано таблицею істинності (рис. 7.8, б). Її ДДНФ має вигляд: f ( w, x, y , z ) w xyz w xyz w xyz wx yz wx yz , а карту Карно зображено на рис. 7.11. yz wx 13 yz 12 wx wx yz wx 14 11 yz 15 Рис. 7.11. Карта Карно функції f (w, x, y, z ) w xyz w xyz w xyz wxyz wx yz Оскільки ця булева функція визначена не для всіх наборів значень аргументів, довільно довизначимо її на наборах, що відповідають десятковим цифрам від 10 до 15, тобто на wx yz , wx yz, wx yz , wxyz, wxyz , wxyz (використаємо позначку d для тих комірок, які відповідають наборам із невизначеним значенням булевої функції). Тоді під час формування найбільших блоків можна вважати, що в деяких (або всіх) комірках з позначкою d містяться 1. Карту Карно довизначеної функції зображено на рис. 7.12. wx wx d wx d wx 1 yz yz d d 1 1 d yz 1 d yz 1 Рис. 7.12. Карта Карно довизначеної функції Блок з 8-ми елементів (2-й та 3-й стовпці) дає w, два блоки з 4-х елементів дають xy та xz (1-й блок – це 3-й та 4-й стовпці і 1-й та 2-й рядки, другий блок – це ті ж стовпці і 1-й та 4-й рядки). Отже, f ( w, x, y , z ) w xy xz . Розглянутий спосіб можна узагальнити на булеві функції від п’яти і навіть шести змінних, однак тривимірні діаграми, які виникають при цьому, і додаткові ускладнення роблять метод карт Карно малопродуктивним. Тому є інші способи спрощення булевих функцій від будь-якої кількості змінних, зокрема, методи Квайна і Мак-Класкі. Використовуючи карту, аналогічну карті Карно (її називають картою Вейча), можна побудувати мінімальну кон’юктивну нормальну форму, при цьому групування слід проводити за нулями, а не за одиницями. 7.6. Методи побудови скороченої диз’юнктивної нормальної форми Метод Квайна. До ДДНФ послідовно застосовують такі кроки: ku ku k ku ku (неповне склеювання), ku k k (поглинання члена ku), де k – елементарна кон’юнкція, и – змінна. Кажуть, що члени ku та ku склеюють по змінній и і в результаті отримують k, склеювання називають неповним, бо ці члени залишаються в правій частині. Алгоритм методу Квайна Крок 1. Булеву функцію f ( x1 , x 2 ,..., x n ) записати в ДДНФ і позначити її f0. Присвоїти i:=0. Крок 2. Якщо до ДДНФ fi не можна застосувати жодного неповного склеювання, то кінець: fi – скорочена ДНФ. Інакше на основі fi побудувати fi+1 за правилом: у формі fi виконати всі неповні склеювання, які можна застосувати до елементарних кон’юнкцій із рангом n-і, а потім вилучити всі ЕК з рангом n-і, до яких можна застосувати поглинання. Крок 3. Присвоїти i:=і+1 і перейти до кроку 2. Приклад 7.6.1. Побудуємо методом Квайна СДНФ булевої функції, заданої ДДНФ: f 0 x y z x yz x y z x y z xyz . Розв’язання. Застосовуючи неповне склеювання до членів 1 і 2, 2 та 5, 3 та 4, 4 та 5, одержимо: f 0' x y z x yz x y z x y z xyz x y yz x y xz . Після п’ятикратного застосування поглинання ( x y поглинає 1-й та 2-й члени, xy поглинає 3-й та 4-й члени, yz поглинає 5-й член) отримаємо f1 x y yz x y xz . Оскільки жодне неповне склеювання не може бути застосоване до ДНФ f1, то ми отримали СДНФ. Метод Мак-Класкі. Удосконалення, зроблені Мак-Класкі до методу Квайна, полягають у його формалізації щодо реалізації на комп’ютері. Алгоритм методу Мак-Класкі Крок 1. Записати булеву функцію, яку потрібно скоротити, в ДДНФ. Крок 2. Упорядкувати змінні й записати їх у кожній ЕК у вибраному порядку. Після цього подати кожну ЕК послідовністю з 1, 0 та – (рисок): на і-тій позиції записати 1, якщо і-та змінна входить до ЕК без заперечення, 0 – якщо вона входить із запереченням, і риску, якщо не входить. Наприклад, ЕК xyz , x z , x u записують, відповідно, у вигляді 111-, 1-0-, 1- -0. Крок 3. Розбити двійкові вирази, які відповідають ЕК, на класи за кількістю одиниць і розмістити списки цих класів за зростанням кількості одиниць. Для ДДНФ з прикладу 7.6.1 отримаємо список з п’яти елементів, розбитих на три класи (рис. 7.13, а). Ми відділили їх рисками. Крок 4. Виконати всі можливі склеювання ku ku k . Їх можна застосувати лише до тих елементів списку, що містяться в сусідніх класах. Склеюють елементи, які відрізняються лише однією позицією (і в цій позиції не має бути риска), їх позначають зірочкою (*) і надалі вони не входять у список простих імплікант. Повторювати крок 4 доти, доки можна застосувати склеювання. Якщо помістити до одного класу всі імпліканти, отримані з двох сусідніх класів, то на черговому повторенні кроку 4 нам знову доведеться порівнювати лише елементи із сусідніх класів. Попередній список після опрацювання має вигляд, як на рис. 7.13, б. Склеємо 1-й і 3-й елементи та 2-й і 4-й з 1-го і 2-го класів і помістимо їх в новий 1-й клас. Потім склеємо перші елементи 2-го та 3-го класів та 2-й елемент 2-го класу з 1-м елементом 3-го класу, помістимо їх в новий 2-й клас (рис. 7.13, в). 010 *010 01- 100 *100 10- 011 *011 -11 101 *101 1-1 111 *111 а) б) в) Рис. 7.13. Знаходження СДНФ методом Мак-Класкі Далі склеювати неможливо. Непозначеними зірочкою залишились 4 елементи. Отже, множина x y yz x y xz . всіх простих імплікант { x y , yz , x y , xz }, а її СДНФ – Метод Блейка. У розглянутих вище методах відшукання СДНФ починалось з ДДНФ. Якщо знаходять СДНФ функції, заданої довільною ДНФ, то доцільно застосовувати метод Блейка. Він грунтується на використанні тотожності узагальненого склеювання (УС): xz y z xz y z xy , (7.1) де х, у, z – довільні формули. Якщо в цій тотожності xy 0 , то кажуть, що до членів можна застосувати нетривіальне УС. Доведемо тотожність (7.1), використовуючи закони алгебри Буля: xz y z xz xyz y z xy z (додали два члени, які можуть поглинатися наявними) xz yz xy ( z z ) xz yz xy. Теорема 7.4. Якщо в будь-якій ДНФ булевої функції виконати всі можливі узагальнені склеювання, а потім – усі поглинання, то одержимо СДНФ цієї функції. Доведення грунтується на тому, що після багатократного застосування тотожності (7.1) до довільної ДНФ функції можна отримати будь-яку просту імпліканту цієї функції. Метод Блейка одержання СДНФ полягає в тому, що у довільній ДНФ спочатку виконують усі допустимі УС (причому одержані внаслідок них члени беруть участь у нових УС). Після цього виконують поглинання, тобто вилучають диз’юнктивні члени у вигляді ху, якщо є диз’юнктивні члени х чи у. Приклад 7.6.2. Знайдемо методом Блейка СДНФ булевої функції f x y x yz yz . Розв’язання. Очевидно, що перший і другий члени формули можна піддати УС як по х, так і по у. Але члени, що виникають унаслідок цих склеювань ( yyz, xx z ) , дорівнюють нулю. Нетривіальне УС тут можливе лише для першого та третього членів формули. Застосувавши його, одержимо ДНФ f1 x y x yz yz xz . У цій формі нетривіальне УС можна застосувати до 1-го і 3-го, а також до 2-го та 4-го членів. Проте обидва ці склеювання дають члени xz i yz, які вже є у формі f1, тому бачимо, що у цій формі виконано всі можливі УС. Виконавши елементарне поглинання (член x yz поглинається членом yz ), отримаємо СДНФ f 2 x y yz xz . Розглянемо важливу властивість СДНФ. Теорема 7.5. Якщо СДНФ булевої функції не містить жодної букви, яка б входила до неї водночас із запереченням і без нього, то ця СДНФ є МДНФ. Доведення. До ДНФ f, яка не має жодної букви водночас із запереченням і без нього, не можна застосувати тотожність УС (7.1). Це саме стосується і диз’юнкції довільної кількості членів цієї форми. Якщо f – СДНФ, то її можна відновити за допомогою УС з МДНФ, що є якоюсь частиною f. Отже, тоді МДНФ збігається зі СДНФ. Метод Нельсона. Розглянемо ще один метод побудови скороченої нормальної форми, яким зручно користуватись, коли функцію подано довільною КНФ. Теорема 7.6. Якщо в будь-якій КНФ булевої функції розкрити всі дужки згідно з дистрибутивним законом і виконати всі поглинання, то одержимо СДНФ цієї функції. Для доведення достатньо переконатись, що розкривши дужки в довільній КНФ булевої функції, можна отримати будь-яку наперед задану просту імпліканту цієї функції. Приклад 7.6.3. Знайдемо методом Нельсона СДНФ булевої функції f ( x y )( x z )( x y z ). Розв’язання. Розкривши дужки, отримаємо f ( xz x y y z )( x y z ) xz xyz x y z x y z . Після поглинань матимемо СДНФ f c xz xz ( y y ) x y z xz x y z . Ми вивчили методи отримання скорочених диз’юнктивних нормальних форм, що є першим етапом мінімізації. 7.7. Побудова тупикових ДНФ Імплікантна таблиця Квайна. На 2-му етапі мінімізації знаходять усі тупикові ДНФ, з яких вибирають мінімальні. Основний апарат для виконання 2-го етапу – імплікантна таблиця (ІТ) булевої функції. Це прямокутна таблиця, рядки якої є простими імплікантами k p функції f, а стовпці – наборами значень змінних a~ n (або відповідними конституентами одиниці k), на яких функція набуває значення 1. Якщо kp перетворюється в 1 на a~ n , то на перетині відповідного стовпця і рядка ставлять * і кажуть, що k p накриває одиницю булевої функції. Таблицю слід заповнювати за правилом: на перетині рядка k p та стовпця k ставлять * тоді і лише тоді, коли k p є частиною k (можливо, співпадає з нею). Приклад 7.7.1. Побудуємо мінімальні ДНФ знайденої в прикладі 7.6.1 методом Квайна СДНФ f1 x y yz x y xz булевої функції f 0 x y z x yz x y z x y z xyz . Розв’язання. Будуємо імплікантну таблицю (табл. 7.2). Таблиця 7.2 k p \k x yz x yz xy * * xy xz yz xyz xyz * * * * xyz * * Якщо у стовпці лише одна *, то просту імпліканту з відповідного рядка вибираємо обов’язково. Множину таких простих імплікант називають ядром булевої функції (у нас це x y та xy ). Імпліканти ядра входять у будь-яку тупикову ДНФ, але вони можуть накривати лише частину одиниць булевої функції (конституент, які відповідають цим одиницям). Викреслимо в таблиці рядки, що відповідають імплікантам ядра, та стовпці, які містять хоча б одну викреслену *. Методом перебору знайдемо мінімальні прості імпліканти, що накривають решту конституент одиниці. Так ми визначимо всі тупикові ДНФ, з яких вибиремо мінімальні. Єдина конституента, що залишається не накритою імплікантами ядра, – це xyz. Її може накрити одна з імплікант xz або yz. Отримали дві тупикові ДНФ: f1 x y x y xz і f 2 x y x y yz . Обидві вони мінімальні (мають по 6 букв). Метод Петріка знаходження всіх тупикових ДНФ. Метод перебору для знаходження тупикових ДНФ з ІТ на практиці можна застосувати лише для відносно простих таблиць, а також тоді, коли достатньо знайти не всі, а лише одну тупикову ДНФ. У разі складних таблиць застосовують метод Петріка. Алгоритм методу Петріка знаходження всіх тупикових ДНФ Крок 1. Прості імпліканти позначають великими латинськими буквами (для табл. 7.2 так: А – x y , В – xy , С – xz, D – yz). Крок 2. Для кожного стовпця ІТ будують диз’юнкцію букв, що відповідають рядкам із * в цьому стовпці (для табл. 7.2 одержимо вирази x yz – A, x yz – x y yz A D , xyz – B, xyz – xy xz B C , xyz – xz yz C D ). Крок 3. Записують кон’юнкцію отриманих диз’юнкцій – кон’юнктивне подання ІТ (для табл. 7.2 одержимо вираз A( A D ) B( B C )(C D ) ). Крок 4. У кон’юнктивному подання ІТ розкривають усі дужки за дистрибутивним законом. Одержаний вираз називають диз’юнктивним поданням ІТ. Крок 5. До диз’юнктивного подання ІТ застосовують усі можливі поглинання A AB A та усувають всі повторення АА=А, A A A . Новий вираз називать зведеним диз’юнктивним поданням ІТ. Кроки 4 та 5 можна об’єднати й одразу шукати зведене диз’юнктивне подання ІТ, застосовуючи перетворення згідно з тотожностями булевої алгебри. Крок 6. Прості імпліканти, позначення яких входять у будь-який диз’юнктивний член зведеного диз’юнктивного подання ІТ, утворюють тупикову ДНФ. Щоб отримати всі тупикові ДНФ, треба розглянути всі диз’юнктивні члени цього подання. Для табл. 7.2 можемо записати A( A D ) B ( B C )(C D ) AB ( AB AC BD CD )(C D) AB ( ABC AC BCD CD ABD ACD BD CD ) ABC ABC ABCD ABCD ABD ABCD ABD ABCD ) ABC ABCD ABD ABC ABD. Очевидно, що кон’юнкції АВС відповідає тупикова ДНФ f1 x y x y xz , а кон’юнкції АВD – тупикова ДНФ f 2 x y x y yz . 7.8. Фізична інтерпретація функцій алгебри логіки. Функціональні схеми Інтерпретуватимемо функції алгебри Буля як перемикальні функції електричних кіл, що містять двопозиційні перемикачі. Одиницю інтерпретуємо як стан перемикача «струм проходить», нуль – «струм не проходить». Вважатимемо, що х – замикальний контакт, x – розмикальний контакт, – послідовне з’єднання контактів, – паралельне з’єднання контактів. Уперше таке застосування булевих функцій запропонував інженер-електрик Еренфест у 1916 р. Ефективним виявилося використання логічних операцій для опису роботи логічних елементів комп’ютерів. Широко застосовують їх і в теорії алгоритмів. Два електричних кола вважають еквівалентними, якщо через одне з них проходить струм тоді і лише тоді, коли він проходить через інше. З двох еквівалентних схем електричних кіл простішою схемою вважатимемо ту, що містить менше контактів. Однією з основних галузей, де застосовують булеві функції, є створення функціональних схем (ФС), які можна реалізувати у вигляді електронних пристроїв зі скінченним числом входів і виходів, причому на кожному вході і виході можуть з’являтися лише два значення. Такі пристрої збирають з функціональних елементів (ФЕ), що генерують основні булеві операції. Стандартні позначення основних функціональних елементів показані на рис. 7.14. АБО І НЕ НЕ-І Рис. 7.14. Стандартні позначення основних функціональних елементів З’єднуючи ФЕ, ми отримуємо ФС. Приклад 7.8.1. Знайдемо, що ми матимемо на виході ФС, поданої на рис. 7.15: Рис. 7.15. Функціональна схема Розв’язання. У табл. 7.3 перераховані входи і відповідні виходи для кожного ФЕ згідно нумерації на рис. 7.15. Таблиця 7.3 ФЕ Вхід Вихід 1 2 p, q p, q pq pq 3 4 pq , r pq , r pqr pq r 5 6 pq , r pqr , pq r pqr pqr pq r 7 pqr pq r , pqr pqr pq r pqr . Отже, на виході схеми отримаємо функцію pqr pq r pqr . ФС можна спростити, якщо дозволити функціональним елементам І та АБО мати не по два входи, а більше. Але більш вражаючого ефекту можна добитися, якщо спростити отриману на виході складну функцію за допомогою карти Карно. Приклад 7.8.2. Спростимо функцію, згенеровану схемою з прикладу 7.9.1, і знайдемо простішу ФС для її реалізації. Розв’язання. Карта Карно виразу pqr pq r pqr подана на рис. 7.16. Вона має дві пари мінтермів для групування (одну з них не видно при даному позначенні стовпців). pq r 1 r 1 pq pq pq 1 Рис. 7.16. Карта Карно виразу pqr pq r pqr Отже, pqr pqr pq (r r ) pq, pqr pq r (q q ) pr. Це зводить функцію до виразу pq pr або, враховуючи закон дистрибутивності, до виразу p (q r ) . Простіша ФС, яка реалізує функцію з прикладу 7.8.1, показана на рис. 7.17. Рис. 7.17. Спрощена ФС, аналогічна поданій на рис. 7.15 При кресленні ФС нема необхідності використовувати всі типи ФЕ. Як ми вже бачили, множина { , } є повною системою функцій, тому ми можемо побудувати будь-яку схему, обмежившись елементами І та НЕ, а для ще більшої компактності лише одним ФЕ НЕ-І. 7.9. Схема завадостійкого кодування. Код Геммінга Надійність електронних пристроїв внаслідок їхнього удосконалення весь час зростає, але, тим не менше, в їхній роботі можливі помилки, як систематичні, так і випадкові. Сигнал у каналі зв’язку може бути спотвореним завадою, поверхня магнітного носія може бути пошкодженою, в роз’ємі може втратитися контакт. Помилки апаратури ведуть до спотворення або втрати даних, які передають чи зберігають. За певних умов, деякі з яких розглянемо у цьому підрозділі, можна застосувати методи кодування, які дають змогу правильно декодувати вихідне повідомлення, незважаючи на помилки в даних коду. Як досліджувану модель досить розглянути канал зв’язку з завадами, тому що до цього випадку легко звести решту. Наприклад, запис на диск можна розглядати як передачу даних в канал, а читання з диска – як приймання даних з каналу. У процесі зберігання даних і передавання інформації з мереж зв’язку неминуче виникають помилки. Контроль цілісності даних і виправлення помилок є важливим завданням на багатьох рівнях роботи з інформацією (зокрема, фізичному, канальному, транспортному рівнях мережевої моделі). У системах зв’язку можливі кілька стратегій боротьби з помилками. Виявлення помилок у блоках даних і автоматичний запит повторного передавання пошкоджених блоків. Цей підхід застосовують, в основному, на канальному і транспортному рівнях. Виявлення помилок у блоках даних і відкидання пошкоджених блоків. Такий підхід іноді застосовують в системах потокового мультимедіа, де не повинно бути затримки передавання і тому немає часу на його повторення. Виправлення помилок (англ. forward error correction) застосовують на фізичному рівні. Завадостійкі коди – один з найбільш ефективних засобів забезпечення високої вірогідності правильного передавання дискретної інформації. Історія розвитку завадостійкого кодування почалась у 1948 році публікацією знаменитої статті Клода Шеннона, у якій він сформулював теорему для випадку передавання дискретної інформації по каналу із завадами, яка стверджує, що ймовірність помилкового декодування прийнятих сигналів може бути як завгодно малою внаслідок вибору відповідного способу кодування сигналів. Означення 7.9.1. Завадостійке кодування – кодування, що дозволяє при передаванні інформації виявляти або виявляти і виправляти помилки, що виникають у результаті впливу завад. Завадостійкий код – код, отриманий за допомогою цього кодування з вхідної інформації. Очевидно, що для завадостійкості разом з основним повідомленняям треба передавати якусь додаткову інформацію, за допомогою якої у випадку помилок можна відновити вихідне повідомлення. При цьому варто мати на увазі, що і при передаванні додаткової інформації помилки можливі. Задача полягає в тому, щоб визначити, яку додаткову інформацію треба передавати, щоб її об’єм був мінімальним, а процедури кодування і декодування якомога простішими. Отже, завадостійке кодування забезпечують завдяки уведенню надмірності до кодових комбінацій, тобто завдяки тому, що не всі символи в кодових комбінаціях використовують для передавання інформації. Означення 7.9.2. Блоковим кодом називають код, у якому при кодуванні до вхідної інформації додається надлишкова; його позначають (n,k), де n – кількість розрядів у закодованій комбінації (прийнято називати довжиною (значністю) коду), k – кількість інформаційних розрядів вхідної інформації. Якщо вихідні k біт код залишає незмінними, і додає r=nk контрольних, такий код називають систематичним, інакше несистематичним. Величину, на яку збільшується вхідна інформація при блоковому кодуванні, називають надмірністю коду. Надмірність коду (n,k) обчислюють за формулою: Rнад = r/n=(n−k)/п. Означення 7.9.3. Кількість одиниць у кодовій комбінації називають вагою (w). Відстань за Геммінгом характеризує ступінь відмінності будь-яких двох кодових комбінацій, тобто вона виражає число позицій (або символів), у яких ці комбінації відрізняються одна від іншої; її позначають d і визначають як вагу суми за модулем 2 символів двох цих комбінацій. Приклад 7.9.1. Визначити значність і вагу кодової комбінації 1001001, а також відстань за Геммінгом між комбінаціями 10010010 та 11011000. Розв’язання. Кодова комбінація 1001001 характеризується значністю n=7 і вагою w=3. Застосуємо побітове альтернативне “або”: 10010010 11011000 01001010 . Задані комбінації відрізняються в другій, п’ятій та сьомій позиціях. Отже, вага отриманої комбінації w=3, тому відстань між вихідними комбінаціями d=3. ▲ Для виявлення помилки декодер аналізує вхідні сигнали та знаходить за допомогою надлишкової інформації синдром S, який характеризує кількість помилок. Наприклад, найпростіший перешкодостійкий код – контроль парності, додає останній біт так, щоб вага коду була парним числом. Якщо при передачі сталась помилка в одному біті, кількість одиниць буде непарною, а, отже, дані потрібно передавати повторно. Для контрольної суми синдром коду x1 x2 x3 x4 ... xn визначають так: S x1 x2 x3 ... xn . Цей найпростіший випадок водночас є дуже важливим на практиці, зокрема, у сучасних комп'ютерах при передаванні даних внутрішніми шинами. До шини додають додатковий розряд, значення якого визначають при передаванні як двійкову суму решти розрядів. Тому загальна кількість одиниць, яку передають по шині, завжди парна. Якщо при прийманні передана кількість одиниць виявляється непарною, діагностується помилка. Контролем парності вияляють одиничну помилку типу заміщення розряду (коли 1 помилково передана 0 і навпаки), але не мають змоги її виправити. Означення 7.9.7. Кодом Геммінга називають (n, k) – систематичний код, який містить надлишкові (контрольні) біти на позиціях 1, 2, 4, 8, ... 2 r 1 , де 2 r 1 < n=k+r < 2 r , r – кількість контрольних розрядів. Розглянемо побудову коду Геммінга, який дозволяє виправити одиничні помилки типу заміщення розряду. У загальному випадку синдром коду Геммінга p1 p 2 d 3 p 4 d 5 ...d n обчислюють так: S (1 p1 ) (2 p 2 ) (3 d 3 ) ( 4 p4 ) ...( n d n ) . (7.2) Операції та для кодування є побітовими, тобто їх застосовують до кожних відповідних бітів числа. Кожне з чисел 1, 2, 3, 4, 6, 7, 8 та 9 записують у двійковій системі: 1 = 0...0001, 2 = 0...0010, 3 = 0...0011, 4 = 0...0100, 5 = 0...0101, 6 = 0...0110, 7 =0...0111, 8 = 0...1000, 9 =0...1001, і т.д. При кодуванні контрольні біти p1 , p2 , p4 ... p2r 1 вибирають так, щоб синдром (7.2) дорівнював нулю. При застосуванні кон’юнкції до невідомих бітів, для прикладу, до 2 p2 , отримаємо 00 p2 0. Тому детальніший запис бітового подання (7.2) має вигляд (двійкові коди йдуть знизу догори і знак кон’юнкціїї опущений): p1 0 1 0 1 0 1 0 1 0 0 0 0 p2 1 0 0 1 1 0 0 0 0 d p 1 d 1 d 1 d 0 0 d ... 0 (7.3) 3 4 5 6 7 9 p8 1 0 0 0 0 0 0 0 0 ... ... ... ... ... ... ... ... ... ... або p1 d3 d5 d7 ... 0, p2 d3 d6 d7 ... 0, p4 d 5 d 6 d 7 ... 0. Синдром коду Геммінга має наступну особливість: якщо помилка сталась в одному біті, то значення синдрому (..., s4, s3, s2, s1) вказує позицію помилки, якщо у двох бітах, то синдром вказує лише на наявність помилок без можливості їх виправлення. Синдром помилки обчислюють за співвідношеннями, аналогічними (7.3): s1 p1 0 1 0 1 0 1 0 1 s 0 p 1 0 0 1 1 0 0 2 2 s 0 0 0 d p 1 d 1 d 1 d 0 0 d ...(7.4) 3 3 4 5 6 7 9 s4 0 0 0 p8 1 0 0 0 0 ... ... ... ... ... ... ... ... ... ... або s1 p1 d3 d5 d7 ..., s2 p2 d3 d6 d7 ..., s3 p4 d5 d6 d7 ..., s4 p8 d9 .... Отже, метод декодування з виправлення одиночної помилки такий. Обчислюємо синдром помилки, замінюємо знайдений помилковий розряд на протилежний і з виправленого повідомлення виділяємо інформаційні розряди, які вже точно не містять помилок. При k=4 кількість контрольних бітів знаходимо з умови 2 r 1 < 4+r < 2 r , r=3 (4 < 7 < 8). Їх розміщуємо на позиціях 1, 2 та 4, код записуємо у вигляді p1 p 2 d 3 p 4 d 5 d 6 d 7 , його синдром, враховуючи (7.3), має вигляд: p1 0 1 0 1 0 1 0 0 p 2 1 d 3 0 0 d 5 1 d 6 1d 7 0 0 0 0 p 1 1 1 0 4 (7.5) або p1 d3 d5 d7 0, p2 d3 d6 d7 0, p4 d 5 d 6 d 7 0. Бачимо, що кожний з контрольних бітів покриває певні (не всі) інформаційні біти, зокрема, контрольний біт р1 покриває біти d3, d5, d7; р2 покриває біти d3, d6, d7; р4 покриває біти d5, d6, d7. Зауважимо, що цю відповідність можна також отримати з діаграми Ейлера-Венна перетину трьох множин (рис. 7.18), де множинами Аі (і=1, 2, 4) позначено контрольні ( p1 , p 2 , p 4 ) та відповідні їм інформаційні ( d3 , d5 , d6 , d7 ) біти, тобто A1 p1 d 3 d 7 d 5 , A2 p 2 d 3 d 7 d 6 , A4 p4 d 5 d 7 d 6 . Якщо помилки немає, то сума бітів у кожному крузі має бути парною. Якщо це не так, то помилка сталась в розряді на перетині лише кругів з непарними сумами. Наприклад, якщо сума бітів непарна лише в кругах, що відповідають р1 та р4, то помилка сталась в розряді d5. A2 A1 p1 d5 A4 d3 p2 d7 d6 p4 Рис. 7.18. Діаграма Ейлера-Венна для ілюстрації коду Геммінга Помилки знаходять за допомогою перевірних співвідношень синдрому коду Гемінга, аналогічних (7.4): s1 p1 0 1 0 1 0 1 s2 0 p 2 1 d 3 0 0 d 5 1 d 6 1d 7 . s 0 0 0 p 1 1 1 3 4 (7.6) або s1 p1 d3 d5 d7 , s2 p2 d3 d6 d7, s3 p4 d5 d6 d7. Синдром помилки (s3, s2, s1) у випадку однієї помилки вказує на біт, в якому вона сталась. При k=5 кількість контрольних бітів знаходимо з умови 2 r 1 < 5+r < 2 r , r=4 (8 < 9 < 16). Їх розміщуємо на позиціях 1, 2, 4 та 8, код записуємо у вигляді p1 p 2 d 3 p 4 d 5 d 6 d 7 p8 d 9 , його синдром, враховуючи (7.4), має вигляд: 0 1 p1 0 1 0 1 0 1 0 0 0 0 p2 1 0 0 1 1 0 d d d d d 3 5 6 7 9 0 0 0 0 0 p 1 1 1 0 . (7.7) 4 p 0 0 0 0 0 0 0 1 0 8 або s1 p1 d3 d5 d7 d9 , s2 p2 d3 d6 d7, s3 p4 d5 d6 d7. Додатковий контрольний біт р8 покриває лише біт d9, який також покриває і р1 (множина А8 перетинається лише з А1), тобто контрольний біт р1 тепер покриває біти d3, d5, d7, d9. Помилки при k=5 знаходять за допомогою таких перевірних співвідношень: s1 p1 0 1 0 1 0 1 0 1 s2 0 p 2 1 0 0 0 0 1 1 d d d d s 0 0 0 3 p 1 5 1 6 1 7 0 0 d 9 . (7.8) 3 4 p s 0 0 0 0 0 0 0 4 8 1 або s1 p1 d3 d5 d7 d9 , s2 p2 d3 d6 d7, s3 p4 d5 d6 d7, s4 p8 d9. Синдром помилки (s4, s3, s2, s1) у випадку однієї помилки вказує на біт, в якому вона сталась. Приклад 7.9.2. Закодувати двійковим кодом Геммінга комбінацію A = 10111 двійкового простого коду. Визначити надмірність коду Геммінга. Розв’язання. Виконуємо кодування заданої комбінації А. При k=5 кількість контрольних бітів r=4. Їх розміщуємо на позиціях 1, 2, 4 та 8. Записавши код Геммінга у вигляді p1p21p4011p81, визначаємо значення р1, р2, р4, р8, використовуючи формулу (7.7): p1 0 1 0 0 1 0 1 p1 1 1 1 0 0 p 2 1 0 1 1 0 0 p 2 1 1 1 0 0 0 0 p 1 1 0 0 p 1 1 0 . 4 4 0 p p 1 0 0 0 0 0 0 1 8 8 П’ятий біт ми не додаємо, бо він рівний 0. Звідcи: р1 = 1; р2 = 1; р4 = 0; р8 =1. Отже, код Геммінга матиме вигляд 111001111. Його надмірність Rнад = r/п = 4/9. ▲ Приклад 7.9.3. Виправити однократні помилки, якщо при передаванні прийнято кодові комбінації 1101101 та 111001011. Розв’язання. Для виявлення та виправлення помилки у першій комбінації знайдемо синдром помилки, використовуючи (7.6): s1 1 0 0 1 1 1 s2 0 1 0 0 1 0 s 0 0 1 1 1 1 3 Обчислений синдром вказує на помилку в п’ятій позиції (читаємо знизу догори), тобто передане кодове слово було 1101001. Для виявлення та виправлення помилки у другій комбінації знайдемо синдром помилки, використовуючи (7.8): s1 1 0 1 0 0 1 1 s2 0 1 1 1 0 0 1 s 0 0 0 1 0 0 1 . 3 s4 0 0 0 0 1 1 0 Маємо синдром 0111. Отже, спотворено елемент за номером 01112=710, тобто елемент d7. Виправляємо його: замість помилкового елемента d7=0 записуємо значення d7=1 і дістаємо правильну кодову комбінацію 111001111.▲ Коригуючу здатність коду Геммінга можна збільшити введенням додаткової перевірки на парність. Тоді при кодуванні додається останній біт як контрольна сума. Контрольні запитання до теми 7 1. Чим займається булева алгебра? 2. Що називають елементарною кон’юнкцією та мінтермом? 3. Як задають диз’юнктивну нормальну форму (ДНФ) функції та її досконалу диз’юнктивну нормальну форму? 4. Що називають елементарною диз’юнкцією та макстермом? 5. Як задають кон’юнктивну нормальну форму функції та її досконалу кон’юнктивну нормальну форму? 6. Назвіть властивості досконалих форм. 7. Опишіть кроки алгебраїчних перетворень, за допомогою яких можна перетворити довільну функцію у досконалі диз’юнктивну та кон’юнктивну нормальні форми. 8. Опишіть побудову досконалих нормальних форм булевих функцій, заданих таблицями істинності. 9. Що називають функціонально повною системою функцій? Які функціонально повні системи функцій ви знаєте? 10. Що називають скороченою та мінімальною диз’юнктивною нормальними формами? 11. Як співвідносяться між собою тупикова та мінімальна диз’юнктивні нормальні форми? 12. Як будують карту Карно і для чого її використовують? 13. Опишіть алгоритм методу Куайна. Коли його застосовують? 14. Опишіть алгоритм методу Мак-Класкі. Коли його застосовують? 15. Опишіть метод Блейка побудови скороченої диз’юнктивної нормальної форми (СДНФ). Коли його застосовують? 16. Опишіть метод Нельсона побудови СДНФ. Коли його застосовують? 17. Як будують тупикові ДНФ за допомогою імплікантної таблиці Квайна? 18. Опишіть алгоритм методу Петріка знаходження всіх тупикових ДНФ. 19. Які основні функціональні елементи для генерації булевих функцій ви знаєте? 20. Що називають завадостійким кодуванням? 21. Як закодовують послідовність символів, використовуючи код Геммінга? 22. Як знаходять помилки при передаванні повідомлень, закодованих кодом Геммінга? Коли їх можна виправити? 8.1. Правила суми і добутку Комбінаторика – це галузь математики, яка займається підрахунком кількості елементів скінченних множин, тобто їх потужності. Ми вже розв’язували такого роду задачі, використовуючи принцип включень і виключень (розділ 2) і принцип Діріхле (розділ 6). У цьому розділі ми навчимось розв’язувати задачі перерахунку за допомогою двох нових принципів: правил суми і добутку. Загальні задачі перерахунку зв’язані з вибіркою деякого числа елементів з заданої базової множини. Такі задачі можна поділити на типи залежно від того, як вибирають елементи: з повторенням чи без, з врахуванням порядку вибору чи без нього. Ми виведемо формули для кожного з перерахованих типів задач. Познайомимось з біномом Ньютона і встановимо між його коефіцієнтами і однією з формул підрахунку зв’язок, який може бути узагальнений на коефіцієнти, отримані при розкритті дужок у виразі ( x1 x2 ... xk ) n . Ці коефіцієнти співпадають з числом вибірок елементів з множини, деякі з яких можуть повторюватись. Як застосування деяких формул комбінаторики у задачах інформатики розглянемо ефективність алгоритмів. Сформулюємо декілька простих задач. Задача 1. Студент може вибрати тему курсової роботи з трьох розділів, кожен з яких містить 20, 15 та 17 тем відповідно. Скількома способами він може здійснити вибір теми? Задача 2. Необхідно вибрати змішану команду, яка буде грати на змаганнях від місцевої тенісної секції. В секції є 6 дівчат і 9 хлопців. Скільки різних пар можна вибрати для участі у змаганнях? Задача 3. Скільки тризначних чисел починається з 3 чи 4? Першу задачу розв’язуємо простим сумуванням – додаємо кількості тем: 20+15+17=52; серед них студент може вибирати. У другій задачі є 6 дівчат, з яких ми можемо вибрати представницю секції, і для кожної з них можемо підібрати партнера серед 9 хлопців. Загальна кількість різних пар, які ми можемо скласти, дорівнює 6х9=54. Ці дві задачі ілюструють два фундаментальні правила перерахунку. Правило суми каже: якщо А і В – незв’язані події, і існує п1 можливих варіантів події А та п2 можливих варіантів події В, то можлива кількість варіантів події «А або В» дорівнює сумі п1+ п2. Правило добутку стверджує: якщо є послідовність k подій з п1 можливими варіантами першої, п2 – другої аж до пk можливих варіантів останньої, то загальна кількість варіантів послідовності k подій дорівнює добутку n1 n2 ... nk . Правило суми по суті – частковий випадок формули включень і виключень. Дійсно, якщо розглядати А і В як множини варіантів, то |А|= п1, |В|= п2; оскільки події А і В не пов’язані між собою, то можна вважати, що відповідні множини не перетинаються. Тоді за формулою включень і виключень | A B | =|А|+|B|, тобто множина A B містить п1+п2 елементів. Це означає, що існує п1+п2 можливих варіантів події «А або В». Правило добутку теж можна сформулювати на мові теорії множин. Нехай А1 позначає множину п1 варіантів першої події, А2 – множину п2 варіантів другої, і т.д. Тоді будь-яку послідовність k подій можна розглядати як елемент декартового добутку А1 х А2 х ... х Аk, потужність якого рівна |А1 ||А2|...|Аk|. Неформально правила суми і добутку можна сформулювати так. Нехай існують деякі можливості побудови комбінаторної конфігурації. Якщо ці можливості взаємно виключають одна одну, то їх кількість треба додавати, а якщо можливості незалежні, то їх кількості треба перемножувати. Тепер ми готові розв’язувати третю зі сформульованих задач, використовуючи обидва правила. Тризначні числа, що задовольняють умову задачі, природнім чином розбиваються на два неперетинальні класи: до 1-го належать числа, які починаються з 3, до 2-го – з 4. Для підрахунку чисел в 1-му класі зауважимо, що існує один можливий варіант для першої цифри (вона має дорівнювати 3), 10 варіантів для другої і 10 варіантів для останньої. За правилом добутку одержимо, що всього чисел в 1-му класі нараховують 1 10 10=100. Аналогічно можна підрахувати кількість чисел в 2-му класі – вона теж рівна 100. Нарешті, за правилом суми отримаємо, що існує 100+100=200 тризначних чисел, які починаються з 3 або 4. Приклад 8.1.1. Дівчинка хоче взяти до школи 2 фрукти. Вдома є 3 банани, 4 яблука і 2 грушки. Скількома способами вона може вибрати 2 фрукти різного виду з наявних у допущенні, що два фрукти одного найменування різняться між собою? Розв’язання. Якщо дівчинка планує взяти один з 3-х бананів і одне з 4-х яблук, то вона може це зробити 3 4=12 різними способами. Банан і грушку можна взяти 32=6 можливими способами. Нарешті грушку і яблуко можна вибрати 4 2=8 різними способами. Оскільки всі три множини можливостей різні, то всього кількість способів, якими можна вибрати 2 фрукти, дорівнює 12+6+8=26. ▲ 8.2. Комбінаторні формули Допустимо, що дитині запропонували мішок з цукерками трьох назв: «Ромашка» (А), «Червоний мак» (В) і «Зоряне сяйво» (С). Скількома способами дитина може вибрати 2 цукерки з мішка? На це запитання можна дати декілька відповідей залежно від уточнення формулювання. Ставлячи задачу, ми не уточнили, можна брати цукерки однієї назви чи ні. Крім того, чи має значення порядок вибору, тобто відрізняється АВ від ВА чи ні? Отже, маємо 4 різні уточнення формулювання. 1. Повторення дозволені і порядок вибору істотний. У цьому випадку маємо 9 можливостей: АА, АВ, АС, ВА, ВВ, ВС, СА, СВ і СС. 2. Заборонено брати цукерки однієї назви, але порядок істотний. У цій ситуації – 6 випадків: АВ, АС, ВА, ВС, СА і СВ. 3. Повторення дозволені, але порядок вибору не має значення. Тоді відповідь – теж 6 можливостей: АА, АВ, АС, ВВ, ВС і СС. 4. І, нарешті, якщо не можна брати однакові цукерки, а порядок не має значення, то у дитини є лише 3 варіанти вибору: АВ, АС і ВС. При розв’язуванні конкретних задач на підрахунок кількості способів необхідно чітко розуміти, про який тип уточнення формулювання йде мова. Щоб розрізняти на термінологічному рівні тип конкретної задачі, уведемо декілька означень. Почнемо з допоміжних термінів. Означення 8.2.1. Набір х1, х2, ..., хk з множини Х потужності п називають вибіркою об’єму k з п елементів або (п, k)-вибіркою. Вибірку називають впорядкованою, якщо порядок слідування елементів заданий. Якщо порядок слідування елементів у вибірці не має значення, то вибірку називають невпорядкованою. Дві впорядковані вибірки, які відрізняються лише порядком слідування елементів, вважають різними. Означення 8.2.2. (п, k)-розміщенням з повтореннями називають впорядковану (п, k)-вибірку, елементи в якій можуть повторюватись. (п, k)-розміщенням без повторень називають впорядковану (п, k)-вибірку, елементи в якій не можуть повторюватись. Означення 8.2.3. (п, k)-сполученням з повтореннями називають невпорядковану (п, k)-вибірку, елементи в якій можуть повторюватись. (п, k)-сполученням без повторень називають невпорядковану (п, k)-вибірку, елементи в якій не можуть повторюватись. Спробуємо підрахувати кількість всіх різних (п, k)-розміщень з повтореннями. На перше місце вибірки ми можемо поставити будь-який з п елементів множини. Оскільки повтори дозволені, то на друге місце ми знову можемо поставити будь-який елемент з цієї множини, і т. д. Оскільки у нас k місць у вибірці, то спираючись на правило добутку, отримаємо, що кількість всіх (п, k)-розміщень з повтореннями дорівнює ~ Ank пk (8.1) ~ (зустрічається також і позначення A(n, k ) ). Приклад 8.2.1. Цілі числа в комп’ютері подають рядком з N двійкових символів. Перший з них відведено на знак (+ або -), а решта N-1 відповідають за модуль цілого числа. Скільки таких різних цілих чисел може використовувати комп’ютер? Розв’язання. Двійкова цифра – це 0 або 1. Для запису числа використовується N таких цифр. Зауважимо, що двійкові рядки, які зображають числа, можуть мати цифри, що повторюються, і порядок їх слідування істотний для даної задачі. Тому ми маємо справу з (2, N)-розміщеннями з повтореннями. За формулою (8.1) отримуємо, що ~ загальна кількість таких рядків дорівнює A2N 2N. Практично завжди різні розміщення зображають різні числа, за винятком двох рядків: -0000...000 і +0000...000, які зображають 0. Тому комп’ютер може оперувати (2N-1) цілими числами. ▲ Підрахуємо кількість всіх (п, k)-розміщень без повторень. На перше місце вибірки ми можемо поставити будь-який з п елементів. Оскільки повторення не дозволені, то на друге місце ми можемо вибрати будь-який з (п-1) решти елементів, на третє – з (п-2) і так далі аж до k-го місця, куди можна написати будь-який з (п-k+1) елементів. Для кінцевої відповіді нам треба застосувати правило добутку. Маємо, ввівши позначення, Ank n(n 1)...(n k 1) (зустрічається також й позначення A(n, k ) ). Перетворимо останній запис: (8.2) Ank n(n 1)...(n k 1) (n k )(n k 1)...2 1 n! . (n k )(n k 1)...2 1 (n k )! Отже, кількість всіх (п, k)-розміщень без повторень рівна Ank n! . (n k )! (8.3) Формули (8.2), (8.3), виведені для кількості розміщень без повторень, дають привід поговорити про елементарні, але дуже важливі, речі. Формула (8.2) виглядає складною і незавершеною, а (8.3) – елегантною і математичною. Однак при практичному обчисленні перша формула має набагато більше переваг, ніж друга. Поперше, для обчислення за нею треба т-1 множення, за другою – 2т-п-2 множень і одне ділення. Оскільки п<m, перша формула обчислюється істотно швидше. По-друге, число Аnт росте доволі швидко і при великих п може не поміститися в розрядну сітку. При обчисленні за другою формулою преповнення може настати «раніше часу», тобто проміжні результати не поміщаються в розрядку сітку, хоч кінцевий результат міг би поміститися, оскільки факторіал – функція, яка дуже швидко зростає. Приклад 8.2.2. Скільки різних «слів» з 4-х літер можна написати, використовуючи літери: а, л, с, п, о, е, якщо під словом розуміти будь-яку послідовність літер, що не повторюються, навіть, якщо вона не має жодного сенсу? Розв’язання. Ми маємо з 6-ти даних літер вибрати послідовності з 4-х, тобто треба підрахувати кількість розміщень без повторень за формулою (8.3): A64 6! 6! 6 5 4 3 360. ▲ (6 4)! 2! Тепер займемося сполученнями без повторень. Оскільки розміщення без повторень відрізняється від сполучень без повторень наявністю порядку, то число Ank , очевидно, є більшим за те, яке ми хочемо зараз знайти. Проведемо експеримент. Зафіксуємо множину А={1, 2, 3, 4}, тобто п=4, а вибирати будемо послідовності 3-х різних цифр з 4-х даних, не враховуючи порядку, тобто k=3. Наприклад, підмножина {1, 2, 3} є (4, 3)-сполученням без повторень. Переставивши цифри у вибраній підмножині {2, 1, 3} ми отримаємо те ж саме сполучення (бо тут порядок неважливий), але цілком інше розміщення (бо там порядок важливий). То ж скільки різних розміщень можна утворити з одного сполучення? У цьому конкретному випадку, перебравши всі варіанти, отримаємо 6. Сформулюємо запитання в загальному випадку: Дано (п, k)-сполучення без повторень, тобто вибрано підмножину B A , де |В|=k і |А|=п. Скільки з нього можна отримати різних (п, k)-розміщень без повторень? Фактично нам треба підрахувати кількість (k, k)-розміщень без повторень, тобто Akk k! k! k!, бо 0!=1 (існує єдина можливість не зробити жодного вибору зі (k k )! 0! скінченної множини об’єктів). Отже, на кожне (п, k)-сполучення без повторень маємо k! різних (п, k)-розміщень без повторень. Тому, ввівши позначення, маємо кількість всіх (п, k)-сполучень без повторень Cnk Ank n! . k! (n k )!k! (8.4) Зауважимо, що зустрічається також і позначення C (n, k ) та (nk ) . Приклад 8.2.3. Меню в китайському ресторані дає можливість вибрати 3 страви з 7 головних страв. Скількома способами можна зробити замовлення? Розв’язання. Тут ми маємо справу з (7, 3)-сполученнями без повторень. За формулою (8.4) знайдемо: C73 7! 1 2 3 4 5 6 7 5 7 35 . ▲ (7 3)!3! 1 2 3 4 1 2 3 Нам залишилось знайти кількість сполучень з повтореннями. Згрупуємо однакові елементи, розділивши групи якимись мітками (порядок тут значення не має). Допустимо, що ми зробили вибірку з 5 літер, кожна з яких може бути однією з а, б, в, наприклад, аа\б\вв, а\\вввв. Домовимось, що зліва від першої мітки або є літери а, або нічого, справа від другої мітки – або в, або нічого, а літери б, якщо вони є, знаходяться між мітками. Тому можна вважати, що ми завжди маємо 7 комірок (5 літер і 2 мітки), причому вибірки відрізняються комірками, в яких є мітки. Отже, кількість всіх таких сполучень з повтореннями співпадає з кількістю способів, якими ми можемо помістити дві мітки до 7 комірок. Залишилось зрозуміти, що ця кількість є не що інше, як кількість всіх (7, 2)-сполучень без повторів, тобто дорівнює C72 . Дійсно, першу мітку можна поставити в будь-яку з 7 комірок, другу – в будь-яку з 6, оскільки одна комірка вже зайнята. Це дає нам 7 6 можливостей. Зауважимо, що помінявши розставлені мітки місцями, ми отримаємо те саме заповнення комірок, тому 42 треба поділити на 2. Отже, кількість способів рівна: 7 6 (1 2 3 4 5) 6 7 7! C75 (C72 ) H 35 . 2 (1 2 3 4 5) 1 2 5!2! Повертаючись до загального випадку (п, k)-сполучення з повтореннями (k об’єктів з п даних), зауважимо, що нам потрібно п-1 мітку і k об’єктів, тобто ми матимемо (п1+k) комірок для заповнення. Отже, кількість (п, k)-сполучень без повторень співпадає з кількістю способів розміщення (п-1) мітки в (п+k-1) комірку. Тому загальна кількість (п, k)-сполучень з повтореннями рівна H nk Cnn1k 1 (n k 1)! (n k 1)! Cnk k 1 . (n k n 1)!(n 1)! (n 1)!k! (8.5) Приклад 8.2.4. Скільки різних варіантів можна отримати, кинувши 5 гральних кубиків? Розв’язання. На кожній грані може випасти від 1 до 6 очок, тобто кожен кубик дасть 6 варіантів. Якщо кинули 5 кубиків, то кожен варіант можна розглядати як невпорядкований набір 5 об’єктів (для кожного з яких є 6 можливостей) з повтореннями, тобто (6,5)-сполучення з повтореннями. За формулою (8.5) знайдемо: H 65 C6551 10! 252 . ▲ 5!5! У табл. 8.1 зібрані разом всі формули для підрахунку кількості вибірок k елементів з п-елементної множини. Таблиця 8.1 Порядок істотний Порядок неістотний Елементи повторюються розміщення з повтореннями ~ Ank пk сполучення з повтореннями Елементи не повторюються розміщення без повторень сполучення без повторень Ank n! (n k )! H nk Сnk k 1 Cnk (n k 1)! (n 1)!k! n! (n k )!k! Приклад 8.2.8. 12 людей, включаючи Марію і Петра, є кандидатами в комітет, який має бути обраний з 5 людей. Скільки різних комітетів можна набрати з 12 кандидатів? До скількох з них: а) входять Марія і Петро, б) не вхлдять ні Марія, ні Петро, в) входять або Марія, або Петро, але не обидвоє? Розв’язання. 5 Існує C12 12! 792 можливих комітети. 7!5! а) якщо Марію і Петра вже вибрано в комітет, нам залишається вибрати в нього лише 3 3 члени з решти 10 кандидатів. Це можна зробити C10 10! 120 способами. Отже, 7!3! Марія і Петро можуть бути членами 120 різних комітетів. б) якщо Марія і Петро не беруть участі у комітеті, то ми вибираємо всіх його членів 5 серед 10 кандидатів. Тому ми маємо C10 10! 252 можливості для різних комітетів, 5!5! до яких не входять ні Марія, ні Петро. в) один зі способів дати відповідь на це запитання – порахувати комітети, до яких 4 входтть Марія, але без Петра. Їх є C10 10! 210 , до такої самої кількості комітетів 6!4! 4 входить Петро, але без Марії. Отже, 2 C10 =420 комітетів мають своїм членом або Марію, або Петра, але не обох разом. Інший підхід до розв’язання оснований на тому, що кожен з 792 можливих складів комітету можна віднести до однієї з категорій: а), б) чи в). Тому кількість комітетів, які належать останній, дорівнює 792-120-252=420. ▲ 8.3. Біном Ньютона Числа Cnk виникають як коефіцієнти при розкритті дужок в біномі (а+b)n. Наприклад, (а+b)3=(a+b)(a+b)(a+b)=aaa+aab+aba+abb+baa+bab+bba+bbb= =а3+3a2b+3ab2+b3. Кожен з 8 доданків, які є після другого знаку рівності, отримано при множенні 3-х змінних, які ми вибираємо по одній з кожної дужки. Ми бачимо, зокрема, що рівно 3 доданки містять одну змінну а і дві b, тому що ми маємо C32 3 способи вибору двох дужок з трьох, звідки візьмемо змінну b (і з тої, що залишилась, беремо а). Аналогічно отримуємо й інші коефіцієнти цього виразу: C30 1 , C31 3 і C33 1 . Щоб узгодити отримані числа з формулою для Cnk (8.4), ми маємо допустити, що 0!=1. У загальному випадку, розкриваючи дужки в біномі (а+b)n, ми будемо отримувати члени вигляду ап-k bk (де k набує кожного зі значень від 0 до п) при перемноженні символів b, взятих з k дужок, і а, взятих з решти (п-k) дужок. Оскільки є Cnk способів вибору k дужок з п, то ми матимемо точно Cnk членів вигляду ап-k bk при k=0, 1, ..., п. Отже, (a b ) n Cn0 a n C1n a n 1b Cn2a n 2b 2 ... Cnnb n n Cnk a n k b k . (8.6) k 0 Цю формулу називають біномом Ньютона, а коефіцієнти Cnk – біноміальними коефіцієнтами. Їх корисно розмістити в так званий трикутник Паскаля (рис. 8.1): C00 C10 C20 C30 ... Cn0 C12 C31 ... C1n C11 C22 C32 ... ... C33 ... ... ... Cnn 1 Cnn Рис. 8.1. Трикутник Паскаля Кожен (п+1)-й рядок цього трикутника містить біноміальні коефіцієнти, отримані при розкритті дужок у виразі (а+b)n. Обчисливши декілька перших коефіцієнтів трикутника Паскаля, ми одержимо 1 1 1 1 1 1 1 ... 2 3 3 4 5 ... 1 6 10 ... 1 4 10 ... 1 5 ... 1 ... ... Оскільки Cn0 = Cnn =1, на зовнішніх сторонах трикутника Паскаля завжди є одиниці. Симетрія відносно вертикальної висоти трикутника випливає з тотожності: Cnk = Cnn k . Є й інші закономірності, які ми можемо побачити. Наприклад, додавши два послідовні числа у рядку, ми одержимо число з наступного рядка, яке знаходиться між двома доданими. Ця властивість відома як формула Паскаля: Cnk11 Cnk1 Cnk , (8.7) яка справедлива для 0<k<n. Доведення формули полягає в послідовності перетворень: (n 1)! (n 1)! (n 1)! 1 1 (n k )!(k 1)! (n k 1)!k! (n k 1)!(k 1)! n k k (n 1)! n n! Cnk . (n k 1)!(k 1)! (n k )k (n k )!k! Cnk11 Cnk1 Приклад 8.3.1. У виразі 53 3 100 розкрили дужки за формулою бінома Ньютона. Скільки з отриманих доданків є раціональними? Розв’язання. Запишемо (k+1)-й член розкладу 100k k k Tk 1 C100 5 2 33 . k Оскільки C100 є натуральним числом, вираз 100 k k 5 2 33 буде раціональним, якщо одночасно будуть цілими числами вирази 100 k k і . Це можливе для k=0, 6, 12, 2 3 18,..., 96, тобто, враховуючи формулу для п-го члена арифметичної прогресії, кількість a a 96 0 п перерахованих значень k дорівнює n n 1 1 1 =17. ▲ d 6 Наведемо ще декілька властивостей біноміальних коефіцієнтів. r n r 1. Правило симетрії. Нехай n і r – невід’ємні числа, n r . Тоді Cn Cn . n n k 1 k 1 k n 2. Винесення за дужки. Cnk Cnk11 , Cnk Cn , Cn Cnk1 . k nk k 3. Заміна індексів. Cnm C mk C nm C nmkk . 0 1 n n 4. Cn C n ... C n 2 . Доведення. Поклавши в біномі Ньютона (8.6) а=b=1, ми одержимо Cn0 C 1n ... C nn (1 1) n 2 n. 0 1 2 n n 5. Cn Cn Cn ... (1) C n 0. Доведення. Підстановка в біном Ньютона (8.6) а=1, b=-1 дає Cn0 C1n Cn2 ... (1) n Cnn (1 1) n 0. 6. Сума коефіцієнтів парних членів розкладу дорівнює сумі коефіцієнтів непарних членів розкладу: Cn0 Cn2 ... Cn2m ... C1n Cn3 ... Cn2m 1 ... , причому кожна з цих сум дорівнює 2п-1, тобто n 2 k 0 Cn2k n 2 Cn2k 1 2 n 1 . k 0 Доведення. Переписавши формулу, яку треба довести, у вигляді: Cn0 Cn2 ... Cn2m ... (C1n Cn3 ... Cn2m 1 ...) 0, Cn0 C1n Cn2 ... (1) n Cnn 0, та врахувавши властивість 5, бачимо, що перша частина властивості 6 доведена. Позначимо вказані суми через А і В відповідно: Cn0 Cn2 ... Cn2m ... A, C1n Cn3 ... Cn2m 1 ... B. Додамо і віднімемо ліві й праві частини сум та скористаємося властивостями 4 і 5: А+В=2п, А-В=0 А=В, 2А=2п, А=2п-1, В=2п-1. n 7. Теорема 8.1. kCnk n2n 1 . k 1 Доведення. Спосіб 1. Розглянемо послідовність, складену з чисел 1,..., п. Спочатку випишемо всі числа довжиною 0, потім всі числа довжиною 1 і т.д. Маємо Cnk підмножин потужності k, де кожна підмножина має довжину k, тобто всього в цій n послідовності kCnk чисел. З іншого боку, кожне число х входить у цю послідовність k 0 2 n 1 разів, а всього чисел п. Спосіб 2. Поклавши в біномі Ньютона (8.6) а=х, b=1, одержимо n n ( x 1) Cnk x k . k 0 Взявши похідну від останнього виразу, маємо n n (( x 1) n )' ( Cnk x k )' n( x 1) n 1 k 0 kCnk x k 1 . (8.8) k 1 Поклавши в (8.8) х=1, одержимо шукану формулу: n2 n 1 n kCnk . k 1 n 8. (1)k 1 kCnk 0 . k 1 Доведення. Поклавши в (8.8) х=-1, одержимо шукану формулу: n 0 (1)k 1 kCnk . k 1 9. Теорема 8.2 (згортка Вандермонда). Нехай т, n, r — невід’ємні цілі числа, r причому r min{m, n}. Тоді Cnrm Cmr k C nk . k 0 Доведення. Спосіб 1. Cnr m – це число способів вибрати r предметів з п+т предметів. Предмети можна вибирати в два прийоми: спочатку вибрати k предметів з перших п предметів, а потім ще r-k предметів (тих, що не вистачає) з т предметів, які r залишилися. Тому загальне число способів вибрати k предметів складає Cmr k Cnk . k 0 Спосіб 2. ( x 1) nm n ( x 1) (1 x ) m Cmr n r Cnk Cmr k . k 0 Наслідок. C2nn n (Cnk )2 . k 0 10. Унімодальність. Означення 3.1. Послідовність ( p n ) дійсних чисел називають унімодальною, якщо існує такий натуральний номер m, що p 0 p1 ... p m ; pm pm 1 pm 2 ... pn , тобто: послідовність строго зростає на відрізку 0, m, m 0; послідовність строго спадає на відрізку m 1, n , m 1 n; максимального значення досягають не більш ніж у двох точках: m і можливо, m+1. За фіксованого n послідовність біноміальних коефіцієнтів C kn , k=0,1,2…,n n унімодальна, т= ([а] – ціла частина числа а). У разі парного n максимум досягається 2 n 1 n n n n 1 в точці т = = , а в разі непарного — у двох точках: т = = й m+1= . 2 2 2 2 2 8.4. Перестановки. Поліноміальна формула Означення 8.4.1. Перестановкою без повторень з п елементів називають розміщення без повторень з п по п елементів, тобто в розміщення входять усі елементи. Перестановки з п елементів називають також п-перестановками, їх кількість позначають Рп. Означення 8.4.2. Нехай є n елементів r різних типів, а число ni (i=1,…,r) – кількість елементів i-гo типу. Очевидно, що n1+п2+...+nr=п. Перестановки з n елементів за такої умови називають перестановками з повтореннями, а їх кількість позначають Рn(п1, п2,..., nr). Розглянемо задачу про кількість перестановок. Спочатку, для прикладу, розглянемо слово «колобок». Воно складене з 7 букв, які можна переставити 7! способами. Однак в ньому є 3 букви «о» та 2 букви «к», міняючи які місцями ми не отримаємо нових «слів». Оскільки кількість перестановок трьох елементів рівна 3!, а двох – 2!, то ми можемо отримати лише 7! 420 різних «слів» із заданого слова. 2!3! В загальній ситуації справедлива така теорема. Теорема 8.3 (теорема про перестановки без повторень та з повтореннями). Існує Pn n! (8.9) різних перестановок п об’єктів, які не повторюються, та Pn (n1, n2 ,..., nr ) n! n1!n2!...nr ! (8.10) різних перестановок п об’єктів, з яких пі належить до і-го типу (і=1,..., r). Приклад 8.4.1. Знайдемо кількість рядків, які можна утворити, переставляючи букви слова SOFTWARE. Розв’язання. Оскільки жодна буква тут не повторюється, то, враховуючи (8.9). можна утворити Р8 =8!= 40320 рядків. ▲ Приклад 8.4.2. Скількома способами можна розподілити 15 студентів на 3 групи по 5 студентів у кожній? Розв’язання. Це можна зробити, враховуючи (8.10), 15! 68796 різними способами. ▲ 5!5!5! Означення 8.4.2. Поліноміальна формула – це формула для розкладу на окремі складові цілого невід’ємного степеня суми кількох змінних, що має вигляд суми всіх можливих доданків Pn n1, n2 ,..., nr x1n1 x2n2 ...xrnr , де n1 n2 ... nr n, тобто Pn1, n2 ,..., nr x1n x2n x1 x2 ... xr n 1 n1 0,..., nk 0, n1 ... n r n 2 ... xrn r . Поліноміальна формула є узагальненням біному Ньютона, в чому можна переконатись, підставивши r=2 до поліноміальної формули. Коефіцієнти n! називають мультиноміальними. Вони стоять при добутках n1!n2!...nr ! x1n1 x2n2 ...xrnr у розкладі степеня ( x1 x2 ... xr ) n . В цьому легко переконатись, оскільки член вигляду x1n1 x2n2 ...xrnr ми отримуємо, коли перемножуємо змінні х1, n n вибрані з п1 дужок, х2, вибрані з п2 дужок, і т.д. Тому коефіцієнт при x1 1 x2 2 ...xrnr рівний кількості перестановок п об’єктів, з яких пі належить до і-го типу (і=1,..., r). Приклад 8.4.3. Знайдемо а) коефіцієнт при x3y2z4 з розкладу степеня (х+у+z)9; б) коефіцієнт при x3y2 з розкладу степеня (х+у+3)7. Розв’язання. а) Коефіцієнт при x3y2z4 з розкладу степеня (х+у+z)9 дорівнює 9! 1260 . 3!2!4! б) Коефіцієнт при x3y2z2 з розкладу степеня (х+у+z)7 дорівнює 7! 210 . 3!2!2! Тому розклад степеня (х+у+z)7 містить член 210x3y2z2. Поклавши z=3, ми побачимо, що в розкладі степеня (х+у+3)7 є член 1890x3y2. Тому коефіцієнт при x3y2 з розкладу степеня (х+у+3)7 дорівнює 1890. ▲ 8.5. Моделі задач Щоб легше було розв’язувати комбінаторні задачі, розглянемо дві різні моделі для введених комбінаторних понять. Кожна модель є насправді розв’язаною задачею. 8.5.1. Букви і слова Нехай маємо деякий набір різних символів – назвемо їх буквами, довільну послідовність букв назвемо словом, а кількість букв у слові – довжиною слова. 1. Нехай маємо п різних букв, по одному екземпляру кожної (наприклад, букви написані на кубиках). Кількість слів довжини k, які можна скласти з цих букв: Апk . 2. Нехай маємо букви k типів, достатньо багато букв кожного типу. Кількість слів ~ довжини п, які можна скласти з цих букв: Апk . 3. Нехай знову маємо п різних букв, по одному екземпляру кожної. Кількість слів довжини п, які можна скласти з цих букв, тобто кількість різних перестановок кубиків: Pn n! . 4. Нехай маємо букви k типів, достатньо багато букв кожного типу. Кількість слів довжини п, в яких рівно nj букв j-го типу, j 1, k , n1 n2 ... nk n : Pn ( n1 , n2 ,..., nk ) . 5. Нехай маємо букви лише двох типів (наприклад, символи 0 і 1), але достатньо багато символів кожного типу. Кількість слів довжини п, в яких рівно k символів першого типу і п-k символів другого типу (або кількість послідовностей довжини п, в яких k одиниць і п-k нулів): Cпk . 6. Така модель не дає доброї інтерпретації для H пk , якщо не брати до уваги те, що H пk – це кількість послідовностей довжини п+k-1, в яких рівно k одиниць і п-1 нуль. 8.5.2. Предмети і скриньки 1. Маємо п різних предметів і k різних скриньок (наприклад, скриньки пронумеровані), k n . Кількість різних способів розкласти предмети у скриньки по одному в кожну (очевидно, що не всі предмети будуть розкладені при k n ): Апk . 2. Маємо п різних предметів і k різних скриньок, причому кожна скринька може вмістити і всі предмети. Кількість різних способів розкласти предмети у скриньки ~ без будь-яких обмежень: Апk . 3. Маємо п різних предметів і п різних скриньок. Кількість різних способів розкласти предмети у скриньки по одному в кожну: Pn . 4. Маємо п різних предметів і k різних скриньок (предмети приблизно однакові за розміром). Відомо, що перша скринька вміщує n1 предметів, друга – n2 предмети, і т.д., k-а скринька вміщує nk предметів ( n1 n2 ... nk n ). Кількість різних способів розкласти предмети у ці скриньки: Pn ( n1 , n2 ,..., nk ) . 5. Маємо п різних предметів і дві різні скриньки, причому перша скринька вміщує k предметів, а друга – n-k предмети. Кількість різних способів розкласти предмети у ці скриньки: Cпk . Інша модель. Нехай є п різних скриньок і k однакових предметів ( k n ). Кількість різних способів розкласти предмети у ці скриньки по одному в кожну: Cпk . 6. Нехай є п різних скриньок і k однакових предметів, причому кожна скринька може вмістити і всі предмети. Кількість різних способів розкласти предмети у ці скриньки: H пk . 8.5.3. Перестановки на відрізку і на колі Якщо ми маємо п-елементну множину А, то переставляти її елементи можна Pn способами (уявляємо собі, що на деякому відрізку є п пронумерованих місць, які й мають зайняти елементи множини А). Нехай тепер в множині А виокремлена k-елементна підмножина В ( k n ). Скількома способами можна переставити елементи множини А так, щоб всі елементи множини В стояли поряд? Елементи множини В можна переставляти k! способами. Уявимо всю цю множину як один елемент, а елементи (п-k+1)-елементної множини можна переставляти (п-k+1)! способами. Тому разом матимемо k!(п-k+1)! спосіб. Якщо в попередній задачі послідовність елементів множини В задана умовою задачі, то нема потреби домножувати на k!, тому відповідь така: (п-k+1)!. Скільки є перестановок множини А, в яких не всі елементи множини В стоять поряд? Від всіх перестановок віднімемо непотрібні: п! - k!(п-k+1)! Тепер нехай елементи множини А треба розмістити на колі. Уявляємо собі, що на колі є п пронумерованих місць, на які мають розташуватися елементи множини А. Скількома способами це можна зробити? Зрозуміло, що ситуація нічим не відрізняється від випадку розташування елементів на відрізку, і відповідь буде п!. Але далі все зміниться. Нехай місця на колі відмічені, але не пронумеровані (наприклад, коло крутиться). Скільки тоді буде різних перестановок елементів множини А? Потрібно всі перестановки, отримані в першому випадку, поділити на п – кількість «прокруток» кола навколо осі. Маємо (п-1)! перестановку. Якщо не має значення за годинниковою стрілкою чи проти дивитися на коло, то відповідь буде (п-1)!/2 (ототожнюємо два дзеркально симетричні розташування). Нехай знову маємо коло з пронумерованими місцями. Скільки є перестановок елементів множини А таких, що всі елементи виділеної k-елементної підмножини В розташовані поряд? Переставляємо елементи множини В k! способами, а потім (п-k)! способами переставляємо елементи її доповнення і отриману картину прокручуємо п разів навколо осі: п k! (п-k)! Якщо місця на колі не пронумеровані, то відповідь буде простіша: k! (п-k)!. Якщо ще й ототожнити дзеркально симетричні розташування, то отримаємо таку відповідь: k! (п-k)!/2. Нехай порядок розташування елементів множини В заданий умовою задачі. Тоді на колі із заданою нумерацією буде п(п-k)! перестановок множини А, на колі без нумерації їх буде (п-k)!, а якщо ще й не звертати уваги на орієнтацію кола, то матимемо (п-k)!/2 перестановок. Якщо п=2k, тобто множини В і А\B є рівнопотужні, то можна сформулювати таку задачу: скільки є таких перестановок елементів множини А на відрізку, що елементи множини В стоять на місцях з парними номерами (елементи множини А\B відповідно на місцях з непарними номерами)? Таких способів буде (k!)2 – елементи двох множин переставляють незалежно. Відповідь не зміниться, якщо ці місця вказані на колі. Нехай умова така: жодні два елементи множин В і А\B не стоять поряд на відрізку. Матимемо тоді 2(k!)2 таких перестановок, те саме стосується і місць, вказаних на колі. Якщо елементи множини А мають бути розташовані на колі без вказаної нумерації, то кількість таких перестановок, що жодні два елементи множини В не стоять поруч, буде 2(k!)2/(2k)=k!(k-1)!. Якщо ж ще й не звертати увагу на орієнтацію кола, матимемо k!(k-1)!/2. Накінець, нехай А=В1 В2 В3 (підмножини попарно не перетинаються), |В1|=|В2|=|В3|=k. Cкільки є перестановок елементів множини А на відрізку, якщо елементи підмножин Ві (і=1, 2, 3) мають бути розташовані на місцях з номерами вигляду 3р+і, р=0, 1, 2, ...? Аналогічно випадку двох підмножин таких способів буде (k!)3. А скільки буде всіх перестановок множини А таких, що кожен елемент має сусідів з двох інших підмножин? Очевидно, що 3! (k!)3. Якщо ми хочемо розташувати так ці елементи на колі без вказаної нумерації місць, то це можна зробити 3! (k!)3/(3k)= 2 (k!)2/(k-1)! способами. 8.6. Алгоритми генерування комбінаторних об’єктів та лексикографічний порядок Алгоритми генерування дуже великого числа варіантів використовують у прикладних дискретних задачах, таких як пошук оптимального рішення, відбір елементів за певними умовами, тощо. Для генерування елементів використовують алгоритми генерування, рекурсії та генерування з поверненням. Найбільш відомі два алгоритми генерування вибірок – рекурсивний і алгоритм лексикографічного порядку перестановок. Стандартна бібліотека шаблонів STL мови програмування С++ містить реалізований алгоритм для знаходження наступної в лексикографічному порядку перестановки next_permutation. Розглянемо алгоритми генерування, які полягають в генерації всіх можливих варіантів усіх об’єктів, що задовольняють певні умови. Спочатку розглянемо перебір усіх вибірок із множини А. Для спрощення записів задачі розміщення (а1, а2,..., аr) позначатимемо як a1a 2 ...ar і розглядатимемо розміщення множини А={1, 2,…, п} – індексів об’єктів, оскільки довільну множину можна проіндексувати шляхом присвоєння кожному об’єкту індивідуального номеру. Для генерування набагато зручніше користуватись індексами, а не реальними об’єктами. Для реалізації генерування потрібно: встановити лексикографічний порядок елементів, що підлягають перерахуванню (зокрема, визначити, який з них буде першим, а який останнім); знайти алгоритм переходу від довільного елемента до лексикографічно наступного (безпосередньо наступного) за ним. Алгоритм ґрунтується на послідовному переході по елементах у лексикографічному порядку, починаючи від мінімального і завершуючи максимальним. Означення 8.6.1. Лексикографічний порядок – це природний спосіб упорядкування послідовностей на основі порівняння індивідуальних символів. На множині всіх розміщень із r елементів означимо порівняння таким чином: b1b2 ...br < a1a 2 ...a r , якщо m : bi ai , i m bm a m . У такому разі говорять, що перестановка b1b2 ...br менша від перестановки a1 a 2 ...a r , або перестановка a1a 2 ...a r більша від перестановки b1b2 ...br . У програмуванні такий лексикографічний порядок використовують для порівняння рядків, тільки замість чисел беруть символи ASCII чи Unicode (в залежності від типу рядка) і лексикографічний порядок відповідає порядку символів. Приклад 8.6.1. Порівняємо стрічки hello та hermes. Розв’язання. Очевидно, що перша та друга літера однакові. Тому порівняння визначатиме третя літера. У таблиці ASCII (чи відповідно до англійської абетки) літера l передує літері r. Тому hello < hermes. ▲ Означення 8.6.2. Вибірку a1a 2 ...a r називають лексикографічно наступною (безпосередньо наступною) за b1b2 ...br , якщо не існує такої вибірки c1c2 ...cr , що: b1b2 ...br < c1c2 ...cr < a1a 2 ...a r . Визначимо, яким чином можна побудувати лексикографічно наступне розміщення за розміщенням a1a 2 ...a r . 8.6.1. Алгоритми генерування розміщень Алгоритм побудови лексикографічно наступного розміщення з повтореннями за розміщенням а1а2...аr Алгоритм подібний до звичайного визначення наступного числа. Крок 1. Знаходимо позицію k першого справа елемента, відмінного від n, a k n . Крок 2. Збільшуємо елемент ak на одиницю. Елементи ai , де i<k, залишаємо без змін. Елементи ai , де i>k, покладаємо рівними одиниці. Приклад 8.6.2. Нехай A = {1, 2 ,3}. Побудуємо 6 розміщень з повтореннями лексикографічно наступних після 1222. Розв’язання. Наступне буде 1223, бо можна збільшити останній елемент. Після нього буде 1231, бо 4-й елемент (3) ми збільшити не можемо, тому збільшуємо 3-й, а 4-й покладаємо рівним одиниці. Як бачимо, маємо аналогію з переносом розряду, подібно до десяткового числення. Наступні елементи, відповідно, будуть 1232,1233, 1311 та 1312. ▲ Алгоритм побудови лексикографічно наступного розміщення без повторень за розміщенням а1а2...аr Алгоритм від попереднього відрізняється тим, що у розміщеннях не може бути повторень, тому потрібно “оновлювати” елементи розміщення, не порушуючи цієї властивості. Крок 1. Знайдемо множину B “вільних” елементів, яких немає у розміщенні a1a 2 ...a r : B = A\ a1a 2 ...ar . Крок 2. Шукаємо перший справа елемент у розміщенні, який можна збільшити. Якщо у B є елементи, які більші за аr, то вибираємо серед них такий, що br min {x a r } . xB Якщо у B немає елементів, більших за аr, то додаємо до B елемент аr, B B {a r } , і шукаємо br 1 min{x a r 1} . xB Якщо у B немає елементів, більших за аr-1, то додаємо до B елемент аr-1, і т.д. Продовжуємо цей процес, поки не знайдемо bk min {x ak } xB або не дійдемо до початку розміщення. Якщо такого bk не знайдено, то ми дійшли до максимального елементу, і алгоритм завершено. Якщо ні, то переходимо до кроку 3. Крок 3. Обчислюємо наступне розміщення. Записуємо в k-ту позицію розміщення знайдений елемент bk і вилучаємо його з множини B. Записуємо у висхідному порядку число bk 1bk 2 ...br з найменших елементів у множині B, розмістивши їх на позиціях k+1, k+2,..., r. Приклад 8.6.3. Нехай A = {1, 2 , 3, 4}. Побудуємо 4 розміщення без повторень лексикографічно наступних після 123. Розв’язання. Наступне буде 124, бо можна збільшити останній елемент (3). Обчислимо наступне розміщення після 124. Оскільки 3-й елемент ми збільшити не можемо, то збільшуємо 2-й елемент, тобто заміняємо 2 на 3. На останньому місці не можна поставити одиницю, бо вона вже є у розміщенні, тому ставимо такий найменший елемент, якого немає в розміщенні , тобто 2, отримуємо 132. Наступне розміщення після 132 рівне 134, бо можна збільшити останній елемент. Яке розміщення буде після 134? Останній елемент ми не можемо збільшити, але можемо збільшити передостанній. Тому наступне розміщення 142. ▲ Іншим алгоритмом для генерування всіх розміщень є генерування усіх сполучень, після чого з кожного сполучення треба генерувати всі можливі перестановки. 8.6.2. Алгоритми генерування сполучень Як і в попередньому підрозділі, розглядатимемо генерування сполучень на множині A={1, 2,…, n}. Сполучення без повторень з n елементів по r – це r-елементна підмножина множини А. Позаяк порядок запису елементів множини неістотний, то для спрощення запису будемо сортувати елементи в сполученнях у висхідному порядку і записувати їх як рядок цифр: наприклад, сполучення {4,1,3} будемо записуватимемо як 134. Алгоритм побудови лексикографічно наступного сполучення з повтореннями за сполученням а1,а2...аr Алгоритм подібний до алгоритмів генерування розміщень, але має одну особливість, яка полягає в наступному: якщо сполучення записане у висхідному порядку, то кожен наступний елемент сполучення не менший за попередній. Крок 1. Знаходимо позицію k першого справа елемента, відмінного від n: a k n . Крок 2. Збільшуємо елемент ak на одиницю: bk a k 1 . Елементи зліва від ai залишаються без змін: bi ai , де i<k . Елементи справа від ai стають рівними bk : bi bk , де i k . Приклад 8.6.4. Нехай A = {1, 2 , 3, 4}. Побудуємо 7 сполучень з повтореннями, лексикографічно наступних після 1233. Розв’язання. Наступне буде 1234, бо можна збільшити останній елемент. При пошуку наступного сполучення після 1234 бачимо, що збільшувати можна 3. Отже, перші три цифри будуть 124. Останній елемент теж повинен бути рівний 4, бо не може бути меншим за попередній, тому отримуємо 1244. Після нього буде 1333, оскільки ми можемо збільшити лише 2, а інші елементи мають бути такими самими. Аналогічно знаходимо наступні елементи: 1334, 1344, 1444 та 2222. ▲ Алгоритм побудови лексикографічно наступного сполучення без повторень за сполученням а1а2...аr Відзначимо одну особливість. Якщо сполучення записане у висхідному порядку і не має повторень, то кожен наступний його елемент більший від попереднього принаймні на одиницю. Тоді максимальне значення, яке може набувати його останній елемент, рівне n. Максимум для передостаннього елемента рівний n-1, а не n. Доведемо це від зворотнього. Припустимо, що останній елемент рівний n , тоді наступний елемент має бути рівний n+1, але такого елемента немає в множині. Отже, максимум для передостаннього елемента n-1. Аналогічно можна довести, що максимум для елемента на k-ій позиції рівний n-(r-k). Мінімум для елемента – попереднє число сполучення, збільшене на 1. Крок 1. Знайдемо перший справа елемент сполучення, який можна збільшувати. Він має бути меншим за свій допустимий максимум, тобто ak n r k , де k –позиція цього елемента. Крок 2. Збільшимо елемент a k на одиницю: bk = аk + 1. Крок 3. Елементи зліва від ai не змінюємо: bi = аi, i<k. Крок 4. Елементи справа змінюємо на мінімальні, тобто такі, що на одиницю більші від попереднього: bi = bi-1 + 1 (це те ж саме, що й аk +i-k), i>k. Приклад 8.6.8. Нехай А={1,2,3,4,5,6}. Знайдемо сполучення, наступне за 1256 у лексикографічному порядку. Розв’язання. Маємо п = 6, r= 4, п-r=2. Почергово перевіряємо елементи, починаючи з крайнього справа на виконання умови, записаної в кроці 1: для 6 k=4, тому 6=2+4 – не підходить, для 5 k=3, тому 5=2+3 – не підходить, для 2 k=2, тому 2<2+2 – підходить. Отже, перший справа з таких елементів, що ak n r k , – це а2=2. Для обчислення наступного більшого сполучення збільшуємо а2 на 1 та одержуємо а2 = 3. Тепер нехай а3= 3+1=4 і a4 = 3 + 2 = 5. Отже, наступне в лексикографічному порядку сполучення зображено рядком 1345, тобто {1, 3, 4, 5}. ▲ 8.6.3. Алгоритми генерування перестановок Алгоритм генерування перестановок множини А = {1, 2, ..., п} можна визначити як алгоритм побудови розміщень із n по n. Але для перестановок можна знайти простіший алгоритм. Алгоритм побудови лексикографічно наступної перестановки за перестановкою а1,а2...аn Наведемо кроки алгоритму. Крок 1. Знайти такі елементи aj і aj+1, що (аj<аj+1, ) (aj+1 aj+2 ... ап). Для цього треба знайти в перестановці першу справа пару сусідніх елементів, у якій елемент ліворуч менший від елемента праворуч. Крок 2. Записати в j-ту позицію таке найменший з елементів aj+1, aj+2,..., ап, який водночас є більшим, ніж aj. Крок 3. Записати елемент аj і решту елементів aj+1, aj+2,...,an у позиції j+1, j+2,...,..., п у висхідному порядку. Зауважимо також, що для генерування перестановок з повтореннями чи без повторень алгоритм не відрізнятиметься. Єдина відмінність полягатиме у тому, що для перестановок без повторень нерівності у кроці 1 будуть строгими. Приклад 8.6.6. Побудуємо дві перестановки, наступні в лексикографічному порядку за 34521. Розв’язання. Згідно першого кроку j=2, бо 4<5>2>1 (34521). Отже, перший елемент (3) залишаємо на місці, а збільшуємо другий (4). Розглянемо послідовність цифр 521. Серед них найменша цифра, більша від 4, це 5. Тепер на другому місці 5, а решту елементів розміщуємо у вихідному порядку: 35124. Побудуємо наступну перестановку після 35124. Згідно першого кроку j =4 і щоб отримати наступну перестановку, треба збільшити 2, поставивши замість нього 4, бо справа немає іншої цифри, більшої за 2. Переставивши місцями два останніх елемента, отримаємо 35142. ▲ Приклад 8.6.7. Побудуємо 5 перестановок, наступних в лексикографічному порядку за 3241242311. Розв’язання. Знаходимо першу пару елементів справа, з яких перший елемент менший за другий (3241242311): 2 3 1 1 . Отже, на місце першого з них ставимо 3, а решту розміщуємо в порядку зростання (112), отримуємо 3241243112. Наступне число запишемо, переставивши дві останні цифри 3241243121. Легко побачити, що наступне 3241243211. Щоб знайти наступне після 3241243211, знову знаходимо перші два елементи справа, перший з яких менший за другий: 2 4 3 2 1 1 . Змінюємо цифру 2 цифрою, більшою за неї і водночас найменшою з цифр, розміщених справа від неї у перестановці – 3. Решту цифр сортуємо за зростанням: 3241311224. ▲ 8.7. Генерування розбиття множини. Числа Стірлінга другого роду. Числа Белла Нагадаємо, що розбиттям множини називають сукупність непорожніх множин, які не перетинаються між собою, а їх об’єднання дає вихідну множину A. Приклад 8.7.1. Задано множину A = {1, 2, 3}. Знайдемо усі її розбиття. Розв’язання. {{1, 2, 3}}, {{1,2}, {3}}, {{2,3}, {1}}, {{1,3}, {2}}, {{1}, {2}, {3}}. ▲ Отримати розбиття множини прямим методом доволі складно. Алгоритм, запропонований нижче, полягає у тому, що кожне розбиття множини {1, 2, …, п-1, п } можна отримати із розбиття {1, 2, …, п -1}, додавши елемент {п }. Алгоритм має недолік: він вимагає попереднього обчислення всіх розбиттів множини із кількістю елементів 1, 2, 3, 4, …, n-1. Існують алгоритми, які можуть робити прямий перебір без додаткових обчислень, але вони суттєво складніші. Алгоритм генерування всіх розбиттів множини Крок 1. Нехай n =1. Розбиття множини A = {1} є єдиним M1= {{1}}. Збільшуємо n на одиницю. Крок 2. Робимо присвоєння n=n+1. На попередньому кроці ми обчислили усі розбиття Mn-1 множини {1, 2, …, п -1}. Ініціалізуємо розбиття Mn порожньою множиною. Крок 3. Для кожного з розбиттів множини {1, 2, …, п -1, п } елемент {п } почергово додаємо до кожної з множин розбиття. Отримане розбиття додаємо до Mn. Зауваження: для цього треба організувати подвійний цикл. Крок 4. Утворюємо розбиття множини {1, 2, …, п -1, п }, додаючи елемент {п } як окрему множину до кожного з розбиттів елемента A та додаємо до Mn. Крок 8. Переходимо до кроку 2, якщо n не досягло кінцевого значення. Розглянемо детальніше рекурсивну роботу алгоритму. Приклад 8.7.2. Знайдемо розбиття множини M3. Розв’язання. Крок 1. Нехай n = 1. Розбиття множини A = {1} є єдиним – M1= {{1}}. Крок 2. Збільшуємо n на одиницю, n = 2. Ініціалізуємо M2= {}. Крок 3. Додаємо до розбиття M1 елемент {2} та до M2 утворену підмножину, отримуємо M2=[{{1,2}}]. Крок 4. Додаємо до M1 {2} як окрему множину. Крок 8. Отримуємо розбиття M2 =[{{1,2}}; {{1},{2}}]. Крок 6. Збільшуємо n на одиницю, n=3. Ініціалізуємо M3= {}. Крок 7. Додаємо до M3 елемент {3} та до кожної з підмножин {{1,2}} та {{1},{2}}. Отримуємо: M3= {{1,2,3}}; {{1,3},{2}} ;{{1},{2,3}} . Як бачимо із розбиття {{1},{2}}, ми отримали два нових розбиття, а з {{1,2}} – лише одне. Крок 8. Додаємо до M3 розбиття, які отримують від додавання {3} до кожної з підмножин {{1,2}} та {{1},{2}} як окремої множини. Отримуємо: M3= {{1,2,3}}; {{1,3},{2}} ; {{1},{2,3}}; {{1,2},{3}};{{1},{2},{3}}. Крок 9. Оскільки n=3, то алгоритм завершено. ▲ Означення 8.7.1. Кількість розбиттів n-елементної множини на k непорожніх частин називають числами Стірлінга другого роду і позначають S(п, k). Елементи розбиття називають блоками. Означення 8.7.2. Кількість усіх розбиттів n-елементної множини на непорожні частини називають числами Белла і позначають S(п). З розглянутого прикладу 8.7.2: S(3, 1) = 1; S(3, 2) = 3; S(3, 3) = 1; S(3) = 1 + 3 +1 = 5. Приклад 8.7.3. Обчислимо S(6,2). Розв’язання. Кількість невпорядкованих розбиттів 6-елементної множини на два блоки, один з яких містить 1 елемент, дорівнює C61 6 . Якщо в одному з двох блоків 2 елементи, то кількість відповідних розбиттів дорівнює C62 15 . Нарешті, якщо два блоки, на які розбивають вихідну множину, складаються з 3-х елементів, то кількість таких розбиттів – C63 / 2 10 . Тому S(6,2)=6+15+10=31. ▲ Очевидно виконання таких «крайових умов»: для довільного натурального п S(п, 1)=1, S(п, п)=1, при k>0 S(0, k)=0, при k>п S(п, k)=0. За означенням покладають S(0, 0)=1, для довільного натурального п S(п, 0)=0, S(п, п)=1. Зв’язок між числами Белла та числами Стірлінга очевидний: S n n S n, k . (8.11) k 1 Для них також виконуються такі рівності. 1) S n, k 2) (1) k k! S n, k k (1)i Cki i n . i 1 n 1 Cni 1S (i, k 1) . (8.12) i k 1 3) S n n 1 Cni 1S i . i 0 4) S n, k S n 1, k 1 kS (n 1, k ) . Останню рівність легко вивести з алгоритму для генерування множин, за її допомогою легко виводити значення чисел Белла та Стірлінга 2-го роду (табл. 8.2). Таблиця 8.2 n\k 1 2 3 4 5 1 1 2 1 1 3 1 3 1 4 1 7 6 1 5 1 15 25 10 1 6 1 31 91 65 15 … … … … … … … S n … 1 … 2 … 5 … 15 … 52 1 … 203 … … … 6 Аналізуючи таблицю, можна зауважити, що S(п, 2)=2п-1-1, S(п, п-1)= Cn2 . Щодо останнього виразу, дійсно, якщо п елементів розбивають на п-1 блоків, то всі блоки, крім одного, будуть одноелементними, і розбиття визначається тим, які два елементи складуть цей блок. Теорема 8.4. За фіксованого п послідовність S n, k , k=1,2,...,n, унімодальна. 8.8. Принцип включення-виключення для довільної кількості множин Теорема 8.8. Для довільних скінченних множин Ak, k=1,....n, виконується формула: m | A1 A2 ... An | | Ai | i 1 | Ai A j | 1i j n | Ai A j Ak | ... 1i j k n (1)n 1 | A1 A2 ... An | . (8.13) Доведення. Достатньо довести, що кожний елемент в об’єднанні множин ураховано в правій частині рівності точно один раз. Припустимо, що елемент а 1 належить рівно r множинам з А1, А2,..., Ап, де 1 r n. Тоді цей елемент ураховано Cr m разів у | Ai | , Cr2 i 1 разів у | Ai A j | ; загалом його враховано Crm разів під час 1 i j n сумування членів, які містять перетин т множин Аі. Отже, елемент а враховано точно C1r Cr2 Cr3 ... (1) r 1Crr разів у виразі в правій частині рівності. За властивістю 5 C1r Cr2 Cr3 ... (1) r 1Crr 0, тому C1r Cr2 Cr3 ... (1) r 1Crr , але C1r 1 , тому Cr2 Cr3 ... (1)r 1Crr 1 . Це й означає, що кожний елемент об’єднання множин ураховано у правій частині рівності точно 1 раз. Зазначимо, що формула (8.13) містить 2n-1 доданків, по одному для кожної непорожньої підмножини з {А1, А2,..., Ап}. Принцип включення-виключення в альтернативній формі Цю форму принципу включення-виключення використовують для розв’язання задач, де необхідно знайти кількість елементів заданої множини А, які не мають жодної з n властивостей 1 , 2 ,..., n . Позначимо: Ai A – підмножина елементів, що мають властивість i ; N (i1 , i2 ,..., in ) – кількість елементів множини А, які одночасно мають властивості i1 , i2 ,..., in ; N (i1 , i2 ,..., in ) – кількість елементів множини А, які не мають жодної властивості i1 , i2 ,..., in ; N – кількість елементів множини А. Тоді N (1 , 2 ,..., n ) N | A1 A2 ... An | . За принципом включення-виключення отримаємо: N ( 1, 2 ,..., n ) N N ( i ) N ( i , j ) 1 i n 1 i j n N (i , j , k ) ... 1 i j k n (1) n N (1, 2 ,..., n ) . (8.14) 8.9. Задача про цілочислові невід’ємні розв’язки Цю задачу формулюють так: знайти кількість розв’язків рівняння x1 x2 ... xn k у цілих невід’ємних числах, де k – ціле невід’ємне число. Узявши такі невід’ємні цілі числа x1 , x2 ,..., xn , що x1 x2 ... xn k , можна одержати сполучення з повтореннями з n елементів по k, а саме: елементів першого типу – х1 одиниць, другого – х2, ..., n-го – хn. Навпаки, якщо є сполучення з повтореннями з n елементів по k, то кількість елементів кожного типу задовольняють вимоги рівняння x1 x2 ... xn k у цілих невід’ємних числах. Отже, кількість цілих невід’ємних розв’язків цього рівняння дорівнює: H nk (див. формулу (8.5)). Приклад 8.9.1. Знайдемо кількість невід’ємних цілих розв’язків рівняння х1+х2+х3=10. Розв’язання. Безпосереднє використання формули (8.5) дає 10 10 N H 310 C10 31 C12 12! 12 11 66. 10!2! 2 ▲ Кількість розв’язків рівняння x1+х2+...+хn = k у цілих невід’ємних числах можна визначити й тоді, коли на змінні накладено певні обмеження. Алгоритм розв’язування задач зі змішаними обмеженнями ai xi bi , i 1,2,3, для 3 рівняння x1 x2 x3 k у випадку bi k i 1 (алгоритм 1) Крок 1. Шукаємо кількість N цілочислових розв’язків задачі: x1 a1, x2 a2 , x3 a3 . Крок 2. Шукаємо кількість N (1), N ( 2 ), N (3 ), цілочислових розв’язків відповідних задач з альтернативними властивостями: 1 : x1 b1 1, x2 a2 , x3 a3 , x1 a1 , 2 : x2 b2 1 , x3 a3 , x1 a1 , x2 a2 , 3 : x3 b3 1. Крок 3. Якщо b1 b2 a3 2 k , b2 b3 a1 2 k чи b1 b3 a2 2 k , то шукаємо кількість N (1, 2 ), N ( 2 , 3 ), N (1, 3 ), цілочислових розв’язків відповідних задач з обмеженнями на дві змінні: x1 b1 1, x2 b2 1 , x3 0, x1 0 , x2 b2 1 , x3 b3 1 , x1 b1 1, x2 0 , x3 b3 1. Знаходимо кількість шуканих розв’язків, використовуючи принцип включеннявиключення в альтернативній формі (8.14), за формулою: 3 K N N (i ) N (1, 2 ) N (1, 3 ) N ( 2 , 3 ) . Кінець. i 1 Крок 4. Знаходимо кількість шуканих розв’язків за формулою: 3 K N N (i ). Кінець. i 1 Приклад 8.9.2. Знайдемо кількість невід’ємних цілих розв’язків рівняння x1 x2 x3 11, якщо на всі змінні накладено змішані обмеження та : 1 x1 7, 1 x2 4, 1 x3 3 . Розв’язання. Знаходимо N як розв’язок задачі x1 1, x2 1 , x3 1. Увівши допоміжні змінні yi xi 1, i 1,2,3, отримаємо замість вихідного рівняння таке: y1 y 2 y3 8 з обмеженнями y1 1, y 2 1 , y3 1. Використання формули (8.5) дає: 8 N H 38 C10 45. 3 Оскільки bi 3 7 4 3 3 17 11, перевіряємо: i 1 b1 b2 a3 2 7 4 2 1 14 11 , b1 b3 a2 2 7 3 1 2 13 11, b2 b3 a1 2 4 3 1 2 10 11 , тому згідно алгоритму 1 шукаємо кількість N ( 2 , 3 ) цілочислових розв’язків відповідної задачі з обмеженнями на дві змінні: x1 1 , x2 5 , x3 4 . Маємо N ( 2 , 3 ) H 31 C31 3. Знаходимо кількість цілочислових розв’язків відповідних задач з обмеженнями на одну змінну: x1 8, x2 1 , x3 1, x1 1 , x2 5 , x3 1, x1 1 , x2 1 , x3 4. Одержимо N (1) H 31 C31 3, N (2 ) H 34 C64 15, N (3 ) H 35 C75 21, 3 K N N (i ) N ( 2 , 3 ) 45 3 15 21 3 9. ▲ i 1 Алгоритм розв’язування задач без обмежень на змінні для нерівності x1 x2 ... xn k (алгоримт 2) 1. Уводимо додаткову змінну xn 1 0 і підставляємо її у вихідну нерівність. 2. Отримуємо рівняння: x1 x2 ... xn xn 1 k . 3. Знаходимо кількість цілочислових розв’язків нової задачі за формулою (8.5): H N H nk 1 Cnk k . (8.16) Приклад 8.9.3. Визначимо кількість розв’язків нерівності x1 x 2 x3 10 у невід’ємних цілих числах. Розв’язання. Уведемо допоміжну змінну х4, яка може набувати цілих невід’ємних значень, і перейдемо до еквівалентної задачі: визначити кількість розв’язків рівняння х1+х2+х3+х4=10 10 в невід’ємних цілих числах. За формулою (8.16) маємо: H N H 10 4 C13 ▲ 13! 286. 10!3! Контрольні запитання до теми 8 1. Сформулюйте правила суми і добутку. 2. Які вибірки називають розміщеннями з повторенням і без повторень? Як знаходять кількість елементів у цих вибірках? 3. Які вибірки називають сполученнями з повторенням і без повторень? Як знаходять кількість елементів у цих вибірках? 4. Що називають біномом Ньютона? 5. Якими властивостями володіє трикутник Паскаля? 6. Які властивості біноміальних коефіцієнтів ви знаєте? 7. Сформулюйте і доведіть принцип включення-виключення для довільної кількості множин. 8. Наведіть принцип включення-виключення для довільної кількості множин у альтернативній формі. 9. Які вибірки називають перестановками з повторенням і без повторень? Як знаходять кількість елементів у цих вибірках? 10. Яку формулу називають поліноміальною? Узагальненням чого вона є? 11. Що називають лексикографічним порядком послідовності символів? 12. Яку вибірку називають лексикографічно наступною до заданої? 13. Опишіть алгоритм побудови лексикографічно наступного розміщення з повтореннями за розміщенням а 1 а 2 ...а r . 14. Опишіть алгоритм побудови лексикографічно наступного розміщення без повторень за розміщенням а 1 а 2 ...а r . 15. Опишіть алгоритм побудови лексикографічно наступного сполучення з повтореннями за сполученням а 1 а 2 ...а r . 16. Опишіть алгоритм побудови лексикографічно наступного сполучення без повторень за сполучення а 1 а 2 ...а r . 17. Опишіть алгоритм побудови лексикографічно наступної перестановки за перестановкою а 1, а 2 ...а n . Вкажіть відмінність при генеруванні перестановок з повтореннями чи без повторень. 18. Опишіть алгоритм генерування всіх розбиттів множини. 19. Що називають числами Стірлінга другого роду і числами Белла? Який між ними зв’язок? 20. Як шукають цілочислові розв’язки рівнянь та нерівностей без обмежень на змінні? 21. Як шукають цілочислові розв’язки рівнянь зі змішаними обмеженнями на змінні? 22. Який спосіб пошуку (послідовний чи двійковий) є ефективнішим і наскільки? 23. Які функції (поліноміальні чи експоненційні) мають вищу часову складність?