СД.ДС.Ф.2 Комбинаторные алгоритмы

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
«Мурманский государственный гуманитарный университет»
(ФГБОУ ВПО «МГГУ»)
УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС
ДИСЦИПЛИНЫ
ДС. 2 КОМБИНАТОРНЫЕ АЛГОРИТМЫ
Основная образовательная программа подготовки специалиста по специальности
010501 «Прикладная математика и информатика»
Утверждено на заседании кафедры
математики и математических методов
в экономике факультета
физико-математического образования,
информатики и программирования
(протокол № 6 от 27 февраля 2013 г.)
Зав. кафедрой _______________О.М. Мартынов
1.1 Автор программы: кандидат технических наук, доцент Ланина Н.Р.
1.2 Рецензент: доктор физико-математических наук, профессор Маренич Е.Е.
1.3 Пояснительная записка:
Целью изучения курса «Комбинаторные алгоритмы» является подготовка студентов
на уровне, необходимом и достаточном для:
 усвоения материала специальных дисциплин;
 практической работы по специальности;
 формирования умения исследовать математическую задачу, выбрать для её решения необходимую структуру данных и программно реализовать алгоритм решения этой задачи.
Основными задачами изучения данной дисциплины являются:
 изучение применяемых в программировании математических методов, позволяющих разрабатывать эффективные алгоритмы;
 изучение структур данных, их спецификации и реализации, алгоритмов обработки
данных и анализ этих алгоритмов, взаимосвязь алгоритмов и структур данных;
 формирование целостной системы знаний о классических алгоритмах программирования, области их применения;
 формирование у студентов математической культуры и развитие логического
мышления;
 обучение решению прикладных задач математическими методами;
 развитие способности творчески подходить к решению профессиональных задач.
В результате изучения курса студенты
должны знать:

об основных методах решения «труднорешаемых» задач, т.е. задач, имеющих
более чем полиномиальную сложность;

об основных алгоритмах на графах и псевдографах, их теоретической сложности.
.
должны уметь:
 разрабатывать программы, используя изложенные в курсе общие схемы, методы и
приемы построения алгоритмов;
 доказывать корректность составленного алгоритма и оценивать основные характеристики его сложности;
 реализовывать алгоритмы и используемые структуры данных средствами языков
программирования высокого уровня (например, С++);
 экспериментально (с помощью компьютера) исследовать эффективность алгоритма
и программы.
1.4.
2
1.5. Объем дисциплины и виды учебной работы.
№
п/п
Шифр и наименование специальности
1.
010200 «Прикладная математика и
информатика»
2.
Курс
Семестр
Трудоемкость
Виды учебной работы в часах
Всего
ЛК
ПР/ ЛБ
Сам.
аудит.
СМ
работа
Вид итогового контроля
(форма отчетности)
5
9
165
92
46
46
−
73
экзамен
3
6
240
134
66
68
−
106
зачет
1.6 Содержание дисциплины.
1.6.1 Разделы дисциплины и виды занятий (в часах). Примерное распределение учебного
времени:
1 вариант
№
п/п
Наименование раздела, темы
1
2
3
ИСЧЕРПЫВАЮЩИЙ ПОИСК
АЛГОРИТМЫ НА ГРАФАХ
NP-ПОЛНЫЕ ЗАДАЧИ
ИТОГО
Количество часов
для специальности 010200 «Прикладная
математика и информатика»
Всего
ЛК
ПР
ЛБ
Сам.
ауд.
раб.
44
22
22
–
36
40
20
20
–
34
8
4
4
–
3
92
46
46
–
73
2 вариант
№
п/п
Наименование раздела, темы
1
2
3
ИСЧЕРПЫВАЮЩИЙ ПОИСК
АЛГОРИТМЫ НА ГРАФАХ
NP-ПОЛНЫЕ ЗАДАЧИ
ИТОГО
Количество часов
для специальности 010200 «Прикладная
математика и информатика»
Всего
ЛК
ПР
ЛБ
Сам.
ауд.
раб.
44
22
22
–
36
46
22
24
–
34
44
22
22
–
36
134
66
68
–
106
1.6.2 Содержание разделов дисциплины.
ИСЧЕРПЫВАЮЩИЙ ПОИСК
§ 1. Алгоритмы с возвратом и их свойства
§ 2. Задача о велосипедном замке
§ 3. Генерация комбинаторных объектов
§ 4. Задача о ходе коня
§ 5. Задача о восьми ферзях
§ 6. Задача о паросочетаниях
§ 7. Метод ветвей и границ на примере задачи оптимального выбора (о рюкзаке)
§ 8. Задача коммивояжера и её решение методом ветвей и границ
§ 9. Динамическое программирование на примере задачи о порядке перемножения це-
почки матриц
§ 10. Дерево оптимального поиска. Построение дерева оптимального поиска
§ 11. Решение задачи коммивояжера методом динамического программирования
§ 12. Жадные алгоритмы применительно к труднорешаемым задачам
АЛГОРИТМЫ НА ГРАФАХ
3
§ 1. Графы и способы их машинного представления. Сильно ветвящиеся деревья и
способы их машинного представления
§ 2. Метод поиска в глубину в графе. Метод поиска в ширину в графе. Задачи, решаемые с помощью поиска в глубину
§ 3. Алгоритм нахождения эйлерова цикла в графе. Алгоритм нахождения гамильтонова цикла в графе. Нахождение в графе точек сочленения
§ 4. Остовное дерево наиманьшей стоимости. Алгоритмы Крускала и Прима построения остовного дерева
§ 5. Задача об изоморфизме графов и пути ее решения. Задача об изоморфизме двух
деревьев, как частный случай задачи об изоморфизме графов
§ 6. Нахождение кратчайших путей в графе. Алгоритм Форда-Беллмана нахождения
расстояний от вершины-источника до остальных вершин
§ 7. Алгоритм Дейкстры нахождения расстояний от вершины-источника до остальных
вершин.
§ 8. Алгоритм Уоршаллла и Флойда нахождения расстояний между всеми парами
вершин
§ 9. Восстановление по расстояниям кратчайшего пути
§ 10. Определение расстояний в бесконтурном графе с использованием топологической сортировки
§ 11. Сети. Потока в сетях. Теорема Форда-Фалкерсона о максимальном потоке
§ 12. Алгоритм нахождения максимального потока в сети
NP-ПОЛНЫЕ ЗАДАЧИ
§ 1. NP-класс. Полиномиальная сводимость задач. Эквивалентность задач. NP–полная
задача
§ 2. Примеры доказательства NP-полноты. Пути решения NP-полных задач
1.6.3 Темы для самостоятельного изучения.
№ п/п
1
2
3
Наименование раздела
дисциплины.
Тема.
Форма самостоятельной работы
ИСЧЕРПЫВАЮЩИЙ
ПОИСК
АЛГОРИТМЫ НА
ГРАФАХ
NP-ПОЛНЫЕ ЗАДАЧИ
Контрольная работа № 1
Контрольная работа № 2
Контрольная работа № 2
Форма контроля
выполнения
самостоятельной
работы
Проверка контрольной работы
Проверка контрольной работы
Проверка контрольной работы
Количество
часов
36
34
3
1.7 Методические рекомендации по организации изучения дисциплины.
1.7.1 Тематика и планы практических занятий по изученному материалу
Практические занятия по теме
«ИСЧЕРПЫВАЮЩИЙ ПОИСК»
ПР № 1. Разработка процедур генерации
 подмножеств конечного множества;
 размещений, перестановок, сочетаний
ПР № 2. Разработка процедур генерации
 размещений с повторениями, сочетаний с повторениями;
 композиций, разбиений
4
ПР № 3. Решение задачи о ходе коня. Решение задачи о ферзях
ПР № 4. Решение задачи о паросочетаниях на примере задачи о стабильных браках
ПР № 5. Решение задачи о рюкзаке полным перебором, а также методом ветвей и границ
ПР № 6. Решение задачи коммивояжера полным перебором, а также методом ветвей и
границ
ПР № 7. Решение задачи коммивояжера методом динамического программирования
ПР № 8. Решение задачи о порядке перемножения цепочки матриц
ПР № 9. Построение дерева оптимального поиска
ПР № 10. Контрольная работа № 1
ПР № 11. Работа над ошибками
Литература:
1. Ахо А., Хопкрофт Дж., Ульман Дж. Структуры данных и алгоритмы. М.: Издательский дом “Вильямс”, 2001.- 384 с.
2. Вирт Н. Алгоритмы и структуры данных. СПб.: Невский Диалект, 2001. - 352 с.
3. Липский В. Комбинаторика для программистов. М.: Мир, 1988.
Практические занятия по теме
«АЛГОРИТМЫ НА ГРАФАХ»
ПР № 12. Способы хранения графов и сильно ветвящихся деревьев. Переход от одного способа хранения к другому
ПР № 13. Реализация процедур обхода графа в глубину и ширину
ПР № 14. Реализация процедур нахождения в графе эйлерова цикла, гамильтонова
цикла
ПР № 15. Реализация процедур нахождения в графе минимального остовного дерева
ПР № 16. Решение задачи об изоморфизме графов методом полного перебора, а также
эвристическими методами
ПР № 17. Методы Форда-Беллмана и Дейкстры нахождения в графе расстояний от
вершины источника до остальных вершин
ПР № 18. Метод Уоршаллла и Флойда нахождения расстояний между всеми парами
вершин. Восстановление по расстояниям кратчайшего пути
ПР № 19. Реализация процедуры топологической сортировки
ПР № 20, 21. Реализация процедуры нахождения максимального потока в сети
Литература:
1. Ахо А., Хопкрофт Дж., Ульман Дж. Структуры данных и алгоритмы. М.: Издательский дом “Вильямс”, 2001.- 384 с.
2. Зубов В.С. Справочник программиста. Базовые методы решения графовых задач и
сортировки. М.: Информационно-издательский Дом “Филинъ”, 1999. - 256 с.
3. Иванов Б.Н. Дискретная математика. Алгоритмы и программы: Учеб. пособие. - М.:
Лаборатория базовых знаний, 2001. - 288 с.
4. Липский В. Комбинаторика для программистов. М.: Мир, 1988.
5. Новиков Ф.А. Дискретная математика для программистов. Спб: Питер, 2000. - 304
с.
Практические занятия по теме
«NP-ПОЛНЫЕ ЗАДАЧИ»
5
ПР № 22. Доказательство NP-полноты путём сведения задач к задаче о выполнимости
ПР № 23. Контрольная работа № 2
Литература:
1. Ахо А., Хопкрофт Дж., Ульман Дж. Структуры данных и алгоритмы. М.: Издательский дом “Вильямс”, 2001.- 384 с.
2. Гудман С., Хидетниеми С. Введение в разработку и анализ алгоритмов. - М,.: Мир,
1981. 368 с.
3. Иванов Б.Н. Дискретная математика. Алгоритмы и программы: Учеб. пособие. - М.:
Лаборатория базовых знаний, 2001. - 288 с.
1.8 Учебно-методическое обеспечение дисциплины.
1.8.1 Рекомендуемая литература:
Основная литература.
лекции
1. Ахо А., Хопкрофт Дж., Ульман Дж. Построение и анализ вычислительных алгоритмов. М.: Мир, 1979. - 536 с.
2. Ахо А., Хопкрофт Дж., Ульман Дж. Структуры данных и алгоритмы. М.: Издательский дом “Вильямс”, 2001.- 384 с.
3. Вирт Н. Алгоритмы и структуры данных. СПб.: Невский Диалект, 2001. - 352 с.
4. Гудман С., Хидетниеми С. Введение в разработку и анализ алгоритмов. - М,.: Мир,
1981. 368 с.
5. Кнут Д. Искусство программирования для ЭВМ. Том 1: Основные алгоритмы. М.:
Издательский дом “Вильямс”, 2000. - 720 с.
6. Липский В. Комбинаторика для программистов. М.: Мир, 1988.
практические занятия
1. Дмитриева М.В., Кубенский А.А. Элементы современного программирования:
Учебное пособие. Спб.: Изд-во С.-Петербургского университета, 1991. - 272 с.
2. Зубов В.С. Справочник программиста. Базовые методы решения графовых задач и
сортировки. М.: Информационно-издательский Дом “Филинъ”, 1999. - 256 с.
3. Иванов Б.Н. Дискретная математика. Алгоритмы и программы: Учеб. пособие. - М.:
Лаборатория базовых знаний, 2001. - 288 с.
4. Новиков Ф.А. Дискретная математика для программистов. Спб: Питер, 2000. - 304
с.
Дополнительная литература.
1. Грин Д., Кнут Д. Математические методы анализа алгоритмов. - М.: Мир, 1987. 120 с.
2. Гэри М., Джонсон Д. Вычислительные машины и труднорешаемые задачи. М.: Мир,
1982. – 416 с
3. Рейнгольд Э., Нивергельт Ю., Део Н. Комбинаторные алгоритмы. Теория и практика. - М.: Мир, 1980. - 476 с.
4. Стивенс Р. Delphi. Готовые алгоритмы. М.: ДМК Пресс, 2001. - 384 с.
5. Харари Ф. Теория графов. М.: Едиториал УРСС, 2003. - 296 с.
1.9 Материально-техническое обеспечение дисциплины.
1.9.1 Перечень используемых технических средств: персональные компьютеры
1.9.2 Электронный конспект лекций
6
1.9.3 Пакет демонстрационно-обучающих программ по темам: «Исчерпывающий поиск»,
«Алгоритмы на графах»
1.9.4 Двадцать четыре варианта индивидуальных заданий в электронном виде
1.10 Примерные зачетные тестовые задания.
Контрольная работа №1. «Исчерпывающий поиск»
Пример одного варианта
1. Разработать и отладить программу, по заданным n и m генерирующую все перестановки с повторениями. Каждая комбинация должна состоять из элементов множества {1, 2,
..., n} и содержать m элементов (m  n). Для каждой комбинации подсчитать сумму S ее элементов. Вывести все комбинации и соответствующие им суммы S в выходной текстовый
файл.
2. Разработать и отладить программу, с помощью алгоритма с возвратом решающую
задачу о ходе коня. Найти только первое из возможных решений. Исходные данные  размер
доски и начальное положение коня ввести с экрана. «Заполненную» доску вывести в выходной текстовый файл.
3. Решить задачу коммивояжера для пяти городов
а) методом полного перебора;
б) методом ветвей и границ;
в) с помощью «жадного» алгоритма.
Сравнить полученные решения
Cij
I
II
III
IV
V
I

36
30
14
15
II
27

16
12
25
III
11
43

26
30
IV
9
13
20

12
V
18
25
24
17

