Уточнение разбиения

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

При разработке алгоритмов уточнение разбиения — это метод представления разбиения множества в виде структуры данных, которая позволяет разбивать его множества на большее количество меньших множеств. В этом смысле уточнение разбиения двойственно системе непересекающихся множеств, которая также поддерживает разбиение на непересекающиеся множества, но в которой операции объединяют пары наборов. В некоторых приложениях уточнения разбиения, таких как лексикографический поиск в ширину, структура данных поддерживает также порядок наборов в разделе.

Уточнение разбиения является ключевым компонентом нескольких эффективных алгоритмов на графах и конечных автоматах, включая минимизацию ДКА, алгоритм Коффмана – Грэма для параллельного планирования и лексикографический поиск в ширину.[1][2][3]

Структура данных[править | править код]

Алгоритм уточнения разбиения поддерживает семейство непересекающихся множеств Si . В начале алгоритма это семейство содержит единственное множество всех элементов в структуре данных. На каждом шаге алгоритм получает множество X, и каждое множество Si в семействе, содержащем элементы X, разбивается на два множества: пересечение SiX и разность Si \ X

Этот алгоритм может быть эффективно реализован с помощью структур данных, представляющих следующую информацию:[4][5]

  • Упорядоченная последовательность множеств Si в семействе в такой форме, как двусвязный список, который позволяет вставлять новые наборы в середину последовательности.
  • Соответствующая каждому множеству Si коллекция его элементов, организованная как двусвязный список или массив, чтобы обеспечить возможность быстрого удаления отдельных элементов из коллекции. Альтернативно этот компонент структуры данных может быть представлен путем хранения всех элементов всех множеств в одном массиве, отсортированном по идентификатору множества каждого элемента, или путем представления коллекции элементов в любом множестве Si по его начальной и конечной позициям в этом массиве.
  • С каждым элементом связан набор, к которому он принадлежит.

Чтобы выполнить операцию уточнения, алгоритм перебирает элементы данного множества X. Для каждого такого элемента x он находит множество Si которое содержит x, и проверяет, произведено ли пересечение SiX. Если нет, он создает второе множество и добавляет Si в список L множеств, разделенных операцией. Затем, независимо от того, было ли сформировано новое множество, алгоритм удаляет x из Si и добавляет его к SiX В представлении, в котором все элементы хранятся в одном массиве, перемещение x из одного множества в другое может выполняться путем обмена x местами c последним элементом Si а затем уменьшения концевого индекса Si и начального индекса нового множества. Наконец, после того, как все элементы X были обработаны таким образом, алгоритм проходит через L, разделяя каждое текущее множество Si на два, рассматривая оба этих множества как сформированные в результате операции уточнения.

Оценка времени для выполнения одной операции уточнения таким образом составляет O(|X|), независимо от количества элементов в семействе множеств, а также независимо от общего количества множеств в структуре данных. Поэтому время исполнения последовательности уточнений пропорционально общему размеру множеств, заданных алгоритму на каждом этапе уточнения.

Применение[править | править код]

Одно из первых применений уточнение разбиения нашло в алгоритме Хопкрофта для минимизации ДКА[6]. В этой задаче на входе задается детерминированный конечный автомат, и он должен найти эквивалентный автомат с как можно меньшим количеством состояний. Алгоритм Хопкрофта поддерживает разделение состояний входного автомата на подмножества с тем свойством, что любые два состояния в разных подмножествах должны отображаться в разные состояния выходного автомата. Изначально существует два подмножества, одно из которых содержит все принимающие состояния автомата, а другое — остальные. На каждом шаге выбираются одно подмножество Si и один из входных символов x автомата, и подмножества состояний уточняются до состояний, для которых переход, помеченный x, приведет в Si, и состояний, для которых x приведет в другое место. Когда выбранное множество Si разделяется уточнением, только одно из двух результирующих множеств (меньшее из двух) нужно рассмотреть снова; таким образом, каждое состояние участвует в множествах X в течение O(s log n) шагов уточнения, а общая оценка времени алгоритма составляет O(ns log n), где n — количество начальных состояний, а s — размер алфавита.[6]

