Л10 ПРИМЕРЫ КОММИВ и др.ppt
- Количество слайдов: 73
Приближенный жадный алгоритм для задачи о коммивояжере
Одна из самых известных и важных задач транспортной логистики и задач оптимизации в целом – задача коммивояжера (задача о бродячем торговце). Задано n городов попарно соединенных дорогами. Для каждой дороги задается стоимость проезда по ней. Коммивояжер должен посетить все n городов по одному разу и вернуться в начальный город, при этом суммарная стоимость проезда должна быть минимальной. Найти самый выгодный маршрут.
Мерой выгодности маршрута будет • минимальное время, проведенное в пути, • минимальные расходы на дорогу или, в простейшем случае, • минимальная длина пути. Одним из первых предложил решение подобной проблемы выдающийся математик XIX в. – Уильям Гамильтон. Рассмотрим решение такой задачи методом ветвей и границ и замкнутый вариант, т. е. такой, когда в итоге мы возвращаемся в исходную точку.
ПЛАН РЕШЕНИЯ Для решения задачи коммивояжера методом ветвей и границ необходимо выполнить следующую последовательность действий: 1. Построение матрицы с исходными данными 2. Нахождение минимума по строкам 3. Редукция строк 4. Нахождение минимума по столбцам 5. Редукция столбцов 6. Вычисление оценок нулевых клеток 7. Редукция матрицы 8. Если полный путь еще не найден, переходим к пункту 2, если найден к пункту 9 9. Вычисление итоговой длины пути и построение маршрута.
МЕТОДИКА РЕШЕНИЯ Вершины графа - города, ребра их соединяющие – дороги. 1. Построение матрицы с исходными данными Сначала необходимо длины дорог соединяющих города представить в виде следующей таблицы:
В примере 4 города и в таблице указано расстояние от каждого города к 3 - м другим, в зависимости от направления движения (т. к. некоторые ж/д пути могут быть с односторонним движением и т. д. ). Расстояние от города к этому же городу обозначено буквой M. Также используется знак бесконечности. Это сделано для того, чтобы данный отрезок пути был условно принят за бесконечно длинный. Тогда не будет смысла выбрать движение от 1 -ого города к 1 -му и т. п. в качестве отрезка маршрута.
2. Нахождение минимума по строкам Находим минимальное значение в каждой строке (di) и выписываем его в отдельный столбец.
3. Редукция строк Производим редукцию строк – из каждого элемента в строке вычитаем соответствующее значение найденного минимума (di). было стало В итоге в каждой строке будет хотя бы одна нулевая клетка.
4. Нахождение минимума по столбцам Далее находим в последней таблице минимальные значения в каждом столбце (dj). Эти минимумы выписываем в отдельную строку.
5. Редукция столбцов Вычитаем из каждого элемента матрицы соответствующее ему dj. В итоге в каждом столбце будет хотя бы одна нулевая клетка.
6. Вычисление оценок нулевых клеток Для каждой нулевой клетки получившейся преобразованной матрицы находим «оценку» . Ею будет сумма минимального элемента по строке и минимального элемента по столбцу, в которых размещена данная нулевая клетка. Сама она при этом не учитывается. Найденные ранее di и dj не учитываются. Полученную оценку записываем рядом с нулем, в скобках.
И так по всем нулевым клеткам:
7. Редукция матрицы Выбираем нулевую клетку с наибольшей оценкой. Заменяем ее на «М» . Мы нашли один из отрезков пути. Выписываем его (от какого города к какому движемся, в нашем примере от 4 -ого к 2 му).
Ту строку и тот столбец, где образовалось две «М» полностью вычеркиваем. В клетку соответствующую обратному пути ставим еще одну букву «М» (т. к. мы уже не будем возвращаться обратно).
8. Если полный путь еще не найден, переходим к пункту 2, если найден к пункту 9 Если мы еще не нашли все отрезки пути, то возвращаемся ко 2 -му пункту и вновь ищем минимумы по строкам и столбцам, проводим их редукцию, считаем оценки нулевых клеток и т. д. Если все отрезки пути найдены (или найдены еще не все отрезков, но оставшаяся часть пути очевидна) – переходим к пункту 9.
9. Вычисление итоговой длины пути и построение маршрута Найдя все отрезки пути, остается только соединить их между собой и рассчитать общую длину пути (стоимость поездки по этому маршруту, затраченное время и т. д. ). Длины дорог соединяющих города берем из самой первой таблицы с исходными данными. В нашем примере маршрут получился следующий: 4 → 2 → 3 → 1 → 4. Общая длина пути: L = 30.
Алгоритм Литтла В каждой строке матрицы стоимости найдем минимальный элемент и вычтем его из всех элементов строки. Сделаем это и для столбцов, не содержащих нуля. Получим матрицу стоимости, каждая строка и каждый столбец которой содержат хотя бы один нулевой элемент. Для каждого нулевого элемента матрицы cij рассчитаем коэффициент Гi, j, который равен сумме наименьшего элемента i строки (исключая элемент Сi, j=0) и наименьшего элемента j столбца. Из всех коэффициентов Гi, jвыберем такой, который является максимальным Гk, l=max{Гi, j}. В гамильтонов контур вносится соответствующая дуга (k, l). Удаляем k-тую строку и столбец l, поменяем на бесконечность значение элемента Сl, k (поскольку дуга (k, l) включена в контур, то обратный путь из l в k недопустим). Повторяем алгоритм шага 1, пока порядок матрицы не станет равным двум. Затем в текущий ориентированный граф вносим две недостающие дуги, определяющиеся однозначно матрицей прядка 2. Получаем гамильтонов контур. В ходе решения ведется постоянный подсчет текущего значения нижней границы. Нижняя граница равна сумме всех вычтенных элементов в строках и столбцах. Итоговое значение нижней границы должно совпасть с длиной результирующего контура.
Алгоритм Литтла является частным случаем применения метода "ветвей и границ" для конкретной задачи. Общая идея: надо разделить огромное число перебираемых вариантов на классы и получить оценки: снизу – в задаче минимизации, сверху – в задаче максимизации для этих классов, чтобы иметь возможность отбрасывать варианты не по одному, а целыми классами. Трудность состоит в том, чтобы найти такое разделение на классы (ветви) и такие оценки (границы), чтобы процедура была эффективной.
Алгоритм Литтла • В каждой строке матрицы стоимости найдем минимальный элемент и вычтем его из всех элементов строки. • Сделаем это и для столбцов, не содержащих нуля. Получим матрицу стоимости, каждая строка и каждый столбец которой содержат хотя бы один нулевой элемент. • Для каждого нулевого элемента матрицы cij рассчитаем коэффициент Di, j, который равен сумме наименьшего элемента i строки (исключая элемент Сi, j=0) и наименьшего элемента j столбца. Из всех коэффициентов D i, jвыберем такой, который является максимальным D k, l=max{D i, j}. В гамильтонов контур вносится соответствующая дуга (k, l).
• Удаляем k-тую строку и столбец l, поменяем на бесконечность значение элемента Сl, k (поскольку дуга (k, l) включена в контур, то обратный путь из l в k недопустим). • Повторяем алгоритм шага 1, пока порядок матрицы не станет равным двум. • Затем в текущий ориентированный граф вносим две недостающие дуги, определяющиеся однозначно матрицей прядка 2. Получаем гамильтонов контур. • В ходе решения ведется постоянный подсчет текущего значения нижней границы. Нижняя граница равна сумме всех вычтенных элементов в строках и столбцах. Итоговое значение нижней границы должно совпасть с длиной результирующего контура.
Пример 1. Задача коммивояжера (алгоритм Литтла) Рассмотрим работу этого алгоритма на конкретном примере. Пусть имеется граф, заданный матрицей смежности: — 6 4 8 7 14 6 — 7 11 7 10 4 7 — 4 3 10 8 11 4 — 5 11 7 7 3 5 — 7 14 10 10 11 7 — Элемент матрицы сij будем считать стоимостью перелета из города i в город j.
Справедливо следующее: вычитая любую константу из всех элементов любой строки или столбца матрицы С, оставляем минимальный тур минимальным. В связи с этим, процесс вычитания из каждой строки ее минимального элемента (приведение по строкам) не влияет на минимальный тур. Аналогично вводится понятие приведения по столбцам, обладающее тем же свойством.
Приведем исходную матрицу по строкам Приведенная по строкам 6 — 7 11 4 7 — 4 8 11 4 — 7 7 3 5 14 10 10 11 7 14 Исходная — 6 4 8 7 10 3 10 5 11 — 7 7 — — 0 1 4 2 — 4 7 0 1 — 0 4 5 1 — 3 1 0 1 10 4 7 7 |4 |6 |3 |4 4 7 4 3 0 3 2 4 — 0 4 — |3 |7
Выделенные жирным шрифтом числа в исходной матрице - это идеальный тур, полученный лексикографическим перебором. Отметим, что сумма констант приведения есть 4 + 6 + 3 + 4 + 3 + 7 = 27 А затем по столбцам: — 0 1 4 0 — 2 5 0 1 — 0 3 4 0 — 3 1 0 1 6 0 3 3 4 7 — 0 2 1 — 2 0 3 — 0 1 3 — 1 — 0 0 — — 4 Отметим, что сумма констант приведения здесь есть 0 + 2 + 0 + 1 + 0 + 4 = 7, а всех констант: 27 + 7 = 34
Теперь, тур, проходящий только через ребра нулевой стоимости, будет, очевидно, минимальным. Для того, чтобы определить его стоимость, прибавим к нулю только что вычисленную константу 34: 0 + 34 = 34 Т. о. , мы получили нижнюю оценку стоимости класса всех возможных туров. Т. е. минимальный тур в данной задаче не может стоить меньше, чем 34.
Назовем оценкой нуля в позиции (i, j) в матрице сумму минимальных элементов в i-й строке и j-м столбце (не считая сам этот ноль). Оценим теперь каждый ноль в приведенной матрице: 1 2 3 4 5 6 1 2 — 01 01 — 0 1 3 4 3 1 6 0 3 4 5 6 1 4 4 7 2 5 2 1 — 01 0 3 01 — 1 3 0 1 — 01 3 3 0 —
следующее: если в тур не будет включен путь из i в j (стоимостью 0), то придется доплатить как минимум k. Поэтому, можно разделить класс всех возможных туров на два: туры, содержащие ребро (i, j) и туры, не содержащие его. Для последних минимальная оценка увеличится на k. Рассмотрим ребро, соответствующее нулю с максимальной оценкой. В данном случае это ребро (1, 2). Таким образом, как только что было замечено, класс всех туров разбивается на два: содержащих ребро (1, 2) и не содержащих его. Нижняя оценка стоимости второго класса туров увеличивается до 35. Чтобы определить оценку для первого класса туров удалим из матрицы строку 1 и столбец 2 (Обозначим ее как C[(1, 2)]):
1 3 4 5 6 2 — 1 4 1 0 3 1 — 01 0 3 4 4 01 — 1 3 5 4 0 1 — 0 6 7 3 3 01 — а также попытаемся привести ее и заново оценить
1 3 4 5 6 2 — 1 4 1 01 3 4 5 6 03 3 3 6 — 01 0 3 01 — 1 3 0 1 — 03 3 3 0 — Т. к. матрицу удалось привести на 1 (по 1 -му столбцу), то оценка класса туров с ребром (1, 2) увеличивается на 1 и становится равной 35.
Разбиение на классы и сами оценки можно представить в виде дерева: Таким образом, класс (ВСЕ) был разбит на два и были вычислены соответствующие оценки.
Выберем теперь класс с наименьшей оценкой и повторим этот процесс для него. Затем из двух полученных классов выберем тот, у которого оценка минимальна и разобьем его. Так будем повторять до тех пор, пока не достигнем листа дерева. Т. е. пока не получим матрицу 0× 0 : C[(1, 2); [−](a 1, b 1); [−](a 2, b 2); … [−](ak, bk)] Где (каждое) −(x, y) означает, что матрица соответствует классу, не содержащему ребро (x, y) Удалив из обозначения матрицы элементы вида −(x, y), получим следующее: (c 0, d 0); (c 1, d 1); … (cn, dn)
Вершина (5, 4) дерева будет соответствовать классу, содержащему ребра: (1, 2); (3, 1); (6, 5); (2, 6); (4, 3); (5, 4). Этот класс, очевидно, состоит из одного полного тура (1, 2, 6, 5, 4, 3, 1) со стоимостью = 36 (для полного тура его минимальная оценка равна точной стоимости)
Запомним этот результат как рекордный и пройдем по дереву вверх, "вычеркивая" все вершины (т. е. исключая из дальнейшего рассмотрение все классы), оценки которых больше или равны только что найденной. Кроме того, будем вычеркивать вершину и в том случае, если у нее оба потомка вычеркнуты, несмотря на ее оценку. Получим следующее:
Матрица, соответствующая классу туров, не содержащих ребро (1, 2), приведенная по второму столбцу, будет выглядеть так: 1 2 3 4 5 6 1 2 3 — 01 1 — — 1 03 1 — 3 4 01 3 1 0 6 0 3 4 5 6 4 4 7 4 1 01 01 0 3 — 1 3 1 — 0 3 0 — Она была получена из матрицы, соответствующей классу всех туров путем установки прочерка (обозначающего бесконечную стоимость перелета) вместо элемента (1, 2). Т. е. с1, 2 = ∞. Обозначим ее как C[−(1, 2)] Т. к. максимальная оценка нуля 3 (элемент 1, 3) получаем, что оценка для ветви −(1, 3) равна 38.
Вычеркивая первую строку и первый столбец, получим матрицу, приводимую на 1 по четвертой строке. То есть оценка ветви −(1, 2)(1, 3) становится равной 36. Дальнейшее ветвление будем продолжать уже с учетом найденного рекордного значения (36): Продолжать далее смысла нет, т. к. у потомков вершины −(1, 2) оценки снизу выше рекорда, т. е. их надо тоже исключить. Класс ВСЕ тоже удаляется, т. к. оба его потомка вычеркнуты.
Т. о. , вершин не осталось, перебор завершен. Найденное в ходе него рекордное значение и соответствующий ему тур — решение задачи.
Удовлетворительных теоретических оценок алгоритма Литтла и ему подобных нет, но практика показывает, что на современных машинах они позволяют решать задачу коммивояжера с количеством вершин ≈ 100. Кроме того, алгоритмы типа ветвей и границ являются эффективными эвристическими процедурами. Если нет возможности доводить их до конца.
Пример. Применяя метод ветвей и границ, решить задачу коммивояжера с матрицей расстояний, заданной таблицей
Результатом вычислений будет таблица, в которой добавлены строка и столбец с минимальными элементами
Алгоритм Литтла - Пример 1 Необходимо найти оптимальный маршрут коммивояжера в графе представленом на рисунке: Пронумеруем вершины исходного графа, и составим матрицу длин кратчайших дуг между каждой парой вершин D 0, в случае, если дуги между вершиной i и j не существует, элементу di, j матрицы присваивается значение ∞. Исходный граф с пронумероваными вершинами представлен на рисунке ниже.
В основе метода ветвей и границ лежит следующая идея (для задачи минимизации): если нижняя граница для подобласти A дерева поиска больше, чем верхняя граница какой-либо ранее просмотренной подобласти B, то A может быть исключена из дальнейшего рассмотрения (правило отсева). Обычно, минимальную из полученных верхних оценок записывают в глобальную переменную m; любой узел дерева поиска, нижняя граница которого больше значения m, может быть исключен из дальнейшего рассмотрения. Если нижняя граница для узла дерева совпадает с верхней границей, то это значение является минимумом функции и достигается на соответствующей подобласти.
Алгоритм Литтла - метод решения задачи коммивояжера Алгоритм Литтла применяют для поиска решения задачи коммивояжера в виде гамильтонова контура. Данный алгоритм используется для поиска оптимального гамильтонова контура в графе, имеющем N вершин, причем каждая вершина i связана с любой другой вершиной j двунаправленной дугой. Каждой дуге приписан вес Сi, j, причем веса дуг строго положительны (Сi, j≥ 0). Веса дуг образуют матрицу стоимости. Все элементы по диагонали матрицы приравнивают к бесконечности (Сj, j=∞). В случае, если пара вершин i и j не связана между собой (граф не полносвязный), то соответствующему элементу матрицы стоимости приписываем вес, равный длине минимального пути между вершинами i и j. Если в итоге дуга (i, j) войдет в результирующий контур, то ее необходимо заменить соответствующим ей путем. Матрицу оптимальных путей между всеми вершинами графа можно получить применив алгоритм Данцига или Флойда.
Пример 2. Задача коммивояжера ("двойной выбор") Простейшее преобразование, которым можно воспользоваться в симметричной задаче коммивояжера, является так называемый"двойной выбор". Он заключается в том, что мы выбираем любые два ребра (например (a, b) и (c, d)), удаляем их и "перекоммутируем" соединявшиеся ими точки так, чтобы образовался новый маршрут. Если сумма стоимостей двух новых ребер оказалась меньше, чем двух старых, то мы нашли улучшенный маршрут.
Рассмотрим тот же граф, для которого мы строили остовное дерево. Выберем в качестве начального маршрута (a, b, c, d, e) и применим к нему "двойной выбор". Легко убедиться, что на рисунке "в" нельзя удалить ни одну пару ребер, выгодно заменив её другой.
Двойной выбор можно обобщить на k-выбор. В этом случае мы удаляем до k ребер и "перекоммутируем" оставшиеся элементы в любом порядке, пытаясь получить маршрут. Мы, вообще говоря, не требуем, чтобы удаляемые ребра были несмежными. Легко убедиться в том, что количество различных преобразований, которые нужно рассмотреть при kвыборе равно O (|V|k). Однако время, требуемое для получения какого-либо оптимального маршрута, может оказаться значительно больше. На практике очень эффективным является "выбор с переменной глубиной". Он с большой вероятностью обеспечивает получение оптимального маршрута для |V| = 40 − 100.
Приближенные и эвристические методы В этом разделе мы рассмотрим алгоритмы, работающие за известное нам полиномиальное время и решающие "переборные" задачи с некоторой известной нам ошибкой. Грань между приближенными и эвристическими методами размыта. Некоторые выделяют как приближенные алгоритмы те, в которых возможно регулировать погрешность, т. е. схемы приближения. В эвристических методах для выбора элементов решения используются те или иные, кажущиеся естественными рекомендательные правила выбора, эвристики. Часто такие правила комбинируются с условием жадности выбора: сделанный выбор в дальнейшем не пересматривается. Более мощной разновидностью такого подхода является сокращенный поиск, в котором дерево вариантов, знакомое нам по методу ветвей и границ, искусственно сокращается исходя из некоторых правил, правдоподобных, но формально не
Пример 1. Задача коммивояжера (деревянный алгоритм) Рассмотрим три эвристических алгоритма, решающих симметричную задачу коммивояжера с неравенством треугольника с ошибкой не более чем в два раза (ρ = 2). Первый из них, так называемый деревянный алгоритм, состоит в следующем: построим для нашего графа минимальное покрывающее дерево с помощью алгоритма Прима, а затем совершим обход дерева в порядке root-left-right, удаляя повторяющиеся вершины. Время работы этого алгоритма равно Θ(E) = Θ(V 2).
Пример 1. Задача коммивояжера (жадный алгоритм и алгоритм Карга-Томпсона) Самый очевидный алгоритм решения задачи коммивояжера — жадный: из текущего города иди в ближайший из тех, куда ещё не ходил. Если выполняется неравенство треугольника, нетрудно доказать, что этот алгоритм ошибается не более, чем в два раза. Трудоемкость этого алгоритма O(V 2). Алгоритм Карга-Томпсона (эвристика ближайшей точки) чуть менее очевиден: сначала возьмем две ближайшие вершины (вырожденный тур), затем в цикле по всем ребрам уже построенного тура для каждого ребра (u, v) выберем из свободных вершин такую w, чтобы c(u, w) + c(w, v) − c (u, v) было минимальным и включим w в тур между u и v. Для этого способа также ρ= 2, однако его трудоемкость составляет уже O(V 3).
Пример 2. Задача о вершинном покрытии Напомним, что вершинным покрытием неориентированного графа G=(V, E) мы называем некоторое семейство его вершин V′ с таким свойством: для всякого ребра (u, v) графа G хотя бы один из его концов u или v содержится в V′. Размером вершинного покрытия считаем количество входящих в него вершин. Задача о вершинном покрытии состоит в нахождении вершинного покрытия минимального размера. Эта задача NP-трудна, однако приведенный ниже простой алгоритм решает её с ошибкой не более, чем в два раза. Пусть С — это уже построенная часть вершинного покрытия, а E′ содержит непокрытые ребра графа. На каждом шаге мы берем ребро из E′ и добавляем его концы u и v в C, а из E′ изымаем все ребра имеющие своим концом u или v. И так пока множество E′ не станет пустым.
Алгоритм Предположим, что задан полный граф. Будем перебирать все ребра графа в порядке возрастания их весов и для каждого ребра проверять два условия: 1) в результате добавления данного ребра к ранее выбранным ребрам не образуется цикл, если это не завершающее ребро пути (для завершающего ребра будет получен цикл, который проходит через все вершины графа); 2) добавляемое ребро после добавления к ранее выбранным ребрам не будет являться третьим ребром, выходящим из некоторой вершины. Если для ребра выполняются эти два условия, то оно добавляется к ранее выбранному множеству ребер.
Пример решить задачу коммивояжера для графа.
Жадный приближенный алгоритм сначала выберет ребро (1, 2), затем ребро (2, 4) и присоединит их к выбранному множеству ребер. Следующим ребром минимального веса будет ребро (1, 4), но оно будет отвергнуто, т. к. для него не выполняется пункт 1) из условий присоединения ребер и оно не является завершающим ребром пути (цикл не проходит через все вершины графа). 1→ 3→ 2→ 1 Последующее ребро (2, 3) также будет отвергнуто, т. к. для него не выполняется 2) пункт из условий присоединения, т. е. из вершины 2 в этом случае выходило бы три ребра. Последующее ребро (1, 3) успешно присоединяется. И, наконец, присоединяется последнее ребро пути (4, 3). Оно является завершающим ребром пути, и полученный цикл проходит через все вершины графа.
Данный алгоритм сгенерировал путь стоимости 106 Это решение не является оптимальным: есть, по крайней мере, один более короткий путь стоимостью 104.
Л10 ПРИМЕРЫ КОММИВ и др.ppt