4. Методом динамического программирования построить дерево оптимального поиска
по заданным частотам обращения к внутренним ключам: a1 = 5, a2 = 1, a3 = 3, a4 = 4, a5 = 2.
Частоты обращения к внешним ключам считать равными 0.
Контрольная работа №2. «Алгоритмы на графах. NP-полные задачи»
Пример одного варианта
1. Изменить исходный способ хранения сильно ветвящегося дерева на заданный.
Представление дерева на входе (из входного файла): имя вершины; ссылки на всех ее сыновей. Представление дерева на выходе: имя вершины; ссылки на самого левого сына и правого брата.
2. Неориентированный граф задан списками смежности. Прочитав списки смежности
из входного текстового файла, определить количество компонент связности графа и указать
номера вершин, содержащихся в каждой из компонент.
Указание. Использовать процедуру обхода графа в глубину.
7
3. Составить упорядоченные по алфавиту списки смежности графа; затем, начиная с вершины
«k», выполнить обходы «в глубину» и «в ширину» (в обоих случаях пронумеровать вершины в
порядке их прохождения; составить множества
древесных Т и обратных В рёбер).
4. В данном нагруженном орграфе:
а) с помощью алгоритма Форда-Беллмана
найти расстояния от вершины-источника «1»
до остальных вершин;
б) по известным расстояниям восстановить
кратчайший путь от вершины-источника «1»
до вершины «6».
5. В данном нагруженном орграфе:
а) с помощью алгоритма Дейкстры найти
расстояния от вершины-источника «1» до
остальных вершин;
б) по известным расстояниям восстановить
кратчайший путь от вершины-источника «1»
до вершины «5».
1.11 Примерный перечень вопросов к экзамену.
ИСЧЕРПЫВАЮЩИЙ ПОИСК
1. Алгоритмы с возвратом и их свойства (с доказательством основного свойства)
2. Задача о велосипедном замке и методы её решения. Оценка максимальной сложно-
сти. Генерация всех подмножеств конечного множества
3. Генерация размещений, сочетаний, перестановок (с повторениями и без)
4. Генерация композиций, разбиений
5. Задача о ходе коня и методы её решения. Оценка максимальной сложности
6. Задача о восьми ферзях и методы её решения. Оценка максимальной сложности
7. Задача о паросочетаниях и методы её решения. Оценка максимальной сложности
8. Задача оптимального выбора (о рюкзаке) и методы её решения. Оценка максимальной сложности
9. Задача коммивояжёра и методы её решения. Оценка максимальной сложности
10. Задача о порядке перемножения цепочки матриц и методы её решения. Оценка
максимальной сложности
11. Дерево оптимального поиска. Построение дерева оптимального поиска. Сложность
алгоритма
АЛГОРИТМЫ НА ГРАФАХ
1. Графы и способы их машинного представления. Сильно ветвящиеся деревья и спо-
собы их машинного представления
2. Метод поиска в глубину в графе. Метод поиска в ширину в графе. Задачи, решаемые с помощью поиска в глубину
3. Алгоритм нахождения эйлерова цикла в графе. Сложность алгоритма
8
4. Алгоритм нахождения гамильтонова цикла в графе. Сложность алгоритма. Нахождение в графе точек сочленения
5 Алгоритмы нахождения остовного дерева наиманьшей стоимости. Сложность алгоритмов
6. Задача об изоморфизме графов и пути ее решения. Оценка максимальной сложности.
7. Алгоритм Форда-Беллмана нахождения расстояний от вершины-источника до
остальных вершин. Сложность алгоритма
8. Алгоритм Дейкстры нахождения расстояний от вершины-источника до остальных
вершин. Сложность алгоритма
9. Алгоритм Уоршаллла и Флойда нахождения расстояний между всеми парами вершин Сложность алгоритма
10. Восстановление по расстояниям кратчайшего пути. Сложность алгоритма
11. Определение расстояний в бесконтурном графе с использованием топологической
сортировки. Сложность алгоритма
12. Сети. Потока в сетях. Теорема Форда-Фалкерсона о максимальном потоке
13. Алгоритм нахождения максимального потока в сети
NP-ПОЛНЫЕ ЗАДАЧИ
1. NP-класс. Полиномиальная сводимость задач. Эквивалентность задач. Задача о вы-
полнимости. NP–полная задача
2. Примеры доказательства NP-полноты. Пути решения NP-полных задач
1.12 Комплект экзаменационных билетов.
Билет № 1.
1.13 Примерная тематика рефератов.
Сравнительный анализ методов внешней сортировки
Сравнительный анализ методов внутренней сортировки
Топологическая сортировка и её использование для нахождения кратчайших расстояний в бесконтурном графе
Проблема изоморфизма графов
Методы нахождения k-го наименьшего элемента в заданном массиве
Задача о распределении ресурсов
1.14 Примерная тематика курсовых работ.
Программная реализация алгоритма




решения задачи коммивояжера методом ветвей и границ;
распознавания планарного графа с использованием критерия Понтрягина-Куратовского;
нахождения простой цепи, соединяющей две заданные вершины графа;
нахождения простой цепи, проходящей через все вершины орграфа с использованием теоремы
Redei;





нахождения в данном графе эйлерова цикла;
нахождения в данном графе гамильтонова цикла;
построения базисного графа в данном орграфе;
поиска выхода из лабиринта;
решения «шахматных задач» (о ходе коня, о ферзях) с использованием графического интерфейса.
9
Раздел 2. Методические указания по изучению дисциплины и контрольные задания для
студентов заочной формы обучения.
Заочная форма обучения не предусмотрена.
Раздел 3. Содержательный компонент теоретического материала.
ГЛАВА I. ИСЧЕРПЫВАЮЩИЙ ПОИСК
Алгоритмы с возвратом
Существуют задачи, которые решаются не по заданным правилам вычислений, а путем перебора большого (но конечного!) числа вариантов. Количество этих вариантов зависит от параметров задачи и часто бывает экспоненциальным. Обычно алгоритм решения таких задач
наиболее естественно выражается в терминах рекурсии.
В общем случае дерево решений строят следующим образом. Принимают какой-либо
принцип разбиения множества М всех решений задачи на такие подмножества Мi, для которых
 Мi = М; Мi  Мj =  при i  j.
i
Затем, пользуясь тем же принципом, разбивают полученные подмножества на части и т.д.
После некоторого шага разбиения каждое множество содержит по одному варианту.
Процесс разбиения множества М на подмножества становится наглядным, если его
изобразить с помощью дерева решений. При этом каждому множеству Мi, полученному при
последовательном разбиении множества М на части, ставится в соответствие вершина дерева с тем же обозначением  Мi. От вершины Мi к вершине Мj проводится ребро, если множество Мj получено непосредственным разбиением на части множества Мi. Построенное
таким образом дерево имеет число концевых вершин, равное мощности множества М: для
каждого варианта имеется одна концевая вершина. Дерево решений по-другому называют
деревом полного перебора.
Для решения переборных задач служит метод разработки алгоритма, известный как
backtracking (программирование с возвратом или с отходом назад), который можно описать
как организованный исчерпывающий поиск, который часто позволяет избежать исследований всех возможностей. Характерное свойство алгоритмов с возвратом заключается в следующем: шаги в направлении общего решения фиксируются т.о., что позже можно вернуться вспять, отбрасывая тем самым ветви, которые ведут не к общему решению, а заводят
в тупик.
Процедура с отходом назад сводится к обходу дерева решений. Применительно к задаче о велосипедном замке будем двигаться по дереву, придерживаясь левой ветки, пока это
возможно. Достигнув листа, пробуем соответствующую комбинацию. Если она не подходит,
поднимаемся на один уровень вверх и проверяем, можно ли из текущей вершины спуститься
по другой ветке. Если «да», то двигаемся по самой левой из неисследованных ветвей. Если
«нет», отходим вверх еще на один уровень и пытаемся спуститься из этой вершины. Процесс
заканчивается, когда мы вернулись в корень, причем в дереве не осталось неисследованных
ветвей.
Для решения задачи годится алгоритм с отходом, если эту задачу можно сформулировать так, что все возможные решения могут быть образованы построением векторов с
конечным числом компонент.
Основное свойство алгоритмов с возвратом
10
Теорема. Пусть s>0 и (x1, x2, …, xs1)  частичное решение. Тогда, если выполнены
условия А и Б, то начиная с первой итерации цикла 1, для которой k = s, алгоритм с возвратом генерирует все целочисленные решения, являющиеся расширением вектора (x1, x2, …,
xs1), и приходит к состоянию, когда k = s  1.
Для s = 1 основное свойство означает корректность алгоритма с возвратом.
Задача об обходе конём шахматной доски
Формулировка задачи. Дана доска размером п  п. На поле с координатами (x0, y0) помещается конь  фигура, перемещающаяся по обычным шахматным правилам. Требуется
отыскать такую последовательность ходов (если она ), при которой конь точно один раз побывает на всех полях доски (обойдет доску), т. е. в ходе решения задачи необходимо вычислить n2 1 ходов.
Задача о восьми ферзях
Формулировка задачи. Восемь ферзей нужно расставить на шахматной доске так, чтобы ни один ферзь не угрожал другому.
Обобщение задачи: разместить п ферзей на квадратной доске размером п  п так, чтобы на каждой горизонтальной, вертикальной и диагональной линии было не больше одной
фигуры.
Для п = 2 и п = 3 решения не существует, для п = 4 существует единственное решение
(если не учитывать решения, получающиеся одно из другого поворотом доски), которое показано на рис. ***
1
2
3
4
1
2
3
4
Генерация комбинаторных объектов
В этом параграфе условимся, что все комбинации будем извлекать из множества A = {1, 2, ...,
n}.
Размещениями называются комбинации, составленные из n элементов по m элементов, которые отличаются либо составом элементов, либо порядком.
Пример. n = 4, m = 2: (1, 2), (2,1), (1, 3), (3, 1), (1, 4), (4, 1), (2, 3), (3, 2), (2, 4), (4,2), (3, 4), (4,
3).
n!
Число всех размещений из n по m можно вычислить по формуле: Anm 
.
(n  m)!
Размещениями с повторениями наз. размещения, элементы в которых могут повторяться.
Пример. n = 2, m = 3: (1,1,1), (1,1,2), (1,2,1), ... (2,2,2).
Если при выборе m элементов из n заданных объекты могут повторяться, то каждый
m
из m элементов можно выбрать n способами, а значит, всего таких способов: An = nm.
Размещения из n элементов по n называются перестановками. Все перестановки
имеют одинаковый состав и отличаются только порядком элементов.
11
****** Пример. n = 3: (1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1).
Общее число перестановок обозначается Pn и вычисляется по формуле: Pn = n!
Перестановками с повторениями называются перестановки, элементы в которых
могут повторяться. Пусть в одной перестановке содержится m объектов, причём первый объект входит в эту совокупность 1 раз (1>0), второй  2 раз (2>0),... , n-й  n раз (n>0),
т.е. m=1+2+...+n. При 1=2=... =n=1 перестановки с повторениями совпадают с обычными перестановками.
Пример. n = 2, m = 3: используются оба элемента!!!
«1»  2, «2»  1: (1, 1, 2), (1, 2, 1), (2, 1, 1);
«1»  1, «2»  2: (1, 2, 2), (2, 1, 2), (2, 2, 1).
Число различных перестановок, имеющих состав (1,2,...,n) равно:
m!
P(1,2,...,n)=
, где
m = 1 + 2 + ... + n.
1! 2!   n!
При генерации перестановок с повторениями важно помнить, что в отличие от размещений с повторениями, комбинация должна содержать все n объектов, некоторые из которых могут повторяться. Сгенерировать перестановки с повторениями можно следующим
образом: сформировав очередное размещение с повторениями, проверить, все ли n объектов в нем содержатся? Если «да», то это перестановка с повторениями, и ее следует распечатать. Если «нет», то эту комбинацию надо пропустить.
Сочетаниями называются комбинации, составленные из n элементов по m элементов
и отличающиеся хотя бы одним элементом. Сочетания различаются только составом элементов; порядок элементов здесь не имеет значения.
n!
Число всех сочетаний из n по m можно вычислить по формуле: Cnm 
.
m! (n  m)!
За основу возьмем процедуру генерации размещений. Будем составлять очередную
комбинацию в порядке возрастания ее элементов. Это означает, что k-я компонента обязательно должна быть больше, чем k1-я.
Сочетаниями с повторениями называются сочетания, элементы в которых могут повторяться.
Общее число сочетаний с повторениями из n по m составляет:
(n  m  1)!
C nm = P(n1, m) =
 C nm m 1 .