Уточнение разделения было применено Sethi[7] в эффективной реализации алгоритма Коффмана — Грэма для параллельного планирования. Сетхи показал, что его можно использовать для построения лексикографически упорядоченной топологической сортировки заданного ориентированного ациклического графа за линейное время; такое лексикографическое топологическое упорядочение является одним из ключевых шагов алгоритма Коффмана — Грэма. В этом приложении элементы непересекающихся множеств являются вершинами входного графа, а множества X используемые для уточнения разбиения, являются множествами соседей вершин. Поскольку общее количество соседей всех вершин — это просто количество ребер в графе, алгоритм требует времени, линейного по количеству ребер.

Уточнение разбиения также является ключевым этапом в лексикографическом поиске в ширину, алгоритме поиска по графу с приложениями для распознавания хордовых графов и некоторых других важных классов графов. В этих случаях элементы непересекающихся множеств являются вершинами, а множество X представляет собой множества точек окрестности, поэтому алгоритм занимает линейное время.[8][9]

См. также[править | править код]

Примечания[править | править код]

  1. Paige, Robert; Tarjan, Robert E. (1987), "Three partition refinement algorithms", SIAM Journal on Computing, 16 (6): 973—989, doi:10.1137/0216062.
  2. Habib, Michel; Paul, Christophe (1999), "Partition refinement techniques: an interesting algorithmic tool kit", International Journal of Foundations of Computer Science, 10 (2): 147—170, doi:10.1142/S0129054199000125.
  3. Habib, Michel; Paul, Christophe (1998), STACS 98: 15th Annual Symposium on Theoretical Aspects of Computer Science Paris, France, February 25–27, 1998, Proceedings, vol. 1373, pp. 25—38, doi:10.1007/BFb0028546.
  4. Valmari, Antti; Lehtinen, Petri (2008), "Efficient minimization of DFAs with partial transition functions", in Albers, Susanne; Weil, Pascal (eds.), 25th International Symposium on Theoretical Aspects of Computer Science (STACS 2008), Leibniz International Proceedings in Informatics (LIPIcs), vol. 1, Dagstuhl, Germany: Schloss Dagstuhl: Leibniz-Zentrum fuer Informatik, pp. 645—656, doi:10.4230/LIPIcs.STACS.2008.1328, ISBN 978-3-939897-06-4, Архивировано из оригинала 18 июля 2021, Дата обращения: 23 сентября 2021
  5. Knuutila, Timo (2001), "Re-describing an algorithm by Hopcroft", Theoretical Computer Science, 250: 333—363, doi:10.1016/S0304-3975(99)00150-4
  6. 1 2 Hopcroft, John (1971), "An n log n algorithm for minimizing states in a finite automaton", Theory of machines and computations (Proc. Internat. Sympos., Technion, Haifa, 1971), New York: Academic Press, pp. 189—196 {{citation}}: templatestyles stripmarker в |contribution= на позиции 4 (справка).
  7. Ravi Sethi. Scheduling Graphs on Two Processors (англ.) // SIAM Journal on Computing. — 1976-03. — Vol. 5, iss. 1. — P. 73–82. — ISSN 1095-7111 0097-5397, 1095-7111. — doi:10.1137/0205005. Архивировано 4 ноября 2021 года.
  8. Rose, D. J.; Tarjan, R. E.; Lueker, G. S. (1976), "Algorithmic aspects of vertex elimination on graphs", SIAM Journal on Computing, 5 (2): 266—283, doi:10.1137/0205021.
  9. Corneil, Derek G. (2004), Graph-Theoretic Methods in Computer Science: 30th International Workshop, WG 2004, Bad Honnef, Germany, June 21-23, 2004, Revised Papers, vol. 3353, pp. 1—19, doi:10.1007/978-3-540-30559-0_1.

Литература[править | править код]