Глава 5 Файл

advertisement
5 От метода к алгоритму
Алгоритм решения комбинаторно-оптимизационной
задачи или некоторого класса таких задач является
реализацией некоторого метода дискретной
оптимизации операциями преобразования модели
объекта проектирования в модель результата.
1
Построение и анализ алгоритмов (от метода к
алгоритму)
Алгоритм как объект разработки с одной стороны и средство решения
некоторой задачи с другой является таким же предметом
исследования, как и те объекты, для работы с которыми он
предназначен. С прикладной точки зрения пользователя интересует:
• какое качество решения задачи может обеспечить алгоритм –
точность алгоритма;
• сколько времени и памяти ЭВМ потребуется для этого – временная
(вычислительная) и емкостная сложность.
Заметим, что эти характеристики служат не только для обоснованного
сравнения и выбора алгоритма пользователем. Конечно, нельзя
доказать, что алгоритм точный, или оценить его вычислительную
сложность, пока он не разработан до конца с той или иной степенью
детализации. Однако, анализ на стадии разработки тех
преобразований, которые предполагается выполнять в ходе работы
алгоритма, может подсказать, как сделать его более
эффективным.
2
Точность алгоритмов
Алгоритм комбинаторно-оптимизационной задачи называется точным,
если на всех допустимых наборах входных данных задачи он
обеспечивает получение оптимального решения, т. е.
( i I ) A(Bi) = opt,
где А – алгоритм, Bi – i - ый набор входных данных, B = {Bi / i I} –
множество всех допустимых наборов входных данных задачи.
Точность (в некоторых источниках «правильность») алгоритма –
фундаментальная проблема теории алгоритмов, а доказательство
точности алгоритма либо ее оценки – один из наиболее важных и
сложных этапов его разработки.
Подходы к доказательству точности алгоритма:
• экспериментальный прогон на специально сконструированных
входных данных и сравнение результатов с заранее известными –
правомерность такого вывода определяется тем, содержат ли
специально сконструированные наборы входных данных все
допустимые варианты;
3
Точность алгоритмов
• установление того, что не существует такого набора входных
данных, при котором A(Bi)  opt;
Несмотря на то, что утверждения «для всех наборов входных
данных A(Bi) = opt» и «не существует набора входных данных, для
которого A(Bi)  opt» логически равнозначны, эти подходы
различаются по методам и возможностям доказательства.
• доказательство того, что действия над графами в ходе всего
процесса их преобразования «правильные», т. е. единственно
возможные с точки зрения обеспечения оптимума целевой функции
задачи независимо от конкретного набора входных данных.
Первые два подхода лишь позволяют установить факт точности
алгоритма, последний – ориентирует разработчика на его
построение.
Для того, чтобы выбрать и осуществлять «правильные»
преобразования графов, нужно исследовать математические
свойства графов объекта и результата преобразования.
4
Доказательство точности алгоритма Прима
Алгоритм строит остовное дерево минимального веса, например, с
минимальной суммой длин ребер, реализуя метод жадного выбора.
Пусть задан взвешенный связный граф G(X, U) без кратных ребер, в
котором каждому ребру uj  U сопоставлен некоторый вес w(uj).
На первом шаге алгоритма ищется ребро минимального веса, на всех
следующих шагах к уже построенному поддереву присоединяется
ребро минимального веса, начиная с третьего шага не образующее
с ним цикла, до тех пор, пока все вершины не будут включены в
дерево.
Докажем, что алгоритм Прима точный, используя следующие два
основные свойства деревьев:
• дерево – это связный граф без циклов;
• добавление в остовное дерево при |U|  2 любого нового ребра
приводит к возникновению ровно одного цикла.
Докажем справедливость следующего утверждения:
Если w(um) = min {w(ui) / i = 1,m}, где m = |U|, то в графе G
существует остовное дерево минимального веса Т, содержащее
ребро um . И более того, если w(um) < min {w(ui) / i = 1,m-1}, то
5
остовное дерево минимального веса должно содержать ребро um.
Доказательство точности алгоритма Прима
Доказательство: пусть Т’ – остовное дерево минимального веса, не
содержащее um. Добавив это ребро к дереву Т’, получим связный
граф с единственным циклом.
um
uj
uj
um
В этом цикле любое ребро uj имеет вес w(uj)  w(um). Следовательно,
удалив uj, мы получим остовное дерево Т, такое, что W(T)  W(T’).
Справедливость этого утверждения доказывает правильность
первого шага алгоритма Прима.
Доказательство правильности k-го (k = 2, 3, …, n-2, где n=|X|)
выполнения второго шага алгоритма базируется на следующей
теореме.
6
Теорема
Пусть Ti – поддерево графа G и um – ребро с наименьшим весом,
соединяющее вершину, принадлежащую Ti и вершину, не
принадлежащую Ti.
Тогда в графе G существует остовное дерево Т, содержащее Ti и um,
такое, что, если T’ – любое остовное дерево в G, содержащее Ti, то
W(T)  W(T’).
Доказательство.
um
Пусть Т’ - остовное дерево в G, содержащее Ti и
обладающее минимальным весом среди всех
остовных деревьев, содержащих Ti, причем T’ не
Ti
включает um. Добавим в Т’ ребро um. Получим
связный граф с одним циклом, одним из ребер
которого является um. Этот цикл содержит ребро
uj, соединяющее вершину, принадлежащую Ti, с
вершиной, не принадлежащей Ti. Согласно
um
исходной посылке w(uj)  w(um). Следовательно,
удалив из Т’ ребро uj и добавив в него um, мы
uj
получим дерево Т, такое что W(T)  W(T’).
T'
Теорема доказана.
7
Доказательство точности алгоритма Прима
Ну и, наконец, поскольку при каждом повторении второго шага к
поддереву (одному ребру после первого шага) присоединяется
ребро, не образующее цикл, и алгоритм заканчивает работу, когда в
дерево включены все вершины графа G, то в результате
выполнения алгоритма строится остовное дерево.
На основании только что доказанных утверждений и теоремы это
дерево будет иметь минимальный вес.
8
Оценка точности алгоритма
Цель оценки точности алгоритма – определение границ погрешности
решения, обеспечиваемого им. Очевидно, что для различных
входных данных приближенный алгоритм может давать решение
ближе к оптимальному и дальше от него, т.е. имеет смысл говорить о
поведении алгоритма «в лучшем» и «в худшем».
При определении границы погрешности «в худшем» надо иметь
гарантию того, что ни при каком допустимом наборе входных данных
решение не будет хуже, чем установлено границей, а для границы «в
лучшем» – того, что не существует набора данных, при котором
решение ближе к оптимальному. Анализируя вид и
последовательность операций, выполняемых над графами в
процессе решения задачи, можно сконструировать входные
данные (или сформулировать требования к ним), на которых этот
алгоритм приводит к наибольшей и наименьшей погрешности по
функционалу.
Гарантированность полученных оценок погрешности алгоритма
обеспечивается доказательством того факта, что сконструированные
наборы входных данных действительно приводят к наихудшему и
наилучшему результату работы алгоритма соответственно.
9
Задача коммивояжера (поиск гамильтонова
цикла минимального веса)
Идея алгоритма при решении методом жадного выбора заключается в
следующем:
• определяем ребра, инцидентные исходной
вершине;
• затем выбираем и включаем в
формируемый цикл ребро минимального
веса (длины).
Далее действия повторяются для каждой,
только что достигнутой вершины, причем в
цепь включаются ребра, не образующие с
ней цикла, до тех пор, пока количество
вершин цепи <n-1, где n = |X|.
x1
1
3
4
x5
5 6
x4
x2
7 7 4
3
2
x3
Ребро, соединяющее (n-1)-ю вершину с начальной и образующее
гамильтонов цикл, определяется однозначно.
10
Задача коммивояжера. Граница «в лучшем»
Для получения оптимального решения необходимо, чтобы на каждом
шаге «удавалось» включать в цепь ребро, имеющее минимальную
длину среди оставшихся ребер, инцидентных текущей вершине
(как не образующих, так и образующих «частичные» циклы).
x1
4
2
3
x3
l = 11
Решение точное: при
построении цикла
условие удовлетворяется на каждом шаге
2
3
x3
l = 16
Решение не точное:
при построении цикла
условие не удовлетворяется на четвертом
шаге.
x2
1
4
5
10
x4
x1
x2
1
4
10
5
x4
x1
x2
1
5
10
2
x4
3
x3
l = 13
Точное
решение
11
Задача коммивояжера. Граница «в лучшем»
Отсюда вытекает следующее утверждение: приближенный алгоритм
решения задачи коммивояжера по методу поиска в глубину
обеспечивает получение точного решения, если каждый раз
выбирается ребро u(xk, xr) такое, что
l(u(xk, xr)) = min{l(u(xk,xj)) /u  Г1xk \ u(xi,xk)},
где xi – предыдущая вершина цепи, являющейся фрагментом
гамильтонова цикла, Г1 – отношение (предикат) инцидентности
между множествами вершин X и ребер U, таким образом, Г1xk = Uk –
ребра, инцидентные вершине xk.
x1
x2
1
Это слишком жесткое условие – граница
8
3
«в лучшем» – есть наборы данных,
которые ему не удовлетворяют, но
5
2
решение при этом будет оптимальным.
x4
4
x3
12
Задача коммивояжера. Граница «в худшем»
Ребра, выбираемые при первом и втором выполнении основного шага
алгоритма, не могут образовывать «частичных» циклов. В результате
получается:
l (u(xн, хr))= min {l (u(xн, xj)) / u  Г1хн}
l (u(xr, xt)) = min {l (u(xr, xj)) / u Г1xr\u(xн, xr),
где xн – исходная вершина гамильтонова цикла.
x1
Далее при каждом повторении выбирается
ребро минимальной длины, исключая
1
ребра, образующие «частичные» циклы.
10
Наихудшим случаем является такой, когда
5
выбираемое ребро имеет максимальную
x5
x2
длину.
Тогда граница погрешности алгоритма «в
6 3 4 2
10
худшем» будет:
10
L х. =min { l(u(xн,xj)) / u  Г1xн} +
+min { l (u(xr,xj)) / u  Г1xr\u(xн,xr)} +
x4
x3
6
+  max { l(u) / u  Г1xi },
хi  X’
где X’ = X \ {xн, xr}, т. е. первые два ребра цикла будут иметь
минимальную, а остальные – максимальную величину из ребер,
инцидентных текущей вершине.
13
Вычислительная сложность алгоритма
Физическое время реализации алгоритма при некотором наборе входных
данных может быть определено как
n
T =  Qi ti,
i =1
где Qi – количество операций i -го типа, выполняемых при решении задачи; ti – время выполнений i -ой операции; n – число типов операций.
Для одного и того же алгоритма время Т зависит от языка
программирования и быстродействия конкретной ЭВМ.
Можно принять за эталон некоторую элементарную операцию и, зная
отношение времени выполнения остальных к эталонной ki = ti / tэ.,
определить суммарное количество условных эталонных операций
n
N э =  k i Qi
i =1
и общее время их реализации
Т = Nэtэ.
14
Вычислительная сложность алгоритма
Объективная мера временной сложности алгоритма должна быть
машинно- и программно-независимой.
В качестве такой оценки может быть использовано значение Nэ.
В зависимости от требуемой или возможной на данной стадии
разработки алгоритма степени его детализации аналогичной по
смыслу оценкой может быть количество выполнений
доминирующей операции (например, сравнения), некоторых
основных действий или шагов N.
Очевидно, что при таком подходе оценка сложности зависит от
удачного выбора доминирующей операции.
Число шагов N определяется описанием процесса решения задачи
некоторой алгоритмической моделью. Это величина
математическая, не зависящая от физической реализации
алгоритма.
Величину N можно считать «математическим временем» выполнения
алгоритма, определяющим физическое время с точностью до
константы (tэ), зависящей от реализации. Такую оценку будем
называть вычислительной сложностью алгоритма на некотором
наборе входных данных.
15
Вычислительная сложность алгоритма
Вычислительная сложность является функцией размерности задачи.
В общем случае размерность задачи может характеризоваться массивом
параметров, в частном – скаляром.
В задачах на графах размерностью может быть:
• скаляр – число вершин графа;
• массив – {число вершин графа; число его ребер; среднее значение
локальной степени вершины; среднее количество вершин, инцидентных ребру гиперграфа}.
Пусть А – алгоритм решения некоторого класса задач, а n – размерность
задачи этого класса. Вычислительная сложность алгоритма – это
некоторая функция fА(n), отображающая размерность задачи в
«математическое время» ее решения.
Функция fА(n) должна давать оценку для максимального числа некоторых
операций или шагов, которые должен выполнить алгоритм для решения
любой задачи данного класса размерностью n.
Эта функция является критерием качества алгоритма с точки зрения
возможных временных затрат:
• эффективными являются полиномиальные алгоритмы, у которых fА(n)
растет не быстрее, чем полином от n;
• алгоритмы с экспоненциальной вычислительной сложностью
16
n
(2 ,n! и т. п.), пригодны для решения задач ограниченной размерности.
Оценки функции вычислительной сложности
Используют три вида оценок:
• «в худшем» – оценка сверху – входные данные являются худшими из
возможных (например в предположении: «граф – полный» или
«отсечения вершин не будет» и др.) – ориентация на худший случай
может приводить к пессимистическим оценкам, например, метод
ветвей и границ имеет экспоненциальную верхнюю оценку
вычислительной сложности, но для ряда наборов входных данных
зависимость времени решения задачи от ее размерности
полиномиальная;
• «в лучшем» – оценка снизу – входные данные лучшие из возможных –
не имеет такой практической ценности, как оценка «в среднем»;
• «в среднем» – наиболее реалистичная оценка – для алгоритмов на
графах получается в предположении, что граф однородный с
некоторым «средним» значением локальной степени вершин – не
обеспечивает гарантий того, что в реальной ситуации не встретится
такой набор входных данных, при котором вычислительная сложность
не превысит оценку в среднем.
Точность оценок вычислительной сложности зависит от степени детализации проработки и анализа алгоритма, поэтому на ранних ста- 17
диях точный анализ вычислительной сложности не возможен.
Асимптотическая оценка вычислительной
сложности
Широко используется асимптотическая оценка вычислительной
сложности алгоритма типа O(n) или o(n). Эта оценка с точностью до
константы – сомножителя и членов более низкого порядка совпадает
с точной (правильнее с функциональной). Основание для
использования таких оценок – большая размерность большинства
практических задач.
Функцию f(n) определяют как O((n)) и говорят, что она порядка (n),
если
lim f(n) / (n) = const.
n
Порядок f(n) обозначают как f(n) = O ((n)).
Функция f(n)) имеет порядок o((n)), если
lim f(n) / (n) = 0.
n
Например, если f(n) = 5n3 -3n2 +2n + 6,
то f(n) = O(n3), так как lim (5n3 - 3n2 +2n + 6)/n3 = 5
n
и f(n) = o(n3,1), так как lim (5n3 - 3n2 +2n + 6)/n3,1 = 0 .
n
18
Обобщенная оценка сложности алгоритма
В общем случае объем памяти, который необходим для реализации
алгоритма – емкостная сложность, – равен сумме объемов,
требуемых для программы, входных данных, а также промежуточных
и окончательных результатов. При разработке алгоритма главным
образом интересуют три последние составляющие. Единицы
измерения этого объема могут быть общепринятыми (байт и т. д.)
либо некоторыми условными, определяемыми спецификой задачи.
Подсчет емкостной сложности, как правило, довольно простая задача,
хотя, возможно, и трудоемкая.
В качестве обобщенной характеристики сложности алгоритма
предложено использовать так называемый коэффициент
сложности, равный отношению суммарного количества эталонных
или доминирующих операций к требуемому объему памяти:
kсл = N / V .
Такая характеристика может быть полезной при сравнительной оценке
алгоритмов. Отметим в заключение, что вычислительная и
емкостная сложность коррелированы. Как правило, снижение
вычислительной сложности приводит к увеличению емкостной и
наоборот.
19
Основные этапы построения алгоритма
Разработка алгоритма, как и подготовка задачи к решению, –
итерационный процесс и кроме этого – столько же наука, сколько и
искусство. Однако в качестве общего руководства целесообразно
определить основные этапы и примерную последовательность их
выполнения. Не всегда удается выбрать метод решения задачи до
разработки алгоритма. Нередко предварительно можно лишь
определить круг возможных методов, а сам выбор приходится
осуществлять в ходе построения и анализа алгоритма.
Основными этапами разработки алгоритма являются:
1. Определение операций, выполняющих преобразование исходного
графа в граф результата.
2. Выбор способа представления графов и его реализации в памяти
ЭВМ.
3. Конструирование или выбор оценочной функции.
4. Анализ возможных методов решения задачи и выбор или
модификация приемлемого.
5. Разработка алгоритмической модели процесса решения задачи.
6. Доказательство правильности или оценка точности алгоритмической
модели.
7. Оценка вычислительной и емкостной сложности.
20
8. Детальная проработка алгоритма.
Определение операций, выполняющих
преобразование исходного графа в граф
результата
Эти операции необходимы для реализации метода решения задачи в
виде алгоритма и выбора структур данных. Совокупность таких
операций определяется по результатам анализа проектных процедур и математической постановки задачи. Из нее нам известны:
• граф, являющийся математической моделью исходного описания
объекта проектирования, его характеристики и свойства;
• вид и свойства графа – математической модели результата
проектирования;
• целевая функция и ограничения задачи, т. е. функции, зависящие от
управляемых параметров (характеристик графа результата) и
свойств, которыми должен обладать этот граф.
Анализируя эту информацию и зная элементарные теоретикомножественные и алгебраические операции над графами, мы можем
определить операции, необходимые для преобразования исходного
графа в граф результата.
Напомним, что к элементарным операциям над графом относятся
операции удаления, добавления, разбиения, стягивания или свертки,
установления соответствий и раскраски его вершин или ребер.
Следует отметить, что далеко не всегда эти операции очевидны21и
однозначны.
Пример выбора операций преобразования.
Задача построения остовного дерева
минимального веса
Формальная постановка:
Выполнить преобразование D графа G(X,U) в связный суграф GS*
(XS,US*) с цикломатическим числом  = 0, такой, что
L =  l(ui) min,
uiUS*
где l(ui) – вес ui -го ребра.
Здесь: L – целевая функция, связность суграфа и равенство
цикломатического числа нулю - ограничения. Из постановки задачи
следует, что US* U, |X| = |XS| и, если |X| = n, |US*| = k, то k = n-1.
Рассмотрим процесс определения операций, составляющих
преобразование D.
Cуграф – это такая часть графа, у которой XS =X, а US  U, т. е. суграф
получается удалением из графа части ребер. В данном случае
суграф должен быть связным и иметь цикломатическое число  =0,
т. е. он является остовным деревом. Если |U| = m, то для
преобразования графа G в остовное дерево нам следует из графа G
удалить (m-n+1) ребер ( у полного графа- (n2-3n)/2+1 ребер).
Примем без доказательства, что для обеспечения min L необходимо
последовательно удалять ребра максимального веса.
22
Пример выбора операций преобразования (2)
Продолжим анализ, можем ли мы удалять ребра, не учитывая их
свойств, их «роли» в графе. Из ограничений задачи мы выясняем,
что суграф должен быть связным и не иметь циклов. Из первого
свойства следует, что нам нельзя удалять ребро-перешеек, даже
если оно имеет максимальный вес среди всех ребер, так как в этом
случае граф распадается на две компоненты связности.
xk
xr
Таким образом, при выборе очередного удаляемого ребра u(xi, xj)
необходимо проверять остается ли граф связным, т. е. определять
наличие маршрута S между вершинами xi и xj. Известно, что это
является достаточно сложной самостоятельной задачей, алгоритм
решения которой имеет вычислительную сложность O(n).
23
Пример выбора операций преобразования
Обратимся ко второму свойству решения: граф результата – дерево, т. е.
не должен иметь циклов. Обязательно ли мы получим дерево, удалив
(m-n+1) ребер и сохранив связность графа? Проанализировав
определение остовного дерева, мы получим положительный ответ.
Мы выполнили достаточно полный анализ и определили основную
операцию преобразования графа G в остовное дерево.
Является ли операция удаления ребер единственно возможной и
эффективной с точки зрения вычислительной сложности алгоритма с
учетом проверки связности получаемого графа?
Точные алгоритмы решения этой задачи – алгоритмы Прима и Краскала
используют операцию добавления ребер, причем количество таких
операций n-1. В ходе работы алгоритма Краскала для того, чтобы
избежать циклов при построении дерева посредством подсоединения
ребра u(xi, xj) минимального веса, достаточно проверить
принадлежность вершин – концов этого ребра разным подграфам и
выполнить коррекцию номеров подграфов. Эти операции имеют
вычислительную сложность O(1) и O(n) соответственно.
24
Сравнение алгоритмов, использующих
операции удаления и добавления ребер
Алгоритм удаления ребер
Упорядочить U по убыванию
L.
2. Исходное состояние: Gп(X,U).
3. Удаление uj максимального
веса.
4. Количество операций:
k=(m-n+1).
При каждом удалении проверка связности графа
1.
O(max(m, n))
Алгоритм Краскала
Упорядочить U по возрастанию
L.
2. Исходное состояние: G(X, ).
3. Добавление uj минимального
веса.
4. Количество операций:
k=n-1.
При каждом удалениипроверка отсутствия циклов через
проверку принадлежности
вершин – концов ребер разным
подграфам – O(1) и коррекция
номеров подграфов – O(n)
1.
Алгоритм Краскала – более эффективен ( у полного графа- n (n-1)/2
25
ребер).
Разработка алгоритмической модели процесса
решения задачи
Алгоритмическая модель – описание процесса решения задачи,
отражающее основные этапы преобразования данных и связи
между этими этапами.
Алгоритмическая модель должна быть адекватна этому процессу в
смысле полноты и правильности отображения в ней информации,
необходимой для оценки его эффективности.
Главное назначение алгоритмической модели – описать идею алгоритма с такой полнотой и степенью детализации и формализации,
которая, не отвлекая на частности, позволила бы оценить ожидаемые вычислительную и емкостную сложность алгоритма, а также,
возможно, доказать его правильность или получить оценки точности.
Для оценки вычислительной и емкостной сложности алгоритмическая
модель должна отображать:
• основные многократно повторяющиеся операции преобразования
исходного графа;
• аналитические зависимости, по которым рассчитываются
определенные критерии и/или оценочные функции;
• операции с выбранными структурами данных.
26
Разработка алгоритмической модели процесса
решения задачи
Для доказательства правильности или оценки точности алгоритма,
основанных на исследовании математических свойств графов как
объекта и результата преобразований и вида выполняемых
операций, алгоритмическая модель должна иметь определенную
степень формализации описания.
Под определенной степенью формализации описания мы будем
понимать использование такой теоретико-множественной символики
для обозначения объектов и операций преобразования, которая
давала бы четкое и полное представление о свойствах графов
(объекта и результата) и однозначную трактовку выполняемых
действий.
Например:
Модель объекта: Gп(X,U), UW или Gп(X,<U,W>).
Вид результата: T(X,U1), c = 0 или |U1| = |X|-1.
Операция преобразования: G := G \ uj или G:= G – uj.
Если все операции преобразования исходного графа, влияющие на
обеспечение оптимума целевой функции задачи и оценку сложности
алгоритма, отражены в алгоритмической модели, то требуемая
27
полнота обеспечена.
Детальная проработка алгоритма
Детальное описание алгоритма – это основные исходные данные для
составления программы.
Детальное описание алгоритма:
•
должно включать все операции – так как трудно рассчитывать, что
программист в такой же степени, как и Вы, владеет аппаратом
математической логики и теории графов, так же хорошо
ориентируется в содержательной и формальной постановке
Вашей задачи и сможет восстановить опущенные Вами операции;
•
должно содержать подробные комментарии – для облегчения
понимания формального описания алгоритма на языке теории
множеств, математической логики и теории графов;
•
может быть представлено в виде схемы – для наглядности
представления структуры алгоритма;
•
представлять операции над графами в максимально возможном
приближении к конструкциям (операторам) выбранного языка
программирования;
•
должно строиться в соответствии с принципами структурного
28
программирования.
Детальная проработка алгоритма
Степень детализации алгоритма можно считать приемлемой, если в
каждом пункте или каждой конструкции алгоритма однозначно и
полно определено над какими данными, какие операции и при каких
условиях должны быть выполнены.
При детальной проработке алгоритма необходимо уделить серьезное
внимание вопросу выбора таких способов преобразования
исходного графа и подсчета значения критериев и/или оценочных
функций, которые обеспечивали бы максимально возможное
снижение вычислительной сложности алгоритма. Реализация этой
рекомендации в виде того или иного способа или приема и их
эффективность зависит от конкретной задачи, метода ее решения и
характеристик исходного графа (количество вершин и ребер,
среднее значение локальной степени вершин, инцидентных ребру и
т. п.).
29
Download