(n  1)! m!
Генерация сочетаний с повторениями практически не отличается от формирования
сочетаний без повторений. Очередная комбинация составляется в порядке неубывания ее
элементов.
Последовательность (z1, z 2, …, z n) называется композицией натурального числа m, если
z1 + z2 + …+ zn = m, причем учитывается порядок чисел zi. Как правило, представляют интерес
композиции, в которых либо все zi  0, либо все zi > 0.
Начнем с генерации композиций при условии: zi  0 для i = 1, 2, ..., n. Известно, что существует взаимнооднозначное соответствие между множеством решений в целых неотрицательных числах уравнения z1 + z2 + …+ zn = m и множеством сочетаний с повторениями из n по m.
Значит, вместо композиций достаточно сформировать все сочетания с повторениями
из n по m (x1, x2, …, xm), после чего в каждом таком сочетании подсчитать z1  количество
вхождений «1», z2  количество вхождений «2», ..., zn  количество вхождений «n».
12
Пусть теперь zi > 0 для i = 1, 2, ..., n. Введем новые переменные ri = zi  1 (zi  0). В этих
переменных соответствующая композиция (r1, r2, …, rn) будет для числа m  n. Генерация слагаемых ri  0 композиции (r1, r2, …, rn) разобрана выше. Добавляя к каждому из ri по единице, получим слагаемые композиции (z1, z2, …, zn).
Последовательность (z1, z 2, …, z n) называется разбиением натурального числа m, если
z1 + z2 + …+ zn = m, все zi > 0 и порядок чисел z i не важен.
Будем формировать разбиение в порядке неубывания его элементов, т.е. полагать, что
z1  z2  … zn . За основу возьмем процедуру генерации сочетаний с повторениями. Кроме
входных параметров int k и int x_k_1, добавим еще один параметр: int sum. Первоначально
sum = 0. На k-м шаге: sum = z1 + z2 +... + zk1 . Вектор формируется до тех пор, пока sum < m.
Оценка сложности алгоритмов с возвратом
Пусть дерево Т  это та часть дерева полного перебора Тp, которая содержит только
пройденные в процессе поиска с возвратом вершины. Очевидно, что сложность алгоритма с
возвратом определяется количеством вершин дерева Т.
Аналитическое выражение для оценки количества вершин дерева Т удается получить
редко, т.к. в общем случае трудно предсказать, как будут взаимодействовать различные
ограничения по мере того, как мы продвигаемся вглубь дерева. Однако существует вероятностный метод оценки размеров дерева  метод Монте-Карло. Идея метода состоит в проведении ряда испытаний; при этом каждое испытание представляет собой процесс поиска с
возвратом со случайно выбранными значениями xk.
Предположим, что построено частичное решение (x1, x2, …, xk1). Компонента xk выбирается из множества Ak. Пусть Sk (Sk  Ak)  это множество тех значений y, для которых Р(x1,
x2, …, xk1, y)=1. Если | Sk |  0, то xk выбирается случайно из Sk с вероятностью 1/| Sk |.
Результатом испытаний является случайная величина Z  количество вершин дерева
Т. Ее значение можно подсчитать, исходя из следующих соображений: на 0-ом уровне дерева
Т находится одна (корневая) вершина, на 1-ом уровне находится | S1 | вершин, на 2-ом
уровне  | S1|| S2| вершин (по | S2 | на каждую вершину первого уровня), на третьем  | S1|| S2||
S3| вершин (по | S3 | на каждую вершину второго уровня) и т.д.
z = 1 + | S1| + | S1|| S2| + | S1|| S2|| S3| + ...
Проведя N испытаний, получим п-ть z1, z2,..., zN значений случайной величины Z, причем каждое из этих значений наблюдалось по одному разу. В качестве наиболее вероятного
значения естественно выбрать математическое ожидание M(Z) случайной величины Z.
Полагая, что значения z1, z2,..., zN равновероятны (по 1/ N), найдем количество вершин дерева Т:
M(Z) = (z1 + z2 + ... + zN) / N.
Алгоритм поиска с возвратом легко преобразуется применительно к реализации таких
испытаний; для этот при | Sk | = 0 вместо возврата нужно просто закончить испытание. Приведенный ниже алгоритм осуществляет N испытаний для аппроксимации числа узлов в дереве.
average=0;
for (i=1; i<=N; i++)
{sum=0; product=1; S1=A1; k=1;
while (Sk<>)
{product*= |Sk|; sum+=product; взять в качестве xk случайный элемент из Sk;
k++; переопределить Sk; };
average+=sum;};
average/=N;
13
Это вычисление по методу Монте-Карло можно использовать для оценки эффективности поиска с возвратом путем сравнения его с эталоном, полученным для задачи с меньшей размерностью. Например, при прогоне задачи о ферзях для отыскания всех решений в
случае доски размером 1010 требуется поиск на дереве с 14 566 узлами. В случае 1111 после 1000 испытаний по методу Монте-Карло оценка числа узлов составила 70 806; поэтому
можно было ожидать, что вычисления для доски 1111 потребуют примерно в 4,9 больше
времени, чем для доски 1010. При прогоне программы для доски 1111 оказалось, что фактическое дерево имеет 70 214 узлов и время вычисления в 5,3 раза больше, чем в случае
1010 (см. Reingold).
Задача о паросочетаниях на примере задачи о стабильных браках
Формулировка задачи. Пусть имеются два непересекающихся множества А и В одинаковой мощности п. Требуется найти биективное отображение : А → В, которое удовлетворяет некоторому дополнительному условию. Другими словами, нужно составить множество пар вида
{ (a1,  (a1)), (a2,  (a2)),…, (an,  (an)) },
где ai  А,  (ai)  B (i = 1, 2, …, n), причем  (ai) ≠  (aj) при i ≠ j (i, j = 1, 2, …, n).
Для выбора таких пар существует много различных критериев; один из них называется правилом стабильных браков. Предположим, что А  множество мужчин, а В  женщин. У
каждого мужчины и каждой женщины имеются свои различные правила предпочтения возможного партнера.
Если среди п выбранных пар существуют мужчины и женщины, не состоящие между
собой в браке, но предпочитающие друг друга, а не своих фактических супругов, то такое
множество браков называется нестабильным. Если же таких пар нет, то множество считается
стабильным.
Подобная ситуация характерна для многих похожих задач, где нужно проводить распределение в соответствии с некоторыми правилами предпочтения. Например, выбор студентами учебных заведений, призывниками  родов войск и т. п.
Будем полагать, что правила предпочтения постоянны и в процессе выбора не изменяются. Это упрощает задачу, но, как всякая абстракция, сильно искажает действительность.
Исходные данные задачи представляют собой две матрицы, задающие предпочтительных партнеров для мужчин и женщин: “women for men” wm[1..n][1..n] и “ men for women ” mw [1..n] [1..n]. Элемент wm [m] [r] матрицы wm равен номеру женщины, стоящей на rм месте в списке предпочтений мужчины m, элемент wm [w] [r] матрицы wm равен номеру
мужчины, стоящем на r-м месте в списке предпочтений женщины w.
Решение. Результатом работы программы является вектор X = (x1, x2, …, xn), компоненты которого определяются следующим образом: (xm = w)  (женщина w является женой мужчины m).
Для поддержания симметрии между мужчинами и женщинами введем дополнительный массив Y = (y1, y2, …, yn) с компонентами: (yw = m)  (xm = w). Фактически массив Y излишен, так как значение yw можно определить с помощью простого просмотра массива X. Однако наличие массива Y повышает эффективность алгоритма.
Будем искать решение поставленной задачи, пытаясь объединять в пары элементы
двух множеств до тех пор, пока эти множества не будут исчерпаны. Обозначив через r ранг
женщины в списке предпочтений мужчины m, запишем блочный вариант рекурсивной процедуры с возвратом TRY(m), осуществляющей поиск супруги для m-го мужчины; поиск идет
в порядке списка предпочтений именно этого мужчины.
По определению, стабильность связана со сравнением предпочтительности партнеров (т.е. со сравнением рангов). Введем в рассмотрение две матрицы: rwm[1..n][1..n] и
14
rmw[1..n][1..n]. Здесь элемент матрицы rwm[m][w] равен рангу женщины w в списке предпочтений мужчины m, а элемент матрицы rmw[w][m] равен рангу мужчины m в списке предпочтений женщины w.
Значения этих вспомогательных матриц постоянны; их можно определить в самом
начале по значениям матриц wm и mw.
Итак, мы пытаемся определить возможность брака между мужчиной m и женщиной
w, где w = wm[m][r], т.е. женщина w стоит в списке предпочтений мужчины m на r-ом месте.
Для нестабильности существуют 2 симметричные возможности:
либо существует женщина pw, которая для m предпочтительнее w, причем для pw m
предпочтительнее её супруга,
либо существует мужчина pm, который для w предпочтительнее m, причем для pm w
предпочтительнее его супруги.
Исследуя первый источник неприятностей, мы проверяем замужних женщин pw, которые для m милее, чем w:
pw = wm [m] [i] при i<r (стоят в списке предпочтений
раньше w),
причем эти женщины предпочитают m, а не своего мужа:
rmw [pw] [m] < rmw [pw]
[y[pw]].
Что касается второго источника неприятностей, то мы должны проверить всех кандидатов pm, которые для w предпочтительнее супруга, т.е. проверить симпатии всех предпочитаемых ею мужчин:
pm = mw [w] [i] для i < rmw [w] [m].
В этом случае также надо сравнивать ранги rwm [pm] [w] и rwm [pm] [x[pm]]. Однако
здесь надо проводить сравнение только в том случае, если pm уже женат, т.е. когда pm < m.
Алгоритмы с возвратом часто употребляются для выбора одного или нескольких в каком-то смысле оптимальных решений. В приведенном примере такими могут быть, скажем,
решения, в среднем больше удовлетворяющие мужчин или женщин или и тех и других.
Так, решение с минимальным значением MR  суммы рангов всех жен  называется
стабильным и оптимальным для мужчин, а решение с минимальным значением WR  суммы
рангов всех мужей  называется стабильным и оптимальным для женщин.
n
MR =

n
rwm [m] [x[m]]; WR =
m 1

rmw [x[m]] [m].
m 1
Метод ветвей и границ на примере задачи оптимального выбора (о рюкзаке)
Применимый для решения многих дискретных комбинаторных задач метод, известный как метод ветвей и границ (МВГ), похож на алгоритмы с возвратом тем, что он также
исследует дерево решений. Но если алгоритмы с возвратом позволяют найти решения, удовлетворяющие определенным свойствам, МВГ ориентирован в большей степени на оптимизацию.
Предположим, что каждому возможному решению задачи приписано некоторое значение числовой функции f. Метод ветвей и границ ищет одно или все оптимальные решения,
т.е. те, на которых функция f достигает максимального (или минимального) значения. Познакомимся с МВГ на примере задачи оптимального выбора (о рюкзаке).
Формулировка задачи. Имеется n объектов, пронумерованных от 1 до n. Каждый из
этих объектов i характеризуется весом wi и ценностью vi. Оптимальной называется выборка,
имеющая максимальную сумму ценностей при заданном ограничении на сумму весов.
Требуется извлечь оптимальную выборку из данного множества объектов.
С такой проблемой сталкивается любой путешественник, упаковывающий чемоданы
и стремящийся выбрать n предметов так, чтобы ценность их была оптимальной, а общий вес
не превышал какого-то допустимого предела.
15
Очевидно, что в этой задаче требуется найти выборку s, доставляющую максимум
функции
Поставленную задачу будем решать методом ветвей и границ, который состоит из
ветвления и отсечений, обусловленных оценкой границ.
Ветвление. На этом этапе строится дерево решений. В задаче о рюкзаке корню (нулевой уровень дерева решений) соответствуют все 2n выборок. Разбиение производим по принципу:
М = М1  M 1 , где
М1 и M 1  множества выборок, соответственно содержащих и не содержащих первый объект. Вершины М1 и M 1 находятся на первом уровне дерева решений.
Далее, из некоторой вершины X k1-го уровня дерева решений проводим ребра в вершину Yk, которой соответствуют выборки, содержащие k-й объект, и вершину Yk , которой
соответствуют выборки, не содержащие k-й объект.
Оценка границ
Каждой вершине дерева решений припишем верхнюю границу цены выборки из множества, представленного вершиной (верхняя граница V вершины X характеризуется тем, что
цена выборки из множества X, не может оказаться больше, чем V).
Верхняя граница должна быть задана таким образом, чтобы для любого листа дерева
решений ее значение совпадало со значением функции f.
Вычисление этих верхних границ  основной фактор, дающий экономию усилий в
МВГ. Предположим, что, спустившись до листа по одной из веток дерева решений, мы уже
нашли выборку с ценой m. Тогда в другой ветке, попав в вершину с верхней границей M  m,
мы уже не будем рассматривать эту вершину и все следующие за ней, т.е. отсечем ветку,
вершинам которой соответствуют заведомо худшие варианты решений.
В качестве верхней границы примем Vt  потенциальную ценность, т.е. ценность, которую еще в принципе можно достичь. Таким образом, оценка корня дерева решений будет
равна суммарной цене всех объектов исходного множества:
n
Vt (root) =
v
i 1
i
.
Далее, если из некоторой вершины X с оценкой Vt мы провели ребра в вершины Yk и
Yk , то вершина Yk будет иметь ту же оценку Vt, что и ее предок X, а вершина Yk  оценку Vt
 v[k] (отказавшись от k-го объекта, мы заведомо потеряли его цену).
Задача коммивояжера
Метод ветвей и границ хорошо работает и в задаче коммивояжера.
Формулировка задачи. Имеется n данных городов. Известна стоимость прямого проезда из города i в город j (i ≠ j; i, j = 1, 2, ... n). Требуется найти маршрут, который проходит
через каждый из n данных городов в точности один раз и при этом имеет наименьшую стоимость.
В терминах теории графов: вершина  город; дорога между городами  ребро, которому приписан вес (стоимость проезда); найти надо гамильтонов цикл (ГЦ) с минимальным
весом (под весом цикла понимается сумма весов входящих в него ребер).
Исходной в данной задаче является матрица С, элемент которой сij0 равен стоимости
(обычно в единицах времени, денег или расстояния) прямого проезда из города i в город j.
Задача наз. симметричной, если сij = сji для всех i и j, т.е. если стоимость проезда между каж-
16
дыми двумя городами не зависит от направления. Чтобы решать задачу методом ветвей и
границ, необходимо положить сii =  всех i.
Очевидно, что в этой задаче требуется найти ГЦ s, доставляющий минимум функции
f, заданной следующим образом: f(s) =  cij .
( i , j )s
Ветвление. Корень дерева соответствует множеству всех возможных ГЦ. Ветви, выходящие из корня, определяются выбором некоторого ребра (i, j). Это ребро разделяет R на
два множества Rij иRij . В множество Rij входят циклы из R, содержащие ребро (i, j), а в Rij
 циклы, не содержащие (i, j).
