Задача о покрытии множествами
Пусть дано конечное множество \(U\) из \(n\) элементов, набор его подмножеств \(\mathcal{S}=\left\{ S_{1}, \ldots , S_{k}\right\} \subset 2^U\). В частности, если \(\left|S_i\right| = 2, \; \forall i\), то \((U, \mathcal{S})\) – это неориентированный граф. Поднабор \(\mathcal{S}^{\prime } \subseteq \mathcal{S}\) называется покрытием, если любой элемент из \(U\) принадлежит хотя бы одному элементу из \(\mathcal{S}^{\prime }\). Т.е.
\[ \bigcup _{S \in \mathcal{S}'}S = U \]
Задача о покрытии множествами минимальной мощности
Конечное множество \(U\) из \(n\) элементов, набор его подмножеств \(\mathcal{S} \subset 2^U\).
Минимальное по мощности покрытие из \(\mathcal{S}\).
Задача о покрытии множествами минимальной мощности
Универсум \(U\) из 9 элементов и семейство \(\mathcal S=\{S_1,\dots,S_6\}\) перекрывающихся подмножеств. Наведите курсор на подпись множества, чтобы выделить его и увидеть элементы; на точку — чтобы узнать, в какие множества она входит.
Обобщение данной задачи – задача о покрытии множествами минимального веса. Мы будем ее рассматривать.
Задача о покрытии множествами минимального веса
Конечное множество \(U\) из \(n\) элементов, набор его подмножеств \(\mathcal{S} \subset 2^U\) и веса подмножеств \(c: \mathcal{S} \rightarrow \mathbf{Q}^{+}\).
Минимальный по весу поднабор из \(\mathcal{S}\), покрывающий множество \(U\).
Задача о покрытии множествами минимального веса
Та же конфигурация \(U,\mathcal S\), но каждому множеству \(S_i\) приписан вес \(c(S_i)\) (число под подписью). Наведите курсор на подпись множества, чтобы выделить его.
1 Жадный алгоритм для задачи о покрытии множествами
В 1979 году чешский математик Вацлав Хватал предложил жадный алгоритм для задачи о покрытии множествами.
На каждой итерации выбираем самое эффективное множество, удаляем покрытые элементы и продолжаем до тех пор, пока не будут покрыты все элементы. Пусть \(C\) – это множество элементов, уже покрытых на предыдущих итерациях. Для каждого множества \(S_{i}\) определим его эффективность как \(\alpha_{i}=\frac{c\left(S_{i}\right)}{\left|S_{i} \setminus C\right|}\). Эффективность множества равна средней стоимости, с которой покрываются элементы этого множества, еще не покрытые на предыдущих итерациях. Ценой элемента назовем среднюю стоимость, с которой он был покрыт. Для всех вновь покрытых элементов множества \(S_{i}\) цена будет одинаковой.
Для натурального \(n \in \mathbb {N}\) обозначим
\[ H_n := 1 +\frac{1}{2}+\frac{1}{3}+\ldots +\frac{1}{n} \]
частичную сумму гармонического ряда. Заметим, что \(H_n = \ln n + \gamma + o(1)\), где \(\gamma \approx 0.577\) – постоянная Эйлера; в частности, \(\ln n < H_n \leq \ln n + 1\).
Точный пример к алгоритму Хватала
\(n\) одноэлементных множеств с весами \(\frac1n,\frac1{n-1},\dots,1\) внутри одного множества веса \(1+\varepsilon\), содержащего все элементы. На каждой итерации жадный алгоритм берёт множество с наименьшей ценой за непокрытый элемент — и это всегда очередное одноэлементное множество: его цена \(\frac1{n-i+1}\) чуть меньше цены большого, \(\frac{1+\varepsilon}{n-i+1}\). Пройдите итерации кнопками или задайте \(n\).
Можно ли получить лучший алгоритм? Нет: задача покрытия множествами не может быть аппроксимирована с коэффициентом \((1 - o(1))\ln (n)\).
2 Задача о вершинном покрытии наименьшего веса
2.1 Использование алгоритма для покрытия множествами
Заметим, что задача о вершинном покрытии наименьшего веса (в частности, наименьшей мощности) является частным случаем задачи о покрытии множествами. Действительно, пусть задан граф \(G=(V, E)\), и требуется найти вершинное покрытие минимального веса. Можно построить следующий экземпляр задачи о покрытии множествами:
Универсум \(U\) сопоставим с множеством рёбер \(E\), т.е. \(U = E\).
Каждая вершина \(v \in V\) соответствует множеству \(S_v \subseteq U\), состоящему из всех рёбер, инцидентных вершине \(v\).
Функция стоимости \(c: S_v \mapsto \text{вес вершины } v\).
Тогда любое покрытие множествами \(S' \subseteq \{ S_v : v \in V\}\), покрывающее \(U\), соответствует выбору вершин \(V' \subseteq V\), образующих вершинное покрытие графа. Минимизация суммарного веса выбранных множеств \(S'\) эквивалентна минимизации веса вершинного покрытия.
Заметим, что жадный алгоритм для задачи о вершинном покрытии наименьшей мощности – это частный случай алгоритма Хватала. Таким образом, у нас есть его оценка точности: \(H_{\tilde{n}}\), где \(\tilde{n}\) – это максимальная степень вершины в \(G\).
2.2 Алгоритмы константной точности через расщепление весов графа
Во введении мы получили алгоритм для задачи о вершинном покрытии наименьшей мощности с фиксированной точностью, равной \(2\). Будет ли он работать с такой же точностью, но для более общей задачи, т.е. задачи о покрытии наим. веса? Нет!
Покрытие наименьшего веса не сводится к покрытию наименьшей мощности
Один и тот же граф на 7 вершинах: сначала без весов и его минимальное по мощности покрытие, затем с весами вершин — и покрытие меньшего веса, но большей мощности. Наведите курсор на вершину, чтобы увидеть её вес.
2.2.1 Алгоритм локальных весов
От англ. local ratio algorithm.
Идея алгоритма локальных весов: расщепление \(w=w_1+w_2\)
Выбираем ребро \(\{v,v'\}\), инцидентное самой дешёвой вершине, и вычитаем \(c=\min(w(v),w(v'))\) с обоих его концов: \(w_1\) сосредоточен на этих двух вершинах (по \(c\) на каждой, остальное — 0), а \(w_2=w-w_1\) — исходный граф с уменьшенными весами. Любое покрытие графа \((V,E,w_1)\) — 2-приближение: хотя бы одну из двух вершин ребра покрыть придётся. Наведите курсор на вершину, чтобы проследить её вес по трём панелям.
Полный прогон алгоритма локальных весов
На каждом шаге \(i\) алгоритм берёт ребро, инцидентное самой дешёвой из ещё ненулевых вершин, и вычитает \(c\) с обоих его концов — вес \(t_i\) сосредоточен на этих двух вершинах. После 5 шагов остаток \(t_6\) отмечает обведённые вершины — это решение алгоритма. Наведите курсор на вершину, чтобы увидеть её остаток.
2.2.2 Уровневый алгоритм
Второй способ расщеплять веса: делать это глобально, а не для каждого ребра по отдельности.
Назовем функцию \(w: V \to \mathbb {Q}_+\), соответствующую весам вершин, пропорционально-степенной, если существует константа \(c>0\), такая, что вес каждой вершины \(v \in V\) равен \(w(v) = c \cdot \operatorname {deg}(v)\).
Уровневый алгоритм: другой способ расщепления весов
Глобальное вычитание пропорционально степени вершины: \(c=\min_v w(v)/\deg(v)=3{,}5\) (достигается на вершине \(ML\), \(\deg=4\)), поэтому \(w_1(v)=c\cdot\deg(v)\) для каждой вершины, а \(w_2=w-w_1\) — остаточная функция (на \(ML\) остаток равен \(0\)). Наведите курсор на вершину: степень и все три веса.
Пусть \(w: V \rightarrow \mathbf{Q}^{+}\) – произвольная функция. Определим наибольшую пропорционально-степенную функцию относительно \(w\) в графе \(G\) следующим образом:
Удалим из графа все вершины степени 0;
Среди оставшихся вершин вычислим величину \(c=\min \left\{ \frac{w(v)}{\operatorname {deg}(v)}\right\}\).
Тогда функция \(t(v)=c \cdot \operatorname {deg}(v)\) – искомая.
Определим через \(w^{\prime }(v)=w(v)-t(v)\) остаточную функцию весов.
Представим алгоритм, который разбивает исходную весовую функцию на пропорционально-степенные функции и строит вершинное покрытие.
2.2.3 Оценки точности
Приведем пример, на котором достигается эта оценка. Пусть задан полный двудольный граф \(K_{n, n}\), в котором все вершины имеют единичные веса. Алгоритм Уровневый возьмет в покрытие все \(2n\) вершин графа \(K_{n, n}\), тогда как оптимальное решение состоит из вершин одной доли.