Комбинаторика играет важную роль в информатике. Мы часто используем комбинаторные методы как в анализе, так и в алгоритмах. Например, один из методов нахождения покрытия графа вершины в графе может просто проверить все \ binom {n} {k} возможных подмножеств. В то время как биномиальные функции растут экспоненциально, если k является некоторой фиксированной константой, мы получаем алгоритм полиномиального времени с помощью асимптотического анализа. к
Часто реальные проблемы требуют более сложных комбинаторных механизмов, которые мы можем определить с точки зрения повторений. Один известный пример - последовательность Фибоначчи (наивно), определенная как:
Теперь вычисление значения го члена растет экспоненциально с использованием этого повторения, но благодаря динамическому программированию мы можем вычислить его за линейное время. Теперь, не все рецидивы поддаются DP (от руки, факториальная функция), но это потенциально эксплуатируемое свойство при определении некоторого количества как рекуррентности, а не производящей функции.
Генерация функций - это элегантный способ формализовать некоторый счет для данной структуры. Возможно, самой известной является биноминальная производящая функция, определяемая как:
К счастью, это решение в закрытой форме. Не все производящие функции допускают такое компактное описание.
Теперь мой вопрос заключается в следующем: как часто генерирующие функции используются при разработке алгоритмов? Легко понять, как их можно использовать для понимания скорости роста, требуемой алгоритмом посредством анализа, но что они могут сказать нам о проблеме при создании метода для решения какой-то проблемы?
Если много раз один и тот же счет может быть переформулирован как повторение, он может использоваться для динамического программирования, но, опять же, возможно, одна и та же генерирующая функция имеет закрытую форму. Так что это не так равномерно.
источник
Ответы:
Генерация функций полезна при разработке алгоритмов подсчета. То есть не только когда вы ищете количество объектов, имеющих определенное свойство, но и когда вы ищете способ перечислить эти объекты (и, возможно, сгенерировать алгоритм для подсчета объектов). В главе 7 « Конкретной математики » есть очень хорошая презентация Рональда Грэма, Дональда Кнута и Орен Паташник . Приведенные ниже примеры взяты из этих книг (ошибки и отсутствие ясности - мои).
Предположим, что вы ищете способы внести изменения с помощью данного набора монет. Например, с обычными номиналами в США¹ возможны монеты . Чтобы дать ¢ 42 в изменении, одна возможность - ; другая возможность - . Мы напишем . В более общем смысле, мы можем написать производящую функцию для всех способов изменения: В более технических терминах - это термин в пространстве степенных рядов над пятью переменными[ 25 ] [ 10 ] [ 5 ] [ 1 ] [ 1 ] [ 10 ] [ 10 ] [ 10 ] [ 10 ] [ 1 ] [ 1 ] 42 ⟨ [ 25 ] [ 10 ][ 1 ] , [ 5 ] , [ 10 ] , [ 25 ] , [ 100 ] [ 25 ] [ 10 ] [ 5 ] [ 1 ] [ 1 ] [ 10 ] [ 10 ] [ 10 ] [ 10 ] [ 1 ] [ 1 ] Н = Σ ч ≥ 0 Σ Q ≥ 0 Σ d ≥ 0 Σ п ≥ 0 Σ р ≥ 0 [ 100 ] ч [ 25 ] д [ 10 ] d [ 5 ] n [ 1 ] p42 ⟨ [ 25 ] [ 10 ] [ 5 ] [ 1 ]2⟩ = ⟨ [ 10 ]4[ 1 ]2⟩
Более сложный пример: предположим, что вы хотите изучить все способы разбиения прямоугольников на 2 × 1 домино. Например, существует два способа наложить прямоугольник 2 × 2, либо с двумя горизонтальными домино, либо с двумя вертикальными домино. Подсчет количества способов разбить прямоугольник довольно прост, но случай быстро становится неочевидным. Мы можем перечислить все возможные наклоны горизонтальной полосы высотой 3, склеив домино вместе, что быстро дает повторяющиеся шаблоны:2 × n 3 × n
Снова, прочитайте Конкретную Математику для менее спешащего представления
¹ Я знаю , что мой список является неполным; предположим, что для математических примеров используется упрощенный метод США.
² Кроме того, если это подходит, предположим, что сферические монеты.
³ И лучше набрать текст.
источник
Я помню проблему, которую мне пришлось решить во время студенческого конкурса по программированию в 2001 году. Проблема была в следующем:
Я начал с вложенных циклов, но быстро ударил стену. Затем я осознал, что мне нужно начать с перечисления того, что можно сделать с более легкими массами, прежде чем перейти к более тяжелым. Я мог бы решить эту проблему с помощью множества неопубликованных циклов.
Если бы я не был высокомерным и самодостаточным в то время (и знал бы я и практиковал генерирование функций), я мог бы определить проблему с генерацией функций как таковую:
Определите как OGF для количества способов, которым вес может быть взвешен, учитывая набор масс.е( х ) N
Какой вес на правой чашке я могу весить, учитывая одну массу 1?
Три возможности:
Таким образом, существует один способ взвешивания , один способ взвешивания и один способ взвешивания . Производящая функция для этой массы имеет вид , что соответствует:- 1 0 1 Икс- 1+ 1 + х
Производящая функция для одной массы имеет вид , который равен:м Икс- м+ 1 + хм
Для заданного мультимножества масс выражается как произведение функций, генерирующих одну массу:M е
Теперь, учитывая пакет, который может выполнять операции над полиномами, вам просто нужно:
И вы сделали. Теперь у вашего полинома есть множество способов взвешивания по индексу . Только вход является мультимножеством масс .w ≥ 0 вес M
Я разработал алгоритм с использованием математически обоснованных компонентов. Основная часть алгоритма, представляющая собой полиномиальное деление с наименьшей первой степенью, является линейной и может быть реализована с помощью готового пакета. Это может быть не оптимально, но, безусловно, работает лучше, чем я делал на конкурсе, и менее подвержено ошибкам.
Если вы внимательно посмотрите на процесс деления, вы быстро увидите, что остаток можно рассматривать как «текущее скрытое состояние» в каждом состоянии процесса, а частное - как результат. Процесс завершается, когда «текущее скрытое состояние» везде достигает нуля.
Вы можете реализовать полиномы как массивы или, если они действительно очень редки, как упорядоченные списки с индексным коэффициентом, и это не изменит алгоритм.
источник
При разработке алгоритма монотонной субмодульной максимизации на матроиде мы должны были решить рецидив Заметив, что , мы сократили задачу до вычисления некоторой универсальной последовательности . Последнее было выполнено с использованием производящих функций, и оттуда мы получили явную формулу для , снова используя производящие функции. Вы можете найти решение в газете, если вам интересно, хотя мы никогда не удосужились включить этот вывод.
источник
Возможно, самым ярким примером является обширное изучение быстрой сортировки и ее многочисленных вариантов. Там комбинаторные соображения регулировали рассмотрение альтернатив, и анализ решений довольно сложных уравнений показывает преимущества производительности (или нет) из них.
источник