Вообще, если Х  вершина дерева, а (i, j)  ребро ветвления, то обозначим вершины,
непосредственно следующие за Х, через Y иY. Множество Y обозначает подмножество
циклов из Х с ребром (i, j), а множество Y  подмножество Х без ребра (i, j).
Каждой вершине дерева решений припишем нижнюю границу стоимости ГЦ из множества, представленного вершиной (нижняя граница W вершины V характеризуется тем, что
стоимость ГЦ, проходящего через эту вершину, не может оказаться меньше, чем W).
Нижняя граница должна быть задана таким образом, чтобы для любого листа дерева
решений ее значение совпадало со значением функции f.
Предположим, что, двигаясь по одной из веток дерева решений, мы нашли ГЦ со стоимостью m. Тогда в другой ветке, попав в вершину с нижней границей M  m, мы уже не будем рассматривать эту вершину и все следующие за ней.
Основной шаг при вычислении нижних границ известен как приведение. Оно основано на следующих соображениях:
1. В связи с тем, что каждый город нужно посетить ровно один раз, каждый ГЦ содержит только один элемент из каждого столбца и каждой строки матрицы C. Заметим, что
обратное утверждение в общем случае не верно. Например, множество {(1,4),(4,1),(2,3),(3,2)}
не образует ГЦ.
2. Если вычесть константу h из каждого элемента какой-то строки или столбца матрицы C, то стоимость любого ГЦ при новой матрице C* ровно на h меньше стоимости того
же ГЦ при матрице C. Поскольку любой ГЦ должен содержать ребро из данной строки или
данного столбца, стоимость всех ГЦ уменьшается на h. Это вычитание наз. приведением
строки (или столбца).
Пусть t  оптимальный ГЦ при матрице C. Тогда его стоимость равна: f(t) =
c
( i , j )t
ij
.
Если C* получается из C приведением строки (или столбца), то t должен остаться оптимальным ГЦ при C* и
f(t) = h + f*(t),
где f*(t)  стоимость ГЦ t при C*.
Под приведением всей матрицы С понимается следующее. Последовательно проходим строки матрицы С и вычитаем значение наименьшего элемента строки из каждого элемента этой строки. Потом то же самое делаем для каждого столбца. Если для некоторого
столбца (строки) наименьший элемент равен нулю, то считается, что этот столбец (строка)
уже приведен. За h примем сумму всех вычтенных элементов. Полученную в результате матрицу стоимостей наз. приведенной из С.
Выбор ребра для ветвления
Можно предположить, что ребра, соответствующие нулевым стоимостям, скорее всего, войдут в оптимальный ГЦ. Ребро для ветвления (l, k) нужно выбирать так, чтобы
попытаться получить возможно большую по величине нижнюю границу для множестваY. (Идея проста: в Y пытаться оставлять варианты получше, а варианты похуже скидывать вY). Пусть ребро (i, j) имеет сij = 0 в С*. Обозначим
Dij = (min стоимость в строке i, не включая сij) + (min стоимость в столбце j, не включая сij).
17
Тогда, вспомнив процедуру нахождения нижней границей для множества R1,3, получим, что
в общем случае для Y эта граница задается в виде:
w(Y) = w(X) + Dij.
Чтобы эта оценка была возможно большей, надо из всех ребер (i, j) с сij = 0 в текущей
матрице С* выбрать то, которое дает наибольшую добавку к w(X) в выражении для w(Y).
Таким образом, следующее ребро ветвления (l, k) выбираем из условия: Dlk =
{
max
(i, j ) / cij  0
Dij }.
Задача о порядке перемножения матриц
Если очевидное разбиение задачи размера n сводит ее к n задачам размера n-1, то в
этом случае часто можно получить более эффективные алгоритмы с помощью табличной
техники, называемой динамическим программированием.
Динамическое программирование, в сущности, вычисляет решение для всех подзадач.
Вычисление идет от малых подзадач к большим, промежуточные ответы при этом запоминаются в таблице. Таким образом, если подзадача решена, то ее ответ хранится в памяти
ЭВМ и в процессе работы программы заново не вычисляется.
Принцип ДП рассмотрим на примере вычисления произведения n матриц:
М = М1 М2... Мn,
где Мi - матрица с ri-1 строками и ri столбцами. Таким образом, размерности перемножаемых
матриц описываются последовательностью чисел r1, r2,..., rn. Порядок, в котором перемножаются эти матрицы, может существенно сказаться на общем числе операций, требуемых
для вычисления М, независимо от алгоритма, применяемого для умножения матриц.
Обычный метод умножения [pq]- матрицы на [qr]-матрицу требует pqr операций.
Рассмотрим произведение: М=М1 [1020]М2 [2050]М3 [501]М4 [1100].
Порядок М=М1(М2(М3М4)) потребует совершить 125000 операций, тогда как порядок М=(М1(М2М3))М4 потребует совершить всего 2200 операций.
Познакомимся с алгоритмом, позволяющим определить тот порядок перемножения
матриц, при котором потребуется совершить наименьшее количество операций. Обозначим
через sij минимальную сложность вычисления матрицы
Мi Мi+1... Мj,
(1  i  j n).
При ij выберем k (ik<j). Выразим sij через sik и sk+1,j - минимальные сложности вычисления
матрицы Мi Мi+1... Мk с размерностью [ri-1rk] и матрицы Мk+1 Мk+2... Мj с размерностью [rkrj] соответственно.
0, при i = j,
s ij   min (s  s
k +1, j  ri -1, j  rk  r j ),
ik < j ik
при i  j.
Величины sij вычисляются в порядке возрастания разностей индексов. Начинают с вычисления sii для каждого i, затем вычисляют все значения si,i+1, затем si,i+2 и т.д. Так как
(k-i) <(j-i) и (j-(k+1))<(j-i),
то при вычислении sij значения sik и sk+1,j будут уже известны.
18
Дерево оптимального поиска
При рассмотрении деревьев поиска и их разновидностей до сих пор предполагалось,
что частота обращения ко всем вершинам одинакова, т. е. все ключи с равной вероятностью
фигурируют как аргументы поиска. Однако встречаются ситуации, когда есть информация о
вероятностях обращения к отдельным ключам. Обычно для таких ситуаций характерно "постоянство" ключей, т. е. в дерево поиска не включаются новые ключи и не исключаются старые; структура дерева остается неизменной.
Пример. Сканер транслятора, определяющий, не относится ли каждое слово (идентификатор) к классу ключевых (зарезервированных) слов. Статистические измерения на сотнях
транслируемых программ в этом случае позволяют определить относительную частоту обращения к каждому из ключей.
Пусть в дереве поиска задана вероятность pi обращения к вершине i: (i = 1, 2,..., n), причем
n

pi = 1.
i 1
Попытаемся организовать дерево поиска так, чтобы общее число шагов поиска, подсчитанное для достаточно большого числа обращений, было минимальным. С этой целью
каждую вершину будем характеризовать величиной pi  hi, где hi  уровень, на котором расположена вершина i (отсчет будем вести от корня, который находится на уровне 1 (а не 0),
поскольку он первым встречается на пути поиска). Назовем взвешенной длиной пути s1 сумму вида:
n
s1 =  pi  hi .
i 1
Дерево поиска называется оптимальным, если при заданном множестве ключей и заданном распределении вероятностей оно имеет минимальную взвешенную длину пути.
Зачастую слова, встречающиеся в исходном тексте, не являются ключевыми словами;
поэтому обобщим поставленную задачу: будем учитывать возможность неудачного поиска.
Для этого будем различать внутренние и внешние вершины:
 внутренние  те, которые действительно присутствуют в дереве поиска (уровень
такой вершины с ключом ki  hi, вероятность обращения к ней  pi);
 внешние  те, которых реально в дереве поиска нет: ключ х такой вершины попадает в интервал от kj до kj+1 (kj < х < kj+1), где kj и kj+1  ключи внутренних вершин
(уровень такой вершины обозначим hj*, вероятность обращения к ней  qj).
Пример на рис. *** (если pi = qi = 1, то s = 25).
Вместо взвешенной длины пути s1 будем рассматривать обобщенную взвешенную
длину пути s2, называемую ценой дерева поиска:
n
s2 =  pi  hi +
i 1
n

n
n
qj  hj*,
где

i 1
j 0
pi +

qj = 1.
j 0
При построении оптимального дерева вместо вероятностей обращения к вершинам
удобнее использовать натуральные числа  частоты обращения к вершинам. Обозначим их
ai  число обращений к вершине с ключом ki ,
19
bj  число обращений к вершине с ключом x: kj < х < kj+1,
b0  число обращений к вершине с ключом x: х < k1,
bn  число обращений к вершине с ключом x: kn < х и будем минимизировать цену дерева:
n
s =  ai  hi +
i 1
n

bj  hj*.
j 0
Основное свойство оптимального дерева
Так как улучшение любого поддерева ведет к улучшению оптимального дерева в целом, то все поддеревья оптимального дерева тоже оптимальны.
На этом свойстве основан алгоритм, который, начиная с отдельных вершин, систематически находит все большие и большие оптимальные деревья. Таким образом, дерево растет
от концевых вершин к корню.
Обозначим через w общее число обращений к дереву поиска Т, имеющего цену s:
n
w =  ai +
i 1
n

bj.
j 0
Величина w называется весом дерева.
Пусть также sL и sR  соответственно цены левого ТL и правого ТR поддеревьев дерева
Т.
Методом матем. индукции можно доказать, что справедливо следующее соотношение:
s = s L + w + s R.
В этой сумме w учитывает увеличение цены за счет смещения вершин с более высокого уровня в поддеревьях ТL и ТR на один уровень вниз в дереве Т.
Пусть Тij  оптимальное дерево, состоящее из вершин с «соседними» ключами ki+1,
ki+2, kj. Обозначим вес этого дерева wij, а его цену  sij. Таким образом, Т0n  оптимальное дерево, содержащее все заданные ключи,  имеет вес w0n и цену s0n.
Построение начинается с поддеревьев Тii, состоящих из одной концевой вершины.
Очевидно, что для них: wii = sii = bi (i = 0, 1,..., n).
Для оптимального дерева Тij справедливы следующие рекуррентные соотношения:
wi j = wi, j1 + aj + bj, si j = wi j + min ( si,k1 + sk j)
ik  j
(0  i < j  n).
Иными словами, из всех возможных оптимальных поддеревьев левое поддерево Тi,k1
и правое поддерево Тk j выбираются так, чтобы новое дерево Тij тоже было оптимальным.
Как и в задаче о порядке перемножения матриц, сложность представленного алгоритма составляет О(n3). Прием, предложенный Д. Кнутом, позволяет снизить эту величину до
О(n2). Пусть ri j  это значение k, при котором достигается минимум. Оказывается, поиск ri j
можно ограничить значительно меньшим интервалом.
В самом деле, удалим левый узел в дереве Тij. Получим дерево Тi+1, j. Так как у нового
дерева корень либо останется на месте, либо сдвинется вправо, то k(Тi+1, j)  k(Тij), т.е. ri+1, j 
rij.
20
С другой стороны, добавим к дереву Тi, j1 вершину справа. Получим дерево Тij. У нового дерева корень либо останется на месте, либо сместится вправо: k(Тij)  k(Тi, j1), т.е. rij 
ri, j1.
Окончательно получаем соотношение: ri, j1  rij  ri+1, j, которое ограничивает поиск
возможных значений для rij.
Решение задачи коммивояжера методом динамического программирования
В случае задачи о коммивояжере идея представления задачи в виде многошагового
процесса реализуется следующим образом. Отметим среди n точек, которые нужно обойти,
произвольную точку j0, которую будем считать точкой старта и финиша. Первым этапом
принятия решения будем считать выбор первой точки, в которую надо идти из места старта,
вторым этапом — выбор следующей точки и т. д.
Допустим, что, правильно выбрав решение на всех предыдущих этапах, мы пришли в
точку i. Пусть при этом не пройденными остались точки j1, j2,…, jk. Обозначим длину кратчайшего пути из точки i до финиша j0 через fi(j1, j2,…, jk), подчеркнув тем самым, что мы
находимся в точке i, и осталось обойти множество точек с индексами j1, j2,…, jk.
Если из точки i направиться в точку jm и затем двигаться по кратчайшему маршруту,
то коммивояжеру предстоит пройти путь длиною
d i , jm  f jm  j1 , j2 ,..., jm 1 , jm 1 ,..., jk 
.
Очевидно, что правильным решением будет то, при котором эта сумма имеет минимальное значение:
f i  j1 , j2 ,..., jk   min d i , jm  f jm  j1 , j2 ,..., jm 1 , jm 1 ,..., jk  
1 m  k
(*)
Нам удалось выразить функцию fi(j1, j2,…, jk) через аналогичные по смыслу функции
f jm  j1 , j2 ,..., jm 1 , jm 1 ,..., jk 
от меньшего числа аргументов. Все значения функций fi(j1) известны — это сумма расстояний от точки i до j1 и от точки j1 до точки старта — финиша j0.
Опираясь на знание значений этих функций, по формуле (*) легко вычислить совокупность всех значений функций fi(j1, j2), где j1, j2, i — неравные между собой числа, заключенные между 1 и n:

d i , j  f j1  j2  
f i  j1 , j2   min  1

d i , j2  f j2  j1  
.

Аналогично,
d i , j1  f j1  j2 , j3  


f i  j1 , j2 , j3   min d i , j2  f j2  j1 , j3  


d i , j3  f j3  j1 , j2  
и т.д.
Преимущество, которое дает ДП, по сравнению с полным перебором, состоит в том,
что вместо прямого сравнения (n  1)! вариантов просматривается значительно меньшее число комбинаций и на всех этапах решения задачи производится n(n 1) сравнений. Основная
трудность при решении задачи о коммивояжере методом ДП  это проблема запоминания
промежуточных результатов. Для того, например, чтобы вычислить все значения функции
2
fi(j1, j2), необходимо предварительно запомнить Cn чисел fi(j1). Чтобы вычислить значения
21
3
fi(j1, j2, j3), необходимо помнить Cn чисел и т. д.
Наиболее критическим является случай, когда k достигает значения (n 1) / 2. На этом
этапе в задаче с 11 городами приходится запоминать 300 чисел, в задаче с 17 городами — 12
000 чисел, в задаче с 23 городами — 1 300 000 чисел. Несмотря на эти трудности, ДП является одним из перспективных методов решения задачи о коммивояжере и сходных с нею NPполных задач.
“Жадные” алгоритмы
Задача. Имеются монеты достоинством 50, 10, 5 коппек и 1 копейка. Требуется вернуть сдачу 77 копеек.
Решение.
1. Выберем монету самого большого достоинства, но не больше 77 копеек — 50 копеек. Найдем разность 77-50=27.
2. Выберем монету самого большого достоинства, но не больше 27 копеек — 10 копеек. Найдем разность 27-10=17 и т.д.
Окончательно получим 77=50+10+10+5+1+1. Заметим, что нам удалось составить самый короткий список список монет требуемого достоинства.
Примененный нами алгоритм внесения изменений называется “жадным”. На каждой
отдельной стадии “жадный” алгоритм выбирает тот вариант, который является локально оптимальным в том или ином смысле.
Надо сказать, что алгоритм для определения сдачи обеспечивает в целом оптимальное
решение лишь вследствие особых свойств монет. Если бы у нас имелись монеты достоинством 1 копейка, 5 и 11 копеек и нужно было бы сдать сдачу 15 копеек, то “жадный” алгоритм выбрал бы следующую последовательность монет: 11, 1, 1, 1, 1, т.е. всего пять монет.
Однако в данном случае можно было бы обойтись тремя монетами по 5 копеек.
Последний пример показывает, что не каждый “жадный” алгоритм позволяет получить оптимальный результат в целом. “Жадная” стратегия подчас обеспечивает лишь сиюминутную выгоду, в то время как в целом результат может оказаться неблагоприятным.
Существуют задачи, для которых ни один из известных “жадных” алгоритмов не позволяет получить оптимального решения; тем не менее с помощью некоторых “жадных” алгоритмов с большой вероятностью можно полчить “хорошие” решения. Нередко бывает достаточно найти “почти оптимальное” решение, характеризующееся стоимостью, которая не
больше некоторой заданной величины (в случае поиска минимума). В таких случаях “жадный” алгоритм оказывается, как правило, самым быстрым способом получить “хорошее”
решение.
Вообще говоря, если рассматриваемая задача такова, что единственным способом получить оптимальное решение является использование метода полного поиска, тогда “жадный” алгоритм или другой эвристический метод получения хорошего (хотя и необязательно
оптимального) решения может оказаться единственным реальным средством достижения результата.
Для рассмотренной в предыдущем параграфе задачи коммивояжера тоже можно
применить “жадный” алгоритм: сначала выбираем самое короткое ребро, а затем критерием
выбора очередного ребра является то, что рассматриваемое ребро (в сочетании с уже выбранными ребрами)
 не приводит к появлению вершины со степенью три и более;
 не образует “короткий” цикл.
