Здравствуйте прошла курсы на тему Алгоритмы С++. Но не пришел сертификат и не доступен.Где и как можно его скаачат? |
Виды графов и их свойства
Задачи обработки графов
Имея в своем распоряжении инструменты, разработанные в данной главе, мы рассмотрим в лекциях 18—22 самые разнообразные алгоритмы решения задач обработки графов. Эти алгоритмы являются фундаментальными и могут оказаться полезными во многих ситуациях, хотя для нас они будут лишь введением в тему алгоритмов на графах. Разработано множество интересных и полезных алгоритмов, которые выходят за рамки данной книги, и известно множество интереснейших задач, для решения которых хорошие алгоритмы еще не найдены.
Как и в любой другой области, первый вопрос при решении новой задачи обработки графов -это определение трудности ее решения. В области обработки графов этот вопрос может оказаться намного более тяжелым, чем можно себе представить, даже для с виду простых задач. Более того, наша интуиция часто оказывается бессильной и не помогает отличить легкие задачи от трудных или от не решенных на данный момент. В этом разделе мы кратко опишем классические задачи и что о них известно.
С какими трудностями приходится сталкиваться при разработке реализации для решения новой задачи обработки графов? Печальная правда состоит в том, что не существует универсального ответа на этот вопрос для любой задачи, с которой мы можем столкнуться. Однако можно дать общее описание сложности решения различных классических задач обработки графов. В этом смысле мы грубо разобьем эти задачи по сложности их решения:
- Легкие
- Разрешимые
- Трудноразрешимые
- Решение неизвестно.
Такая классификация позволяет примерно сравнивать задачи между собой и с текущим уровнем знаний в области алгоритмов на графах.
Как показывает эта терминология, основная причина такого разбиения задач заключается в том, что существует множество задач на графах, подобных задаче поиска гамильтонова цикла, для которых никто не знает эффективного решения. Позже (в части VIII) мы узнаем, как наполнить это заявление точным техническим смыслом; а на данном этапе мы, по меньшей мере, будем предупреждены о серьезных трудностях при написании программ решения этих задач.
Подробное рассмотрение многих задач обработки графов будет выполнено в последующих разделах данной книги. Здесь мы ограничимся краткими описаниями, чтобы просто классифицировать задачи обработки графов по трудности их решения.
Легкая задача обработки графа -это задача, которую можно решить с помощью компактных, элегантных и эффективных программ, к виду которых мы уже успели привыкнуть в частях I—IV Время выполнения таких программ зачастую линейно в худшем случае или ограничено полиномами низких степеней от количества вершин и/или ребер. Обычно, как мы делали в других областях, можно установить, что проблема относится к категории легких, если можно разработать примитивное решение, которое, будучи слишком медленным для крупных графов, вполне приемлемо для графов небольших, а иногда и средних размеров. Затем, зная, что задача имеет легкое решение, мы ищем эффективные решения, которыми можно воспользоваться на практике, и пытаемся выбрать наилучшее из них. Ярким примером легких задач может служить задача поиска эйлерова цикла, рассмотренная в разделе 17.7, а в лекциях 18—22 мы познакомимся с множеством других таких задач. Ниже приведены наиболее яркие примеры таких задач.
- Простая связность. Является ли заданный граф связным? Иначе говоря, существует ли путь, соединяющий каждую пару его вершин? Существует ли цикл в графе, или он представляет собой лес? Принадлежат ли какому-либо циклу две заданные вершины? Впервые мы столкнулись с такими основными вопросами, касающимися обработки графов, в "Введение" , и мы рассмотрим многочисленные решения подобных задач в "Поиск на графе" . Некоторые из них легко решаются за линейное время; но для линейного решения других необходимы изощренные алгоритмы, которые требуют серьезного изучения.
- Сильная связность в орграфах. Существует ли ориентированный путь, соединяющий каждую пару вершин орграфа? Соединены ли две заданные вершины графа ориентированными путями в обоих направлениях (принадлежат ли они какому-либо направленному циклу)? Реализация эффективного решения этих задач намного сложнее, чем соответствующая задача простой связности в неориентированных графах, их изучению посвящена значительная часть "Орграфы и DAG-графы" . Несмотря на все хитрые приемы, применяемые для их решения, мы относим эти проблемы к легким, т.к. мы можем написать компактную, эффективную и полезную реализацию.
- Транзитивное замыкание. Какое множество вершин достижимо при следовании по направленным ребрам из каждой вершины орграфа? Эта задача имеет прямое отношение к задаче сильной связности и другим фундаментальным вычислительным задачам. В "Орграфы и DAG-графы" будут приведены классические решения, которые сводятся лишь к нескольким строкам кода.
- Минимальное остовное дерево. Во взвешенном графе необходимо найти множество ребер с минимальным весом, которые соединяет все вершины. Это одна из старейших и хорошо изученных задач обработки графов; "Минимальные остовные деревья" целиком посвящена изучению различных классических алгоритмов ее решения. Однако исследователи продолжают поиски более быстродействующих алгоритмов решения этой задачи.
- Кратчайшие пути с одним началом. Каковы кратчайшие пути, соединяющий заданную вершину с каждой другой вершиной во взвешенном орграфе (сети)? Вся "Кратчайшие пути" посвящена этой задаче, которая исключительно важна для многочисленных приложений. Эта задача не относится к легким, если веса могут принимать отрицательные значения.
Разрешимая (tractable) задача обработки графов -это задача, для которой известен алгоритм решения, а его требования к времени и памяти ограничены полиномиальной функцией от размера графа ( V+E). Все легкие задачи разрешимы, однако мы проводим различия между ними, поскольку для многих разрешимых задач разработка эффективных и практичных программ их решения представляет собой исключительно трудную, если не невозможную, проблему. Такие решения могут оказаться слишком сложным, чтобы приводить их в данной книге, поскольку их реализации могут содержать сотни и даже тысячи строк кода. Ниже приведены два примера наиболее важных задач этого класса.
- Планарность. Можно ли начертить заданный граф так, чтобы никакие линии, представляющие ребра, не пересекались? Поскольку вершины можно помещать в любое место, эта задача разрешима для многих графов, но она все-таки неразрешима для многих других графов. Замечательный классический результат, известный как теорема Куратовского, позволяет легко проверить, является ли граф планарным (плоским). Эта теорема утверждает: единственный вид графов, который невозможно изобразить на чертеже без пересечения ребер -это графы, содержащие некоторый подграф, который после удаления из него вершин степени 2, становится изоморфным одному из графов, изображенных на рис. 17.24. Примитивная реализация этой проверки, даже без учета вершин степени 2, работает на крупных графах недопустимо медленно (см. упражнение 17.110). Однако в 1974 г. Тарьяну (R. Tarjan) удалось разработать хитроумный (хотя и запутанный) алгоритм для решения этой задачи за линейное время с помощью схемы поиска в глубину, которая является расширением схем, рассматриваемых в "Поиск на графе" . Алгоритм Тарьяна не обязательно позволяет получить реальную компоновку, он просто утверждает, что такой чертеж существует. Как было сказано в разделе 17.1, построение наглядного чертежа графа для приложений, в котором вершины графа не обязательно соответствуют реальным объектам внешнего мира, является сложной исследовательской задачей. Ни один из изображенных здесь графов нельзя начертить на плоскости без пересечения его ребер; это невозможно и для всех графов, которые содержат любой из этих графов в качестве подграфа (после того удаления вершин степени 2). Однако для всех остальных графов подобное изображение возможно.
- Сопоставление. Каким является наибольшее подмножество ребер графа, в котором никакие два ребра не связаны с одной и той же вершиной? Известно, что эта классическая задача имеет решение, при этом она решается за время, пропорциональное полиномиальной функции от V и E, однако исследователям никак не удается найти быстродействующий алгоритм для работы с крупными графами. Эту задачу проще решить при наличии различных ограничений. Например, задача распределения студентов по свободным позициям в различных общественных организациях есть задача двудольного сопоставления (bipartite matching): имеются два различных вида вершин (студенты и организации), и нас интересуют только те ребра, которые соединяют вершину одного вида с вершиной другого вида. Решение этой задачи приведено в "Потоки в сетях"
Решения некоторых разрешимых задач никогда не были записаны в виде программ, либо время их выполнения настолько велико, что делает невозможным их практическое применение. Приведенный ниже пример принадлежит к классу таких задач. Он также демонстрирует непредсказуемый характер математической реальности обработки графов.
- Четные циклы в орграфах. Имеется ли в заданном орграфе цикл четной длины? На первый взгляд кажется, что на этот вопрос нетрудно ответить, поскольку нетрудно ответить на аналогичный вопрос для неориентированных графов (см. "Поиск на графе" ), а также на вопрос, имеется ли в орграфе цикл нечетной длины. Однако в течение многих лет эта задача не понята даже настолько, чтобы просто ответить, существует ли алгоритм ее решения (см. раздел ссылок). В 1999 г. была доказана теорема, утверждающая существование эффективного алгоритма, однако метод оказался настолько сложным, что ни один математик или программист не возьмется за его реализацию.
Одной из основных тем, рассматриваемых в "Потоки в сетях" , является то, что многие разрешимые задачи на графах лучше всего решаются алгоритмами, ориентированными на целый класс таких задач в общей постановке. Алгоритмы поиска кратчайшего пути ( "Кратчайшие пути" ), алгоритмы определения сетевых потоков ( "Потоки в сетях" ), а также мощный сетевой симплексный алгоритм ( "Потоки в сетях" ) способны решать многие задачи на графах, которые иначе представляют собой трудно преодолимые проблемы. Ниже приведены примеры таких задач.
- Распределение. Эта задача известна еще как задача двудольного взвешенного сопоставления (bipartite weighed matching): нужно найти в двудольном графе совершенное сопоставление с минимальным весом. Она легко решается с помощью алгоритмов потоков в сетях. Известны специальные методы, которые решают данную задачу непосредственно, но по сути они эквивалентны определению сетевых потоков.
- Общая связность. Какое минимальное количество ребер нужно удалить из графа, чтобы он распался на две несвязные части (реберная связность)? Каково минимальное количество вершин, удаление которых разобьет граф на две несвязных части? Как мы узнаем в "Потоки в сетях" , эти две задачи трудно решить непосредственно, но они решаются алгоритмами определения сетевых потоков.
- Задача почтальона. На заданном графе необходимо найти цикл с минимальным количеством ребер, в котором каждое ребро графа содержится минимум один раз (ребра можно использовать многократно). Эта задача намного сложнее, чем задача поиска эйлерова пути, но намного легче задачи поиска гамильтонова пути.
Переход от проверки, что задача разрешима, до получения готовой программы, позволяющей решать эту задач на практике, может оказаться весьма продолжительным. С одной стороны, при доказательстве, что задача допускает реализацию, исследователи стараются отмести многочисленные детали, с которыми приходится иметь дело при разработке реализации; с другой стороны, они должны учитывать различные возможные ситуации, которые на практике могут и не возникнуть. Этот разрыв между теорией и практикой особенно остро ощущается при разработке алгоритмов на графах, поскольку математические исследования основаны на глубоких результатах, описывающих огромное разнообразие структурных свойств, которые необходимо учитывать при обработке графов, а связь между этими теоретическими результатами и свойствами реальных графов слабо изучена. Разработка общих схем, таких как, например, сетевой симплексный алгоритм, представляет собой исключительно эффективный подход к решению подобных задач.
Трудноразрешимая (intractable) задача обработки графов -это задача, для которой не известен алгоритм, гарантирующий ее решение за приемлемый промежуток времени. Для многих таких задач характерно то, что для ее решения можно использовать примитивный метод, когда мы пытаемся вычислить решение, перебирая все варианты, а трудноразрешимыми они считаются потому, что таких вариантов слишком много. Этот очень широкий класс задач включает в себя многие важные задачи, решение которых хотелось бы знать. Для описания задач этого класса применяется термин NP-трудный (NP-hard). Многие специалисты уверены, что эффективных алгоритмов решения этих задач не существует. В части VIII мы более подробно рассмотрим, что послужило причиной для такой уверенности и этого термина. Хрестоматийным примером NP-трудной задачи обработки графов является задача поиска гамильтонова цикла, рассмотренная в разделе 17.7, а также задачи из приведенного ниже списка.
- Самый длинный путь. Какой путь, соединяющий две заданных вершины графа, является самым длинным? Несмотря на сходство этой задачи с задачей поиска кратчайшего пути, она представляет собой вариант задачи поиска гамильтонова цикла, и поэтому NP-трудна.
- Задача раскраски. Существует ли такой способ закрашивания каждой вершины графа одним из к цветов, чтобы ни одно ребро не соединяло две вершины одинакового цвета? Эта классическая задача легко решается для к = 2 (см. "Поиск на графе" ), но является NP-трудной при к = 3.
- Множество независимых вершин. Каков размер наибольшего подмножества вершин графа, никакие две из которых не соединены ребром? Как и в случае задач нахождения эйлерова и гамильтонова путей, эта задача является NP-трудной, несмотря на внешнее сходство с задачей сопоставления, которая решается за полиномиальное время.
- Клика. Каков размер максимальной клики (полного подграфа) в заданном графе? Эта задача обобщает часть задачи планарности, т.к. если наибольшая клика состоит из более четырех узлов, то граф не может быть планарным.
Эти задачи сформулированы как задачи существования -нужно определить, существует или не существует подграф конкретного типа. В некоторых задачах требуется определить размер наибольшего подграфа конкретного типа, а это можно сделать, сведя задачу существования к проверке существования подграфа размера к с нужным свойством с последующим бинарным поиском наибольшего из них. Однако на практике часто бывает нужно отыскать полное решение, которое в общем случае найти гораздо труднее. Например, известная теорема четырех красок (four color theorem) утверждает, что можно воспользоваться четырьмя цветами для раскраски всех вершин планарного графа таким образом, что ни одно ребро не будет соединять две вершины одного и того же цвета. Однако эта теорема ничего не говорит о том, как это сделать для конкретного плоского графа: знание о том, что такая раскраска существует, ничем не может помочь в поиске полного решения задачи. Другой известный пример -задача коммивояжера (traveling salesperson problem), в которой требуется определить путь обхода вершин взвешенного графа минимальной длины. Эта задача относится к тому же классу задач, что и задача поиска гамильтонова цикла, и нисколько не легче ее: если мы не можем найти эффективное решение задачи поиска гамильтонова пути, то не можем рассчитывать и на то, что найдем решение задачи коммивояжера. Как правило, сталкиваясь с трудными задачами, мы работаем с простейшими вариантами, которые в состоянии решить. Задачи существования в принципе соответствуют этому правилу, но, как мы увидим в части VIII, они играют важную роль в теории.
Перечисленные выше задачи -лишь небольшая часть из тысяч известных NP-трудных задач. Как мы увидим в части VIII, они возникают во всех видах вычислительных приложений. Особенно много таких задач возникает при обработке графов, так что мы будем учитывать их существование на протяжении всей книги.
Обратите внимание: мы настаиваем, чтобы наши алгоритмы гарантировали эффективное решение в худшем случае. Возможно, следовало бы ориентироваться на алгоритмы, которые эффективно работают для типичных входных данных (не обязательно для худшего случая). Аналогично, многие задачи требуют оптимального решения. Возможно, вместо этого достаточно найти просто длинный путь (не обязательно самый длинный) или большую клику (но не обязательно максимальную). В задачах обработки графов зачастую легко найти хороший ответ для реальных графов, и вряд ли нас заинтересует алгоритм, который может найти оптимальное решение на каком-то выдуманном графе, с которым никогда не доведется иметь дела. Вообще-то для трудноразрешимых задач можно применить примитивные или универсальные алгоритмы, подобные программе 17.17, которые, несмотря на экспоненциальное время выполнения в худшем случае, позволяют быстро найти решение (или приемлемое приближение) для многих конкретных примеров реальных задач. Можно отказаться от использования программы, которая иногда может дать неверные результаты или аварийно завершиться, но можно и воспользоваться программами с экспоненциальным временем выполнения для некоторых входных данных. Мы рассмотрим эту ситуацию в части VIII.
Результаты многочисленных исследований показывают, что многие трудноразрешимые задачи так и остаются трудноразрешимыми, даже если ослабить некоторые ограничения. Более того, существует множество практических задач, которые мы не можем решить, поскольку неизвестен достаточно быстрый алгоритм. В данной части мы будем считать такие задачи NP-трудными, не будем искать эффективный алгоритм их решения и не будем пытаться найти их решение без применения продвинутых технологий, вроде рассматриваемых в части VIII (за исключением, возможно, примитивных методов для решения совсем небольших задач).
Существуют задачи обработки графов, трудность решения которых неизвестна. Неизвестно, существует ли алгоритм их эффективного решения, и неизвестно, являются ли они NP-трудными. Вполне возможно, что по мере расширения нашего знания алгоритмов и свойств графов некоторые из этих задач перейдут в категорию разрешимых и даже легких задач. Наиболее известной задачей такого класса является описанная ниже важная естественная задача, с которой нам уже приходилось сталкиваться (см. рис. 17.2).
Изоморфизм графов. Можно ли сделать два графа идентичными, переименовав их вершины? Известны эффективные алгоритмы решения этой задачи для многих специальных видов графов, но вопрос о трудности решения общей задачи остается открытым. Количество важных задач, трудность решения которых неизвестна, невелико по сравнению с другими рассмотренными категориями задач, благодаря интенсивным исследованиям в этой области за последние несколько десятилетий. Некоторые задачи этого класса, такие как изоморфизм графов, имеют огромный практический интерес, а другие задачи известны в основном потому, что они не поддаются классификации.
Рассматривая легкие задачи, мы обычно сравниваем алгоритмы с различными характеристиками в худшем случае и пытаемся предсказать производительность с помощью анализа и эмпирических исследований. В случае обработки графов решение таких задач сопряжено с особыми трудностями из-за сложности определения видов графов, которые могут встретиться на практике. К счастью, многие важные классические алгоритмы имеют оптимальную или почти оптимальную производительность в худшем случае, либо время их выполнения зависит только от количества вершин и ребер, а не от структуры графа. Это позволяет сосредоточиться на оптимизации реализаций, не теряя возможности надежно предсказывать их производительность.
Итак, известен широкий спектр задач и алгоритмов обработки графов. В таблице 17.2 содержится некоторая приведенная выше информация. Каждая задача представлена в различных вариантах для различных видов графов (ориентированные, взвешенные, двудольные, планарные разреженные, насыщенные), и существуют тысячи задач и алгоритмов, заслуживающих изучения.
В данной таблице обобщены приведенные в тексте (грубые и субъективные) показатели относительной трудности решения различных классических задач обработки графов. Эти примеры не только показывают диапазон сложности задач, но и то, что сама классификация конкретной задачи может оказаться трудной проблемой.
Л | Р | Т | ? | |
---|---|---|---|---|
Неориентированные графы | ||||
Связность | v | |||
Общая связность | v | |||
Эйлеров цикл | v | |||
Гамильтонов цикл | v | |||
Двудольное сопоставление | v | |||
Максимальное сопоставление | v | |||
Планарность | v | |||
Максимальная клика | v | |||
Раскраска 2 цветами | v | |||
Раскраска 3 цветами | v | |||
Кратчайшие пути | v | |||
Самые длинные пути | v | |||
Вершинное покрытие | v | |||
Изоморфизм | v | |||
Орграфы | ||||
Транзитивное замыкание | v | |||
Сильная связность | v | |||
Цикл нечетной длины | v | |||
Цикл четной длины | v | |||
Взвешенные графы | ||||
Минимальное остовое дерево | v | |||
Задача коммивояжера | v | |||
Сети | ||||
Кратчайшие пути (неотрицательные веса) | v | |||
Кратчайшие пути (отрицательные веса) | v | |||
Максимальный поток | v | |||
Распределение | v | |||
Поток минимальной стоимости | v |
Обозначения: | |
Л | Легкая -известен эффективный классический алгоритм решения |
Р | Разрешимая -решение существует (трудно получить реализацию) |
Т | Трудноразрешимая -эффективное решение неизвестно (NP-трудная задача) |
? | Неизвестно, существует ли решение |
Разумеется, мы не рассчитываем на то, что решим любую задачу, с которой встретимся, а некоторые с виду простые задачи все еще приводят экспертов в замешательство. Несмотря на естественное ожидание, что отделить легкие задачи от трудноразрешимых будет нетрудно, многие из рассмотренных нами примеров показывают, что даже отнесение задачи к одной из этих приблизительных категорий может оказаться сложной исследовательской задачей.
По мере расширения наших знаний о графах и алгоритмах на графах отдельные задачи могут переходить из одной категории в другую. Несмотря на всплеск исследовательской деятельности в семидесятые годы прошлого столетия и интенсивную работу многих исследователей в последующий период, все-таки остается вероятность, что все рассматриваемые нами задачи когда-то будут отнесены к категории " легких " (т.е. решаемых компактным, эффективным и, возможно, хитроумным алгоритмом).
Теперь, подготовив данный контекст, мы приступим к рассмотрению множества полезных алгоритмов обработки графов. Задачи, которые мы способны решать, возникают часто, а изучаемые нами алгоритмы на графах хорошо работают в самых разнообразных приложениях. Эти алгоритмы служат основой для решения других многочисленных задач, которые нам приходится решать, даже если невозможно гарантировать наличие эффективного решения.
Упражнения
17.108. Докажите, что ни один из графов, изображенных на рис. 17.24, не может быть планарным.
17.109. Напишите клиентскую функцию АТД графа, которая выясняет, содержит ли заданный граф один из графов, показанных на рис. 17.24. Для этой цели воспользуйтесь примитивным алгоритмом, который проверяет все возможные подмножества из пяти вершин для клики и все возможные подмножества из шести вершин для полного двудольного графа. Примечание: Этой проверки недостаточно для доказательства планарности графа, поскольку она игнорирует условие, что удаление вершин степени 2 в некоторых подграфах может дать один из двух запрещенных подграфов.
17.110. Начертите граф
3-71-47-80-55-23-02-90-64-92-6
6-41-58-29-08-34-52-31-63-57-6,
в котором нет пересекающихся ребер, либо докажите, что такой чертеж невозможен.
17.111. Найдите такой способ назначить один из трех цветов каждой вершине графа
3-71-47-80-55-23-02-90-64-92-6
6-41-58-29-08-34-52-31-63-57-6,
чтобы ни одно ребро не соединяло вершины одного и того же цвета, либо покажите, что это сделать невозможно.
17.112. Решите задачу независимого множества для графа
3-71-47-80-55-23-02-90-64-92-6
6-41-58-29-08-34-52-31-63-57-6.
17.113. Каков размер максимальной клики в графе де Брюйна порядка п?