ГЛАВА II. АЛГОРИТМЫ НА ГРАФАХ
22
Графы, их вершины, рёбра и дуги
Рассмотрим множество V={v1,v2,...,vn}, n2, и множество E={e1,e2,...,em}, элементами
ek которого являются двухэлементные подмножества {vi, vj} множества V. Пара множеств
V и E называется неориентированным графом F(V,E) с множеством вершин V и множеством
ребер E. При этом говорят, что неориентированное ребро ek соединяет вершины vi, vj или
ребро ek и вершины vi, vj инцидентны. Вершины vi и vj называют смежными.
Граф F(V,E) может быть изображен геометрически. Для этого некоторые n точек
трехмерного пространства помечаются элементами множества вершин V и вершины vi и vj
соединяются линией, если {vi, vj} Е. Геометрическое изображение графа будем называть
диаграммой.
Пример 3.1. Пусть V={v1,v2,v3,v4}, а элементами множества E являются все возможные
множества вида {vi, vj} при i,j=1,2,3,4; ij. Диаграмма графа приведена на рис. 3.1, а.
Пусть теперь множество E={e1,e2,...,em} представляет собой некоторое бинарное отношение на множестве V (EVV). Тогда пара множеств V и E называется ориентированным
графом (орграфом) F(V,E) с множеством вершин V и множеством ребер E.
Ребро ориентированного графа называется дугой. Для дуги ek=(vi, vj) вершина vi
называется начальной, а vj  конечной. Иными словами, ребро ek выходит из вершины vi и
заходит в вершину vj. Как и в случае неориентированного ребра, дуга ek инцидентна вершинам vi и vj, а вершины vi и vj инцидентны дуге ek. Вершины vi и vj также называют смежными.
Ребро, у которого концевые точки совпадают, называется петлей.
Пример 3.2. Пусть V={3, 8, 24}. Зададим на этом множестве отношение
E={(u,w)/ u - делитель w; u,wV}={(3,3), (3,24), (8,8), (8,24), (24,24)}.
Диаграмма графа приведена на рис. 3.1, б.
Из приведенных определений графов следует, что в них
отсутствуют кратные, или параллельные, ребра, соединяющие
одни и те же пары вершин. Кроме того, в неориентированном
графе не допускаются петли.
Однако иногда удобно снять
указанные ограничения.
Рис. 3.1.
Граф, содержащий кратные ребра называется мультиграфом. Граф, содержащий петли и (или) кратные ребра, называется псевдографом.
Два графа F и F* изоморфны, если существует такое взаимно однозначное соответствие между множествами их вершин V и V*, что вершины соединены рёбрами в одном из
графов тогда и только тогда, когда соответствующие им вершины соединены в другом графе.
Если рёбра ориентированы, то их направления также должны соответствовать друг другу.
Все изоморфные графы имеют одинаковые свойства.
Вершина, не инцидентная никакому ребру, называется изолированной. Граф, состоящий только из изолированных вершин, называется нуль-графом (пустым графом) и обозначается через 0. Для нуль-графа множество ребер  пустое: Е=.
23
Другим важным частным случаем является полный граф, в котором каждая вершина
множества V соединена ребром со всеми остальными вершинами этого множества. В дельнейшем полный неориентированный граф с n вершинами будем обозначать Kn. В ориентированном полном графе для каждой пары вершин имеются два ребра: по одному в каждом
направлении.
Пример. На рис. 3.1, а представлен граф K4.
Граф H(VH, EH) называется частью графа F(V, E) (обозначение: HF), если VH  V,
EH  E. Нуль-граф является частью каждого графа.
Особенно важный тип
частей составляют подграфы.
Пусть V*  V. Подграф F*(V*,
E*) графа F  это такая часть
графа F(V, E), множество рёбер E* которого составляют
все рёбра графа F(V, E), оба
Рис. 3.3.
конца которых лежат в V*.
Если V* = V, то подграф F*(V*, E*) совпадает с F(V, E). В противном случае подграф
F*(V*, E*) называется собственным подграфом графа F*(V*, E*). Для единичной вершины
V* = {а} подграф F*(V*, E*) состоит из петель в а.
Пример (рис. 3.3). Для графа 3.3, а граф 3.3, б является частью, но не является подграфом, тогда как граф 3.3, в является для графа 3.3, а как частью, так и подграфом.
Число неориентированных графов с n вершинами
Пусть имеется n вершин, помеченных соответственно: v1, v2,..., vn. Подсчитаем количество различных диаграмм, которые можно построить на этих вершинах. Максимальное количество ребер в графе определяется количеством способов, которыми из n вершин можно
выбрать две: =Сn2. Для каждого ребра существует две возможности: либо его проводят, либо нет. В соответствии с правилом произведения в комбинаторике, количество диаграмм, а
значит, и графов, равно 2.
Число неориентированных графов с n вершинами и m ребрами
Пусть по-прежнему имеется n вершин, помеченных соответственно: v1, v2,..., vn. Графов с m ребрами столько, сколько существует способов из всех =Сn2 ребер выбрать m ребер, т.е Сm.
Способы задания псевдографов. Степени вершин
Граф, по определению представляющий собой пару множеств, можно задать любым
из способов задания множеств. Однако для графа существуют некоторые специфические
способы задания, пригодные и для псевдографов.
1. Матрица инцидентности
Пусть v1,v2,...,vn  вершины псевдографа F; e1,e2,...,em  его рёбра. Отношение инцидентности можно определить матрицей инцидентности Bmn , n столбцов которой соответствуют вершинам псевдографа, а m строк - его рёбрам. Для неориентированного графа: bij
=1, если ребро ei инцидентно вершине vj, в противном случае bij =0.
В матрице инцидентности ориентированного псевдографа, если вершина vj - начало
ребра ei , то bij = 1, если vj - конец ei, то bij =1, если ei - петля, а vj - инцидентная ей вершина,
то bij = (где  - любое число, отличное от 1, 0, 1), в остальных случаях bij =0.
24
В каждой строке матрицы инцидентности для неориентированного или ориентированного псевдографа только два элемента отличны от нуля (или один, если ребро является
петлёй), поэтому такой способ задания графа оказывается недостаточно экономным.
2. Список рёбер
Отношение инцидентности можно задать ещё списком рёбер. Каждая строка этого
списка соответствует одному ребру; в ней записаны номера вершин, инцидентных ему. Для
неориентированного псевдографа порядок вершин в строке произволен, для ориентированного псевдографа сначала указывается начальная вершина, а затем - конечная.
3. Матрица смежности
Матрицей смежности псевдографа является квадратная матрица C nn, столбцам и
строкам которой соответствуют вершины. Для неориентированного псевдографа элемент
матрицы смежности cij равен количеству рёбер, инцидентных i-й и j-й вершинам; для ориентированного псевдографа этот элемент равен количеству рёбер с началом в i-й вершине и
концом в j-й вершине.
Таким образом, матрица смежности неориентированного псевдографа симметрична
(cij=cji) относительно главной диагонали. Для ориентированного псевдографа она будет симметрична только в том случае, если для каждого ребра имеется ребро, соединяющее те же
вершины, но идущее в противоположном направлении.
В силу симметричности матрицы смежности для неориентированного графа все его
рёбра будут определяться верхним правым треугольником вместе с главной диагональю этой
матрицы.
Рассмотрим теперь два графа F и F* c n вершинами , которые различаются только
нумерацией вершин, т.е. являются изоморфными. По определению изоморфных графов (см.
§ 2) существует взаимно однозначное соответствие s между множествами их вершин V и
V*, при котором вершины u и w соединены в одном из графов тогда и только тогда, когда
соответствующие им вершины s(u) и s(w) соединены в другом графе.
Обозначив матрицы смежности этих графов соответственно C и C*, получим
C*S(i)S(j) = Cij,
i = 1, 2,..., n, j = 1, 2,..., n.
Тем самым доказана
Теорема 3.2. Графы изоморфны тогда и только тогда, когда их матрицы смежности
получаются друг из друга одинаковыми перестановками строк и столбцов.
Для неориентированного псевдографа F количество  (v) рёбер, инцидентных вершине vF, называется локальной степенью или просто степенью этой вершины.
Зная матрицу смежности или матрицу инцидентности графа, случаях степень вершины vj можно найти путём суммирования элементов j-го столбца матрицы инцидентности или
m
n
i 1
i 1
матрицы смежности:  (vj)=  bi j  (vj)=  ci j .
При подсчёте степеней вершин по этим формулам каждая петля вносит в степень инцидентной ей вершины вклад 1. Однако при изображении петли на схеме к этой вершине
примыкают два конца петли, т.е. петля вносит в эту степень вклад 2. Учёт вклада петель несколько усложняет формулы:
 *(vj)=
m
n
i 1
k 1
 (bi j (3   bi k )) .
25
n
 bi k =2,
Когда i-е ребро обычное,
и  *(vj)= (vj).
k 1
n
Если речь идёт о петле, то
 bi k =1,
и слагаемое внешней суммы удваивается.
k 1
Соответствующая ф-ла при заданной матрице смежности выглядит следующим образом:
 *(vj)=
n
 ci j  c j j 
i 1
n
cjk
k 1
 cj j .
В зависимости от требований конкретной задачи можно пользоваться как одним, так
и другим способом определения степени вершины.
Рассмотрим сумму степеней всех вершин графа:   * (v ) . Каждое ребро имеет два
v F
конца и, следовательно, вносит вклад 2 в эту сумму; поэтому справедлива следующая лемма.
Лемма 3.1 (о рукопожатиях). Сумма степеней всех вершин графа  чётное число,
равное удвоенному числу рёбер.
Возможная интерпретация этой леммы такова: поскольку в каждом рукопожатии
участвуют две руки, то при любом числе рукопожатий общее число пожатых рук чётно (при
этом каждая рука учитывается столько раз, во скольких рукопожатиях она участвовала).
Следствие. В любом графе число вершин нечётной степени чётно.
Неориентированный граф называется однородным степени k (регулярным), если степени всех его вершин равны между собой и равны k. Если однородный граф степени k
имеет n вершин и m рёбер, то справедливо соотношение
m
kn
1
 * (v ) 
.

2 vF
2
Регулярный граф степени 3 называется кубическим. Из леммы 3.1 следует, что каждый кубический граф имеет четное число вершин.
На рисунке 3.7, а изображен кубический граф с 6 вершинами.
Теорема 3.2. Во всяком неориентированном графе без петель и кратных рёбер с n
вершинами, где n  2, всегда найдутся, по меньшей мере, две вершины с одинаковыми степенями.

Предположим, что существует отвечающий условиям теоремы граф F, все вершины
которого имеют разную степень, т.е. 0, 1, 2, ... , n1. Это означает, что одна из вершин графа
F  изолированная (степени 0), а другая (степени n1) соединена рёбрами со всеми остальными вершинами. 
Для вершин ориентированного графа определяются две
локальные степени:
1(v) - число рёбер с
началом в вершине v (количество выходящих из v рёбер) и
2(v) - количество захоРис. 3.7.
дящих в v рёбер (тех, для которых эта вершина является концом).
Первую из этих степеней легко определить, суммируя элементы i-й строки матрицы
смежности, а вторую  суммируя элементы i-го столбца:
26
n
1(v) =  ci j ;
2(v)=
j 1
n
 ck i .
k 1
Пример. Для графа, изображённого на рис. 3.1, б, степени вершин следующие:
1(3)=3; 1(8)=2; 1(24)=1;
2(3)=1; 2(8)=2; 2(24)=3.
Петля даёт вклад 1 в обе эти степени. Очевидно, что общее количество всех выходящих рёбер равно общему количеству всех входящих рёбер и равно количеству рёбер этого
графа:
m=
  1 (v ) =   2 (v ) .
v F
v F
Ориентированный граф называется однородным степени k, если для каждой его вершины 1(v)=2(v)= k (рис. 3.7, б). Если однородный граф степени k имеет n вершин и m
рёбер, то справедливо соотношение
m    1 (v )    2 (v )  kn .
vG
vG
Пример. На рисунке рис. 3.7, б изображен однородный орграф степени 1.
Отношение связности для вершин неориентированного графа
Пусть F  неориентированный граф.
Маршрутом в F называется такая конечная или бесконечная последовательность рёбер (...,e0,e1,e2,...,en,...), в которой каждые два соседние ребра ei1 и ei имеют общую инцидентную вершину. Одно и то же ребро может встречаться в маршруте несколько раз.
В дальнейшем будут рассматриваться в основном конечные маршруты (e1,e2,...,en). В
таких маршрутах имеются первое ребро e1 и последнее ребро en. Вершина v0, инцидентная e1
и не инцидентная e2, называется началом маршрута. Вершина vn, инцидентная en и не инцидентная en-1, называется концом маршрута. Вершины, инцидентные рёбрам маршрута, кроме начальной и конечной, называются внутренними (промежуточными).
Пусть маршрут М (e1,e2,...,en) имеет начало в v0 и конец в vn . В этом случае его называют соединяющим вершины v0 и vn. Число рёбер маршрута называется его длиной.
Пример. Маршрут (e5,e6,e7,e2,e3,e4,e1,e7) (рис. 3.8) имеет длину 8.
Маршрут называется цепью, если каждое ребро встречается в нём не более 1 раза, и простой цепью, если каждая вершина графа F инцидентна не более чем двум его рёбрам.
Пример. Маршрут (e5,e6,e7,e2,e3,e4)  цепь, а маршрут (e5,e2,e3,e4)  простая цепь.
Если начальная и конечная вершины маршрута совпадают, т.е. v0=vn, то маршрут
называется циклическим. Пример. Маршрут (e4,e1,e5,e6,e7,e1,e4)  циклический.
Циклический маршрут называется циклом, если он является цепью, и простым циклом, если он является простой цепью.
Пример. Маршрут (e5,e6,e7,e2,e3,e4,e1)  цикл, маршрут
(e5,e6,e7)  простой цикл.
Начало цикла обычно не фиксируется, т.е. все маршруты, получающиеся друг из друга циклическим сдвигом, считаются одним и тем же циклом. Любой участок цепи или цикла
сам является цепью.
Рис. 3.8.
27
На множестве вершин V зададим отношение связности RS следующим образом: вершины v’, v’’V находятся в отношении RS (такие вершины называются связанными), если
существует маршрут М с началом v’ и концом v’’. В этом случае существует также маршрут с началом v’’ и концом v’ (для этого рёбра маршрута М должны идти в обратном порядке), откуда следует симметричность отношения связности двух вершин.
Пусть вершина vV инцидентна более чем двум рёбрам маршрута М, связывающего
вершины v’ и v’’, причём ei - первое из этих рёбер, ej - последнее (j > i+1) (рис. 3.9). Тогда из
маршрута М можно “выбросить” участок, начиная с (i+1)-го ребра и кончая (j1)-м. Получится маршрут М’ (e1,e2,...,ei,ej,...,en). Если М’ - не простая цепь, то можно повторить описанную выше процедуру. Наконец, получится простая цепь М*, связывающая вершины v’ и
v’’. Таким образом, вершины, связанные маршрутом, связаны также и простой цепью.
Если вершина vF связана с какой-либо другой вершиной v’, то она связана и сама
с собой. В самом деле, если v и v’ связывает маршрут М(e1,e2,...,en), тогда v и v связывает
маршрут (e1,e2,...,en-1,en ,en-1,...,e2,e1). Обычно считают, что изолированная вершина также
связана сама с собой, а значит, отношение связанности рефлексивно.
Наконец, оно транзитивно. Действительно, если вершина v’ связана с вершиной v’’ маршрутом М’(e1’,e2’,...,en’), а вершина
v’’
с v’’’
 маршрутом
М”(e1”,e2”,...,em”), то вершина v’ связана с
вершиной
v’’’
маршрутом
Рис. 3.9.
М(e1’,e2’,...,en’,e1”,e2”,...,em”).
Из рефлексивности, симметричности, транзитивности вытекает эквивалентность отношения связности.
Граф называется связным, если все его вершины связаны между собой.
Пример. Граф, изображенный на рис. 3.8,  связный.
Компонентой связности графа F называется его связный подграф, не являющийся
собственным подграфом никакого другого связного подграфа графа F.
Пример. Граф, изображенный на рис. 3.3, б, имеет две компоненты связности.
Под операцией удаления вершины из графа понимают удаление вершины вместе с инцидентными ей
ребрами.
Вершина графа, удаление которой увеличивает
число компонент связности, называется разделяющей
(или точкой сочленения); ребро с таким же свойством
называется мостом.
Пример. Граф, изображенный на рис. 3.10, имеРис. 3.10.
ет четыре точки сочленения: v3, v6, v7 и два моста:
(v4, v5) и (v6, v7).
Отношение достижимости для вершин орграфа
Пусть V - множество вершин ориентированного графа F, Е - множество его рёбер.
Каждое ребро eE имеет начало v’V и конец v’’V. Таким образом, заданы два отображения 1 и 2, где v’=1(e)  начало ребра е, v’’ =2(e)  конец ребра е.
Можно дать несколько определений пути в орграфе F.
1. Путь из вершин и рёбер  это последовательность L(v0,e1,v1,e2,...,en,vn ), где
vi1=1(ei), vi=2(ei). Вершина v0 называется началом пути L, вершина vn - концом пути L,
число n рёбер  его длиной. Путь, состоящий из одной вершины, имеет нулевую длину.
28
~
2. Путь из рёбер  это последовательность L (e1,e2,...,en ). Это понятие пути  аналог
понятия маршрута в неориентированном графе.
3. Путь из вершин  это последовательность L (v0,v1,...,vn ). Путь из вершин определён
для графов, не содержащих кратных рёбер.
На практике можно пользоваться тем определением пути, которое окажется удобнее в
данной конкретной задаче.
Путь называется ориентированной цепью (или просто цепью, когда рассматриваются
только орграфы),, если каждое ребро встречается в нём не более 1 раза, и простой ориентированной цепью, если каждая вершина графа F инцидентна не более чем двум его рёбрам.
Пример. Путь (e5,e6,e7,e1,e4,e3) (рис. 3.11)  ор. цепь, а путь (e7,e1,e4,e3) - простая ор.
цепь.
Путь называется ориентированным циклом (или
просто циклом, когда рассматриваются только орграфы), если он состоит более чем из одного элемента и
его начало совпадает с его концом. Как и для неориентированного графа, начало цикла обычно не фиксируется. Цикл называется простым, если каждая принадлежащая ему вершина инцидентна ровно двум его рёбрам.
Пример. Путь (e1,e4,e3,e2,e5,e6,e7)  цикл, путь
(e5,e6,e7)  простой цикл.
В связи с ориентированными цепями справедлива
теорема,
которую доказал Redei при изучении квадРис. 3.11.
ратичных полей.
Теорема 3.3. Пусть F  конечный орграф, в котором каждая пара вершин соединена
ребром. Тогда в F существует простая ориентированная цепь, проходящая через все его вершины.

Доказательство проведем методом МИ. Обозначим количество вершин графа через n.
 n=2: дуга, соединяющая две вершины графа F2, и есть простая ориентированная цепь,
проходящая через все вершины графа.
 Предположим, что при n = m для графа Fm теорема верна.
 Докажем, что при n = m+1 для графа Fm+1 теорема верна.
Построим граф Fm+1, добавив к графу Fm некоторую вершину vm+1, в которой имеются
ребра ко всем вершинам vi (i=1,2,...,m) из Fm. По предположению, существует простая ориентированная цепь, проходящая через все вершины графа Fm: Pm=(v1,v2,...,vm). Для ребер, инцидентных вершине vm+1, имеется три возможности.
1. Существует дуга (vm+1,v1). Добавив ее к цепи Pm “слева”, получим искомую цепь,
проходящую через все вершины графа Fm+1: Pm+1=( vm+1,v1,v2,...,vm).
2. Существует дуга (vm,vm+1). Добавив ее к цепи Pm “справа”, получим искомую цепь,
проходящую через все вершины графа Fm+1: Pm+1=( vm+1,v1,v2,..., vm,vm+1).
3. Если в графе Fm+1 нет ни дуги (vm+1,v1), ни дуги (vm,vm+1), то при некотором k
(k=2,3,...,m-1) в нем обязательно найдутся дуги (vk ,vm+1) и (vm+1,vk +1). Составим цепь
Pm+1=(v1,v2,...,vk ,vm+1,vk +1,...,vm).
Эта цепь проходит через все вершины графа Fm+1.

На множестве вершин V зададим отношение достижимости RD следующим образом:
Вершина v’V находится в отношении RD с вершиной v’’V (в этом случае говорят, что
29
вершина v’’ достижима из вершины v’), если существует путь L(v’,... ,v’’) с началом v’ и
концом v’’.
Аналогично отношению связности для вершин неориентированного графа отношение
достижимости для вершин ориентированного графа рефлексивно и транзитивно, но в отличие от отношения связанности отношение достижимости не обязательно симметрично.
С помощью отношения достижимости определяется разбиение множества вершин орграфа на классы эквивалентности: вершины v’, v’’ принадлежат одному классу, если отношение симметрично, т.е. v’’ достижима из v’, а v’ достижима из v’’.
Пусть L1(v’, ... ,v’’) и L2(v’’, ... ,v’)  соответствующие пути, связывающие эти вершины. Тогда вместе они образуют цикл, проходящий через вершины v’ и v’’. Таким образом,
любые вершины одного и того же класса эквивалентности принадлежат некоторому циклу.
Если циклы в графе отсутствуют, то каждый класс эквивалентности состоит из одной вершины.
Рис. 3.13.
Минимальный граф FB , индуцирующий на множестве
вершин V то же отношение достижимости, что и данный ориентированный граф F, т.е. граф с неуменьшаемым далее множеством рёбер, называется базисным графом для графа F.
Если существует базисный граф, то он не обязательно
единственный. Так, для графа на рис. 3.13, любое радиальное
ребро и ориентированный многоугольный цикл определяют
базисный граф.
Если F - конечный орграф, то базисные графы существуют; они могут быть получены при последовательном удалении “излишних” рёбер (v0,vn), для которых найдётся не содержащая ребра (v0,vn) ориентированная цепь Р(v0,vn).
Обходы в глубину и в ширину
Пусть имеется неор. граф F(V,E) с n вершинами и m ребрами, заданный своими списками смежности. Необходимо проделать заданную операцию P(vi) с каждой вершиной этого
графа.
Метод поиска в глубину (процесс поиска идет в направлении «вглубь», пока это возможно )
Произвольно выбрать и посетить v1. Пусть w  L1. Посетить w и продолжить поиск из
нее.
Пусть находимся в вершине vi, причем попали в нее из вершины vk. Если существует
вершина u  Li, которая еще не посещалась, то посетить эту вершину и продолжить поиск из
нее. В противном случае вернуться в vk.
Множество E разбивается на два непересекающихся множества: Т (пройденных ребер) и В (не пройденных ребер). Элементы Т называются древесными, элементы В - обратными.
В сл. связного графа F(V,Т) - глубинное остовное дерево (иначе был бы цикл, т.е. в
какую-то вершину зашли дважды, что противоречит построению). Вершина v1 считается
корнем дерева.
В сл. несвязного графа - F(V,Т) - глубинный остовный лес.
30
Если поиск в глубину осуществляется на связном графе, то посещается каждая вершина. Иначе отыскивается его связная компонента. Закончив работу с ней, выбирают в качестве новой начальной вершины ту, которая еще не посещалась, и начинают новый поиск.
Т.к. при работе рекурсивных процедур промежуточные результаты помещаются в
стек, то метод поиска в глубину можно реализовать и без рекурсии; при этом организацию и
поддержание стека для хранения промежуточных вершин должен организовать сам программист.
Метод поиска в ширину основывается на замене стека очередью
(здесь движемся во всех возможных направлениях).
Организовать пустую очередь.
Произвольно выбрать и посетить v1. Все вершины w  L1. поместить в очередь.
Пока очередь не пуста
{Забрать первую из очереди - vi.
Если она еще не посещалась, то
{посетить ее; все вершины u  Li добавить в очередь}
}
Здесь, чтобы построить остовное дерево, в очереди следует хранить записи:
первое поле - сама вершина vj; второе поле - номер i списка Li, если в vj пришли из vi.
Задачи, решаемые с помощью обхода графа
1. Количество компонент связности (связный ли?)
2. Дерево или нет? (1 компонента + m=n-1) Лес или нет? (Е=Т)
3. Нахождение остовного дерева (леса), не обязательно минимального
4. Путь между двумя вершинами, не обязательно кратчайший: начать поиск с одной
из вершин и вести его, пока не попадешь в другую.
В сл. поиска в ширину для каждой вершины v хранить back[v] = w, если в v попали из
w.
Изоморфизм
Два графа F(V,E) и F*(V*,E*) изоморфны, если существует взаимно-однозначное соответствие между множествами вершин V и V*, такое, что любые две вершины в графе F
смежные тогда и только тогда, когда смежные соответствующие им вершины в графе F*.
Проблема определения, являются ли два графа изоморфными, неожиданно оказывается трудной. Для произвольных графов все известные алгоритмы, гарантирующие правильный ответ, экспоненциальные.”
Пусть |V|=n. Проставим в графе F нумерацию вершин [1,2,...,n] и составим для него
матрицу смежности С. Затем вершины графа F* пронумеруем в соответствии с некоторой
перестановкой списка [1,2,...,n] и составим его матрицу смежности С*. Если С=С*, то графы
изоморфны, если нет, то снова нумеруем вершины графа F* в соответствии с другой перестановкой списка [1,2,...,n], снова составляем матрицу смежности, и процесс сравнения матриц повторяется.
Понятно, что если графы не изоморфны, то придется проверить все n! перестановок из
n элементов, т.е. сложность этого алгоритма составляет T(n)=O(n!).
Как следствие, “исследователи часто отказываются от поиска эффективного алгоритма изоморфизма и взамен этого строят простые процедуры, от которых ожидается хорошая
работа в большинстве случаев.” Кроме того, разрабатываются алгоритмы полиномиальной
31
сложности, “пригодные для специальных классов графов, появляюшихся в некоторых приложениях.
Инвариантом графа F называется параметр, имеющий одно и то же значение для всех
графов, изоморфных графу F. Среди самых очевидных инвариантов отметим следующие:
1. Число вершин |V|=n.
2. Число ребер |E|=m.
3. Число компонент связности.
4. Последовательность степеней, т.е.список степеней всех вершин в убывающем порядке значений.
Эвристики для решения задач изоморфизма обычно состоят в попытках показать, что
два рассматриваемые графа не изоморфны. Для этого составляется список различных инвариантов в порядке, определяемом сложностью вычисления инварианта. Затем последовательно сравниваются значения параметров графов. Как только обнаруживаются два различных значения одного и того же параметра, приходят к заключению, что данные графы не
изоморфны.
Множество инвариантов, которое позволило бы этой процедуре установить изоморфность графов за полиномиальное время, наз. кодом графа. К сожалению, на сегодняшний
день такое множество не найдено.
По существу, эвристический алгоритм рассматриваемого типа сводится к сравнению
неполных кодов двух графов. Конечно, рассмотрение большого числа инвариантов увеличивает вероятность правильного заключения об изоморфизме при совпадении всех значений
параметров, но в общем случае ничего не гарантирует.
Рассмотрим теперь пример достаточно сложной эвристики, работающей с матрицей
смежности С(F). Сама по себе матрица смежности не является инвариантом”, хотя графы F и
F* изоморфны тогда и только тогда, когда их матрицы смежности получаются друг из друга
одинаковыми перестановками строк и столбцов (эта теорема была доказана в курсе ДМ).
Описываемая ниже полиномиальная процедура достаточно хорошо справляется с задачей отсеивания неизоморфных сетей.
Вычисляется С2(Fi) для i=1,2. Затем переставляются строки и столбцы матриц С2(F1) и
С2(F2) так, чтобы элементы на главной диагонали оказались в нисходящем порядке. Если F1
и F2 изоморфны и все диагональные элементы различны, то при этой перестановке должны
получиться идентичные матрицы. Если нет, то данные два графа не могут быть изоморфными.
Если матрицы идентичны, то можно продолжить проверку с
С (Fi)= С2(Fi)* С2(Fi),
С8(Fi)= С4(Fi)* С4(Fi), ... ,
С2 k(Fi)= Сk(Fi)* Сk(Fi),
для i=1,2. Значение k=2s определяется имеющимся бюджетом машинных ресурсов.
Если все из проверенных матриц совпадают, то весьма правдоподобно, но не обязательно истинно, что Если F1 и F2 изоморфны. Эту процедуру называют СПС (сравнение порядков смежности).
4
Потоки в сетях. Определение максимального потока
Рассмотрим некоторые примеры практических задач.
1. Пусть имеется сеть автомобильных дорог, по которым можно проехать из п. А в п.
В. Дороги могут пересекаться в промежуточных пунктах. Количество автомобилей, которые
могут проехать по каждому отрезку дороги в единицу времени, определяется шириной проезжей части, качеством дорожного покрытия, ограничением скорости движения и т.д. (“про-
32
пускная способность “ дороги). Каково max количество автомобилей, которые могут проехать из п. А в п. В без образования пробок на дорогах?
2. Пусть имеется сеть трубопроводов, соединяющих п. А (например, нефтепромысел)
с п. В (например, нефтеперерабатывающий завод). Трубопроводы могут соединяться и разветвляться в промежуточных пунктах. Количество нефти, которое может быть перекачено по
каждому отрезку трубопровода, определяется диаметром трубы, мощностью нагнетающего
насоса и т.д. (“пропускная способность” или “максимальный расход” трубопровода). Сколько нефти можно перекачать через такую сеть в единицу времени?
3. Пусть имеется система машин для производства готовых изделий из сырья, и последовательность технологических операций может быть различной (т.е. операции могут
выполняться на разном оборудовании или в разной последовательности), но все допустимые
варианты заранее строго определены. Max производительность каждой единицы оборудования известна. Какова max-но возможная производительность всей системы в целом и как
нужно орг-ть производство для достижения max-й производительности?
Необходимость решения этих и подобных им задач привела к разработке теории потоков в сетях. Рассмотрим самую существенную задачу этой теории, а именно: задачу определения максимального потока.
Вершина v орграфа F называется источником, если 2(v) = 0.
Вершина v орграфа F называется стоком, если 1(v) = 0.
Орграф с одним источником и одним стоком называется сетью.
Пусть F(V, E) — сеть, s и t — соответственно источник и сток сети. Каждой дуге сети
приписано неотрицательное вещественное число, с: ER+. Если u и v — вершины, то с(u,v)
называется пропускной способностью дуги (u, v). Если дуга (u, v) в графе отсутствует, то
принято считать, что с(u,v)=0.
Пусть задана функция f: ER. Дивергенцией функции f в вершине u называется число
div(f, u), которое определяется следующим образом:
div (f, u) =
 f (u, v)   .
{v|( u,v )E}
{v|( v ,u)E}
Пример.
div (f, s) =

f (s, v)  0 > 0;
div (f, t) = 0 
{v|( s,v )E}

f (t, v) < 0.
{v|( v ,t )E}
Функция f: ER называется потоком в сети F, если
1. (u, v) E поток через дугу неотрицателен и не превосходит пропускной способности дуги, т.е. выполняется двойное неравенство: 0  f (u, v)  с (u, v);
2. u  V\{s,t} дивергенция потока равна нулю во всех вершинах, кроме источника и
стока, т.е. div (f, u) = 0.
Дуга (u, v) E называется насыщенной, если поток по ней равен ее пропускной способности, т.е. если f (u, v) = с (u, v).
Число (f) = div (f, s) называется величиной потока f.
Разобьем множество вершин V орграфа F(V, E) на два непустных непересекающихся
множества S и T, так, чтобы источник попал в множество S (sS), а сток — в множество T
(tT).
Множество Р дуг, соединяющих элементы множеств S и T, называется (s, t)-разрезом.
Очевидно, что Р  E.
33
Сумму потоков через дуги разреза Р обозначим Н(Р). Сумму пропускных способностей дуг разреза Р (она называется пропускной способностью разреза) обозначим С(Р):
Н(Р) =  f (е),
С(Р) =  с(е).
eP
eP
Очевидно, что множество Р можно разбить на два непересекающихся множества Р+ и
где Р+ — дуги от элементов множества S к элементам множеста T, а Р — дуги от элементов множества T к элементам множеста S.
Пример. В условиях примеров*: 1, 2, 4. Р+ = Р, Р = ; 3. Р+ = {1, 2, 5} , Р = {4}.
Р,

Лемма 1. (f) = Н(Р+)  Н(Р).
Рассмотрим сумму W =  div (f, v). Пусть дуга (u, v) E.
vS
Если u, v  S, то в сумму W попадают два слагаемых для этой дуги: + f(u, v) при вычислении div (f, u) и f(u, v) при вычислении div (f, v), итого 0.
Если uS, vТ, то в W попадает 1 слагаемое: +f(u,v); все такие слагаемые дают Н(Р+).
Если uТ, vS, то в W попадает 1 слагаемое: f(u,v); все такие слагаемые дают Н(Р).
Таким образом, W = Н(Р+)  Н(Р).
С другой стороны, W =  div (f, v) = div (f, s) = (f).

vS
Лемма 2. div (f, s) =  div (f, t).

Выберем S = V\{t}, T = {t}. Для соответствующего разреза Р имеем:
div (f, s) = (f) = Н(Р+)  Н(Р) = Н(Р+) =  f (v, t) =  div (f, t).

v

Лемма 3. (f)  Н(Р)
(f) = Н(Р+)  Н(Р)  Н(Р+)  Н(Р).

Лемма 4. max (f)  min C(Р)
f

P
Так как (f)  Н(Р), то max (f)  min Н(Р).
f
P
По определению, Н(Р)  C(Р), значит, max (f)  min Н(Р)  min C(Р).
f
P

P
Теорема (Форда и Фалкерсона). Максимальный поток в сети равен минимальной
пропускной способности разреза, т.е. существет поток f*, такой что
(f*) = max (f) = min C(Р).
f
P

Пусть f — некоторый максимальный поток. Покажем, что существует разрез Р, такой
что (f) = C(Р). Рассмотрим граф F*, полученный из сети F отменой ориентации ребер. Построим множество вершин S следующим образом:
S=
{ uV |
в F*  путь L из s в u, для всех ребер (ui, ui+1) которого справедливо:
( если (ui, ui+1)  Е, то f(ui, ui+1) < C(ui, ui+1) ) &
( если (ui+1, ui)  Е, то f(ui+1, ui) > 0 )
},
т.е. вдоль направления пути L дуги не насыщены, а дуги против направления пути L имеют
положительный поток. Путь L называется аугментальным.
Так как s — начало пути L, то sS. Следовательно, S .
Выберем T = V\S и покажем, что tT.
34
Предположим противное: пусть tS. Тогда существует аугментальный путь из s в t,
обозначим его R. Для каждого ребра е этого пути подсчитаем велитчину (е) по формулам:
(е) = c(е)  f(е) > 0, если (е) ориентировано вдоль R,
(е) = f(е) > 0, если (е) ориентировано против R.
Выберем в качестве  минимальную из этих величин:  = min (е).
eR
В этом случае можно увеличить величину потока на , изменив поток для всех дуг пути R по формулам
f(е) = f(е) + , если (е) ориентировано вдоль R,
f(е) = f(е)  , если (е) ориентировано против R.
Действительно, в новой ситуации условия потока по-прежнему выполняются:
0  f (е)  с (е);
div(v) = 0.
Таким образом, поток f увеличен на , что противоречит максимальности потока f.
Это доказывает, что tT и, следовательно, Т .
Итак, в S содержится источник, в T — сток; значит множества S и T определяют разрез Р = Р+  Р. В этом разрезе все дуги е+ насыщены (f (е+) = с (е+)), а все дуги е не нагружены (f (е) = 0), иначе S можно было бы расширить.
Окончательно, (f) = Н(Р+)  Н(Р) = C(Р+). Таким образом, Р+ — искомый разрез. 
Алгоритм нахождения максимального потока
Пусть сеть задана матрицей пропускных способностей дуг. Алгоритм использует
идею до-ка теоремы Форда и Фалкерсона, а именно: задавшись начальным приближением
потока, определяем множество вершин S, которые соединены аугментальными путями с источником s. Если оказывается, что tS, то это означает, что поток не максимальный и его
можно увеличить на величину . Для нахождения аугментальных путей и одновременного
подсчета величины  используется вспомогательная структура данных:
P: array [1..p] of record
s: enum (+,) {направление дуги}
p: 1..n
{предшествующая вершина в аугментальном пути}
: real
{величина возможного увеличения потока}
end record
Вход: сеть F(V, E) с источником s и стоком t,
матрица пропускных способностей С: array [1..n, 1..n] of real.
Выход: матрица максимального потока Н: array [1..n, 1..n] of real.
BEGIN
for i:=1 to n do
M:
Н[i, j]:=0;
for j:=1 to n do
{итерация увеличения потока}
for i:=1 to n do
begin
S[i]:=false; N[i]:=false;
P[i]:=(,,)
end
S[s]:=true;
P[s]:=(+, s, );
{первоначально поток = 0}
{S и N — множества, представленные в виде}
{характеристического вектора}
{так как sS}
repeat
35
a:=false;
{признак расширения S}
for vV do
begin
if (S[v])&(not N[v]) then{вершина v в S и не исключена из рассмотрения}
begin
for uL(v) do
БЛОК А: проверяем u на предмет включения в множество S
for uL1(v) do
{ L1(v) = Back(v) }
БЛОК Б: проверяем u на предмет включения в множество S
N[v]:=true
{вершина v уже рассмотрена}
end
end
if S[t] then
БЛОК С: если сток в мн-ве S то улучшаем max поток и уходим на метку М
until (not (a))
END.
Рассмотрим каждый из блоков подробнее.
БЛОК А: Проверка u на предмет включения в множество S
begin
if (not (S[u]))&( H[v, u]< C[v, u]) then
begin
S[u]:=true;
{включаем вершину u в S}
P[u]:=(+, v, min(P[v]., C[v, u]H[v, u]) );
a:=true
end
end
БЛОК Б: Проверка u на предмет включения в множество S
begin
if (not (S[u]))&( H[u, v]>0) then
begin
S[u]:=true;
{включаем вершину u в S}
P[u]:=( , v, min(P[v]., H[u, v]) );
a:=true
end
end
БЛОК С: если сток в множестве S то улучшаем max поток и уходим на метку М
begin
x:=t; := P[t].;
while (x<>s) do
begin
if (P[x].s:=+) then H[P[x].p, x]):=H[P[x].p, x])+
else
H[x, P[x].p]):=H[x, P[x].p])
x:= P[x].p;
end;
goto M
36
end
ОБОСНОВАНИЕ. В качестве первого приближения берется нулевой поток, который
по определению является допустимым. В основном цикле, помеченном меткой М, делается
попытка увеличить поток. Для этого в цикле repeat расширяется, пока это возможно, множество S вершин, достижимых из вершины s по аугментальным путям. Если в множество S попадает сток t, то поток вдоль пути из s в t увеличивается на величину , после чего начинается новая итерация с целью увеличить поток.
Процесс расширения множества S в цикле repeat заканчивается, потому что множество вершин конечно, а отмеченные в массиве N вершины повторно не рассматирваются. Если процесс расширения множества S заканчивается и при этом вершина t не попадает в множество S, то по теореме Форда и Фалкерсона найденный поток Н является максимальным и
работа алгоритма завершается.
ГЛАВА III. NP-ПОЛНЫЕ ЗАДАЧИ
При анализе сложности решения вопрос формального описания задачи приобретает
фундаментальный смысл. Дело в том, что способ записи (кодировки) условия задачи в существенной степени влияет на сложность ее решения.
Пример. «Является ли натуральное число n простым?»
Решение. Делим на простые a, не превышающие n (пусть ab и ab=n  b=n/aa;
2
na ).
I способ задания n: в десятичной сс. Длина l записи составит l = [log10 n]+1, откуда n = 10l1.
Сложность алгоритма  O( n ) = O(10(l1)/2)  показательная.
II способ задания n: в мультипликативной форме записи: n = p11 p22... pkk, где pi  простые.
Если p2 = p3 = ... = pk = 1 = 1, то n  простое. Сложность алгоритма  O(1).
Класс P включает в себя задачи, время решения которых ограничено полиномом от
длины записи условия.
Пример. Внутренние сортировки: от O(n) до O(n2), где n  количество элементов сортируемого массива.
Американский математик С. Кук выделил широкий класс задач (класс NP), для решения которых в настоящее время не построены алгоритмы полиномиальной сложности, но
которые могут быть решены путем просмотра значительного числа различных вариантов.
Примеры. 1) Задача о распознавании простоты натурального числа. 2) Задача о раскраске n  вершинного графа в k цветов (всего способов раскраски k n; если вершины каждого ребра имеют разный цвет, то раскраска правильная; вопрос задачи: при данных n и k
сколько способов раскрасить правильно?)
Теория С. Кука дает реальный инструмент для оценки относительной сложности задач из класса NP. Подробнее.
Сводимость. Пусть требуется создать программу П1 для решения задачи А. Пусть
уже существует программа П2 для решения задачи В. Разрешается включить П2 в П1 в качестве подпрограммы, причем к этой подпрограмме можно обратиться только один раз. Считая, что П2 выполняется за единицу времени, определим время выполнения П1. Если П1 выполняется за полиномиальное время, то задача А полиномиально преобразуется в задачу В.
Оказалось, что многие задачи выбора, эффективное решение которых пока не найдено, полиномиально преобразуются друг в друга.
37
С. Кук доказал, что все задачи из класса NP полиномиально преобразуются в одну
конкретную задачу  задачу о выполнимости.
Формулировка задачи о выполнимости. Булева функция задана в виде КНФ:
s
f(x1,..., xn) = & Di, где Di = xi  1  xi  2  ...  xi  r  элементарная дизъюнкция.
1
2
r
i 1
Существует ли набор (a1,..., an) значений переменных (x1,..., xn), обращающих функцию f в 1?
Эта задача и является той самой «универсальной задачей», к которой можно свести
любую задачу из класса NP.
Полиномиальная эквивалентность двух задач Z1 и Z2 из класса NP определяется как
двусторонняя полиномиальная сводимость: Z1 к Z2 и Z2 к Z1.
Любая задача класса NP, полиномиально эквивалентная проблеме выполнимости,
называется NP-полной.
Для доказательства NP-полноты произвольной задачи S из класса NP достаточно показать, что к ней полиномиально сводится проблема выполнимости или любая другая задача,
NP-полнота которой уже установлена.
Примеры.
1. Задача о разрешимости в числах (0, 1) системы линейных уравнений.
Сведем проблему выполнимости к этой задаче на частном примере. Пусть БФ имеет вид:
f( x1, x2, x3, x4) = x1 ( x1 x2  x3) ( x2   x3) (x2  x4) x4.
Условие выполнимости ~ разрешению системы:
x1 = 1;  x1 x2  x3 = 1; x2 x3 = 1; x2x4 = 1; x4 = 1.
[решения: (1, 1, 0, 1) и (1, 1, 1, 1)]
Замена:  x = 1  x: x1 = 1; (1  x1)  x2  x3 = 1; x2 (1x3) = 1; x2(1x4) = 1; x4 = 1.
Замена: xi  xj = xi + xj  yk, где yk  {0, 1}
x1 = 1; (1  x1) + x2 + x3  y1  y2 = 1; x2 + (1x3)  y3 = 1; x2 + (1x4)  y4 = 1; x4 = 1.
Наконец, x1 = 1;  x1 + x2 + x3  y1  y2 = 0; x2  x3  y3 = 0; x2 x4  y4 = 0; x4 = 1.
2. Задача о клике
Кликой графа F называется максимальное по мощности множество вершин этого графа, любые две из которых являются смежными.
Пример. Граф, изображенный на рисунке, имеет клику мощности 4.
Формулировка: существует ли в F клика из m вершин?
Сведем проблему выполнимости к этой задаче на частном примере. Пусть
БФ имеет вид:
f( x1, x2, x3) = x1 (x1 x2  x3) (x2  x3).
Разных решений три: (1, 0, 0), (1, 0, 1), (1, 1, 1).
I
II III
Решение
Переменной xr, входящей в i-ю скобку и
x1
x1 x2
x1=1; x2=0; x3  любое
занимающей
там j-е место, сопоставляется пара
x1
x1
x3
x1=1; x3=1; x2  любое
(i , j). Каждая вершина графа имеет двойное
x1
x2 x2

обозначение:
x1
x2
x3
x1 = x2 = x3 = 1
xr (i , j).
x1 x3 x2
x1=1; x2=0; x3 = 0
 Не соединяем ребром вершины (i , j) и (i , k)
x1 x3 x3

(переменные из одной скобки).
 Не соединяем ребром вершины xr и xr (не могут быть равны единице одновременно).
 В остальных случаях вершины соединяются ребром.
Задачу о выполнимости можно сформулировать
следующим образом: существует ли в графе F клика мощности 3? В нашем примере таких клик 4  по числу решений в таблице.
38
Другими примерами NP-полных задач является задача коммивояжера и задача нахождения в графе гамильтонова цикла.
Существуют задачи класса NP, для которых не доказана их NP-полнота. Например,
задача о простоте натурального числа и задача распознавания изоморфизма графов.
Если будет найден полиномиальный алгоритм решения некоторой NP-полной задачи,
то это будет означать, что все NP-полные задачи могут быть решены за полиномиальное
время.
Вопрос о справедливости равенства P=NP  один из главных в современной математике.
В настоящее время доказательство NP-полноты той или иной задачи является аргументом в пользу отказа от поиска полиномиального алгоритма ее решения и переключения
внимания исследователя на приближенные методы или варианты переборных алгоритмов.
РАЗДЕЛ 4. Словарь терминов (глоссарий)
Исчерпывающий поиск
Алгоритмы с возвратом
Динамическое программирование
Жадные алгоритмы
Задача
коммивояжера
о велосипедном замке
о паросочетаниях
о порядке перемножения матриц
о рюкзаке (об оптимальной выборке)
о стабильных браках
о ферзях
об обходе конём шахматной доски
об оптимальной выборке (о рюкзаке)
Композиции
Метод ветвей и границ
Оптимальное дерево
Перестановки
Перестановки с повторениями
Разбиения
Размещения
Размещения с повторениями
Сочетания
Сочетания с повторениями
Алгоритмы на графах
Алгоритм
Дейкстры
Крускала
Прима
Уоршалла и Флойда
39
Форда-Беллмана
Гамильтонов цикл
Граф
гамильтонов
неориентированный
ориентированный
полный
Матрица
инцидентности
смежности
Мультиграф
Обход графа
в глубину
в ширину
Остовное дерево
Поток
максимальный
полный
Псевдограф
эйлеров
Списки смежности
Список рёбер
Эйлеров цикл
NP-полные задачи
Задача
о выполнимости
о клике
NP-полная
NP-трудная
Полиномиальная сводимость задач
Полиномиальная эквивалентность задач
РАЗДЕЛ 5. Практикум по решению задач (практических ситуаций) по темам лекций (одна из составляющих частей итоговой государственной аттестации)
Исчерпывающий поиск
Задание 1.1. Разработать и реализовать процедуру генерации размещений с повторениями.
Решение.
void RazmRepeat(int k)
{int i,j;
for (i=1; i<=n; i++)
{
a[k]=i;
if (k<m)
40
{RazmRepeat(k+1);}
else
{count++;
fprintf(f,"N %d\t",count);
for (j=1; j<=m; j++)
{fprintf(f,"%d ",a[j]);};
fprintf(f,";\n");
};
};
}
Задание 1.2. Разработать и реализовать процедуру генерации сочетаний.
Решение.
void Sochet(int k, int x_k_1)
{int i, j, x_k_1_new;
for (i=x_k_1+1; i<=n; i++)
{
a[k]=i;
x_k_1_new=i;
if (k<m)
{Sochet(k+1,x_k_1_new);}
else
{count++;
fprintf (f,"*** N %d: ",count);
for (j=1; j<=m; j++)
{fprintf(f,"%d ",a[j]);}
fprintf(f,"\n");
};
};
}
Задание 1.3. Разработать и реализовать процедуру генерации разбиений.
Решение.
void Razbien(int k, int x_k_1, int sum)
{int i, j, x_k_1_new, sum_new;
for (i=x_k_1; i<=m-sum; i++)
{
a[k]=i;
x_k_1_new=i;
sum_new=sum+a[k];
if (m-sum_new>0)
{Razbien(k+1,x_k_1_new,sum_new);}
else
{count++;
fprintf (f,"*** N %d: ",count);
for (j=1; j<=k; j++)
{fprintf(f,"%d ",a[j]);}
fprintf(f,"\n");
};
};
41
}
Задание 1.4. Разработать и реализовать процедуру обхода конём шахматной доски.
Решение.
Объявим следующие глобальные переменные:
#define TRUE 1
#define FALSE 0
#define MAX_SIZE 11
int dx[]={2,1,-1,-2,-2,-1,1,2},
dy[]={1,2,2,1,-1,-2,-2,-1},
n,n2, count, sol_1;
int h[MAX_SIZE][MAX_SIZE];
Тогда искомая процедура выглядит следующим образом:
void Horse(int k, int x, int y)
{
int i,u,v,l1,l2;
if (sol_1==TRUE)
for (i=0; i<8; i++)
{
u=x+dx[i];
v=y+dy[i];
if ( 1<=u && u<=n && 1<=v && v<=n && h[u][v]==0 )
{ h[u][v]=k;
if (k<n2)
{Horse(k+1,u,v);}
else
{count++;
cout << " Solution N " << count << "\n";
for (l1=1; l1<=n; l1++)
{for (l2=1; l2<=n; l2++)
{
if (h[l1][l2]<10)
{cout << " " << h[l1][l2] << " ";}
else
{cout << h[l1][l2] << " ";}
}
cout << "\n";
};
sol_1=FALSE;
};
h[u][v]=0;
}
}
}
Задачи для самостоятельного решения
Задание 1.5. Разработать и реализовать процедуру генерации сочетаний с повторениями.
Задание 1.6. Разработать и реализовать процедуру генерации композиций.
42
Алгоритмы на графах
Задание 2.1. Найти кратчайшие пути в графе, используя алгоритм Дейкстры.
Будем изображать временные метки внутри каждого узла, а когда метка превращается
в постоянную, будем помечать число звездочкой. Когда дуга применяется в некотором кратчайшем пути, будем изображать ее жирной линией.
Шаг 0. Все узлы получают временные метки, равные d 0i , а узел V0 - постоянную метку 0.
Шаг 1. Среди всех временных меток минимальное значение 2 имеет метка узла V3 , поэтому
V3 получает постоянную метку.
Шаг 2. Узел V3 имеет соседей V2 и V5 .
l2  min{l2 , l3  d32}  min{5, 2  1}  3 .
l5  min{l5 , l3  d35}  min{, 2  11}  13 .
Шаг 1. Среди всех временных меток наименьшую метку 3 имеет узел V2 . Поэтому V2 получает постоянную метку.
Шаг 2. Соседями узла V2 являются V1 , V7 . (Узел V3 тоже соседний, но он стал постоянным и
поэтому исключается.)
l1  min{l1, l2  d21}  min{4,3  3}  4 .
l7  min{l7 , l2  d27 }  min{,3  13}  16 .
Шаг 1. Узел V1 получает постоянную метку 4.
Шаг 2. l4  min{l4 , l1  d14}  min{12, 4  1}  5 .
Шаг 1. V4 получает постоянную метку.
Шаг 2. l6  min{l6 , l4  d46}  min{,5  6}  11 .
l7  min{l7 , l4  d47 }  min{16,5  9}  14 .
Шаг 1. V6 получает постоянную метку.
Шаг 2. l7  min{l7 , l6  d67 }  min{14,11  7}  14 .
Шаг 1. V5 получает постоянную метку.
Шаг 2. l7  min{l7 , l5  d57 }  min{14,13  8}  14 .
Шаг 1. V7 получает постоянную метку.
Задание 2.2. Используя процедуру СПС (сравнение порядков смежности), доказать,
что графы не изоморфные.
43
Решение.
 0 1 1 0 1


 1 0 1 0 0
C(F1)=  1 1 0 1 0  ;


 0 0 1 0 1


 1 0 0 1 0
 0 1 0 1 1


 1 0 1 0 0
C(F2)=  0 1 0 1 1  ;


 1 0 1 0 0


 1 0 1 0 0
311 2 0 


1 2 1 1 1 
C2(F1)  1 1 3 0 2  ;


 2 1 0 2 0


 0 1 2 0 2
3 0 3 0 0


 0 2 0 2 2
C2(F2)=  3 0 3 0 0  .


 0 2 0 2 2


 0 2 0 2 2
Элементы на главных диагоналях матриц C2(F1) и C2(F2) будут расположены в нисходящем порядке, если поменять местами элементы с22=2 и с33=3. Для этого в обеих матрицах
необходимо поменять местами вторую и третью строку, а также второй и третий столбец:
311 2 0 
3 3 0 0 0




1 3 1 0 2 
3 3 0 0 0
Переупорядоченная C2(F1)=  1 1 2 1 1  ; Переупорядоченная C2(F2)=  0 0 2 2 2 .




 2 0 1 2 0
 0 0 2 2 2




 0 2 1 0 2
 0 0 2 2 2
Диагонали переупорядоченных
C (F1) и C2(F2) в квадрат:
 15

 8
4
15
C (F1)= 

9



матриц совпали; поэтому снова возведем матрицы
2



;



9
 18



 12

4

.
18
C (F2)=


12 



12

Даже не производя переупорядочение, легко видеть, что диагонали матриц C 4(F1) и
C4(F2) содержат разные элементы. На этом основании можно сделать вывод, что графы F1 и
F2 не являются изоморфными.
Задачи для самостоятельного решения
Задание 2.3. Найти минимальное остовное дерево, используя алгоритм
1) Крускала, 2) Прима.
44
Задание 2.4. Найти кратчайшие пути от вершины-источника s до всех остальных вершин как методом Форда-Беллмана, так и методом Дейкстры.
NP-полные задачи
Задание 3.1. Свести проблему выполнимости для функции
f( x1, x2, x3, x4) = x1 ( x1 x2  x3) ( x2   x3) (x2  x4) x4.
к задаче о разрешимости в числах (0, 1) системы линейных уравнений.
Решение. Условие выполнимости эквивалентно разрешению системы:
x1 = 1;  x1 x2  x3 = 1; x2 x3 = 1; x2x4 = 1; x4 = 1.
[решения: (1, 1, 0, 1) и (1, 1, 1, 1)]
Замена:  x = 1  x: x1 = 1; (1  x1)  x2  x3 = 1; x2 (1x3) = 1; x2(1x4) = 1; x4 = 1.
Замена: xi  xj = xi + xj  yk, где yk  {0, 1}
x1 = 1; (1  x1) + x2 + x3  y1  y2 = 1; x2 + (1x3)  y3 = 1; x2 + (1x4)  y4 = 1; x4 = 1.
Наконец, x1 = 1;  x1 + x2 + x3  y1  y2 = 0; x2  x3  y3 = 0; x2 x4  y4 = 0; x4 = 1.
Задание 3.2. Свести проблему выполнимости для функции
f( x1, x2, x3) = x1 (x1 x2  x3) (x2  x3)
к задаче о клике.
Решение. Разных решений три: (1, 0, 0), (1, 0, 1), (1, 1, 1).
I
x1
x1
x1
x1
x1
x1
II
x1
x1
x2
x2
x3
x3
III
x2
x3
x2
x3
x2
x3
Решение
x1=1; x2=0; x3  любое
x1=1; x3=1; x2  любое

x1 = x2 = x3 = 1
x1=1; x2=0; x3 = 0

Переменной xr, входящей в i-ю скобку и
занимающей там j-е место, сопоставляется пара
(i , j). Каждая вершина графа имеет двойное
обозначение:
xr (i , j).
 Не соединяем ребром вершины (i , j) и (i , k)
(переменные из одной скобки).
 Не соединяем ребром вершины xr и xr (не
могут быть равны единице одновременно).
 В остальных случаях вершины соединяются ребром.
45
Задачу о выполнимости можно сформулировать
следующим образом: существует ли в графе F клика мощности 3? В нашем примере таких клик 4  по числу решений в таблице.
Задачи для самостоятельного решения
Задание 3.3. Свести проблему выполнимости для функции
f( x1, x2, x3) = x1 (x1 x2  x3) (x2  x3)
к задаче о разрешимости в числах (0, 1) системы линейных уравнений.
Задание 3.4. Свести проблему выполнимости для функции
f( x1, x2, x3, x4) = x1 ( x1 x2  x3) ( x2   x3) (x2  x4) x4.
к задаче о клике.
Раздел 6. Изменения в рабочей программе, которые произошли после утверждения программы.
Характер изменений в
программе
Номер и дата протокола заседания кафедры, на котором
было принято данное решение
Подпись заведующего
кафедрой, утверждающего внесенное изменение
Подпись декана факультета (проректора по
учебной работе), утверждающего данное изменение
Раздел 7. Учебные занятия по дисциплине ведут:
Ф.И.О., ученое звание и степень преподавателя
кандидат тех. наук,
доцент Ланина Н.Р.
кандидат тех. наук,
доцент Ланина Н.Р.
кандидат тех. наук,
доцент Ланина Н.Р.
кандидат тех. наук,
доцент Ланина Н.Р.
Учебный
год
Факультет
Специальность
2007-2008
ПМПЭ
2010-2011
ФМОИП
2011-2012
ФМОИП
2012-2013
ФМОИП
010200 Прикладная математика и информатика
Прикладная математика и информатика
Прикладная математика и информатика
Прикладная математика и информатика
46
47
Download