Вопрос

Комбинаторика играет важную роль в информатике. Мы часто используем комбинаторные методы как в анализе, так и в проектировании в алгоритмах. Например, один метод поиска набора покрытий $ k $ -vertex в графике может просто осмотреть все $ binom {n} {k} $ возможные подмножества. В то время как биномиальные функции растет в геометрической прогрессии, если $ k $ является какой -то фиксированной постоянной, мы заканчиваем алгоритмом полиномиального времени с помощью асимптотического анализа.

Часто реальные проблемы требуют более сложных комбинаторных механизмов, которые мы можем определить с точки зрения рецидивов. Одним из известных примеров является Последовательность Фибоначчи (наивно) определяется как:

$ f (n) = begin {case} 1 & text {if} n = 1 0 & text {if} n = 0 f (n-1) + f (n-2) & Текст {иной} end {case} $

Теперь вычисление стоимости $ n $ th -члена растут в геометрической прогрессии, используя этот рецидив, но благодаря динамическому программированию мы можем вычислить его в линейное время. Теперь не все рецидивы поддаются DP (вне рук, факториальная функция), но это потенциально используемое свойство при определении некоторого счета как рецидив, а не генерирующую функцию.

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

$ (x + y)^ alpha = sum_ {k = 0}^ infty binom { alpha} {k} x^{ alpha - k} y^k $

К счастью, это имеет решение закрытой формы. Не все генерирующие функции позволяют такому компактному описанию.

Теперь мой вопрос: как часто генерируют функции, используемые в дизайн алгоритмов? Легко увидеть, как их можно использовать, чтобы понять скорость роста, требуемое алгоритмом с помощью анализа, но что они могут рассказать нам о проблеме при создании метода для решения какой -то проблемы?

Если во многих случаях один и тот же счет может быть переформулирован как рецидив, он может поддаваться динамическому программированию, но опять же, возможно, та же самая генерирующая функция имеет закрытую форму. Так что это не так равномерно.

Это было полезно?

Решение

Генерация функций полезна при разработке алгоритмов подсчета. То есть не только когда вы ищете количество объектов, имеющих определенное свойство, но и когда вы ищете способ перечислять эти объекты (и, возможно, генерировать алгоритм для подсчета объектов). В главе 7 есть очень хорошая презентация Бетонная математика Рональд Грэм, Дональд Кнут и Орен Паташник. Анкет Примеры ниже из этих книг (ошибки и отсутствие ясности - мои).

Предположим, что вы ищете способы внести изменения с помощью данного набора монет. Например, с обычными деноминациями США возможными монетами являются $ [1], [5], [10], [25], [100] $. Чтобы дать 42 в изменении, одна возможность - $ [25] [10] [5] [1] [1] $; Другая возможность - $ [10] [10] [10] [10] [1] [1] $. Мы напишем $ 42 Langle [25] [10] [5] [1]^2 rangle = langle [10]^4 [1]^2 rangle $. В целом, мы можем написать функцию генерирования для всех способов дать изменения: $$ H = sum_ {H ge0} sum_ {q ge0} sum_ {d ge0} sum_ {n ge0} sum_ {p ge0} [100]^h [25]^q [10]^d [5]^n [1]^p $$. За пять переменных $ [100], [25], [10], [5], [1] $. Определите оценку монома в этом пространстве $$ langle [100]^H [25]^Q [10]^d [5]^n [1]^p rangle = 100 H + 25 Q + 10 D + 5 N + P $$, тогда способы дать $ V $ центы в изменениях - это количество мономов, оценка которых составляет $ V $. Мы можем выразить $ H $ постепенно, сначала записав, как $ p $ даст изменения только в копейках, а затем способы, которые $ n $, чтобы внести изменения в копейки и никели, и так далее. ($ I $ не означает монеты.) $$ begin {Gather*} p = i + [1] + [1]^2 + [1]^3 + ldots = frac {i} {i - [1 ]} n = (i + [5] + [5]^2 + [5]^3 + ldots) p = frac {p} {i - [5]} d = (i + [ 10] + [10]^2 + [10]^3 + ldots) n = frac {n} {i - [10]} q = (i + [25] + [25]^2 + [ 25]^3 + ldots) d = frac {d} {i - [25]} h = (i + [100] + [100]^2 + [100]^3 + ldots) q = frac {q} {i - [100]} end {Gather*} $$, если вы хотите считать, а не просто перечислять способы внесения изменений, то есть простой способ использовать формальную серию, которую мы ve получено. Примените гомоморфизм $$ S: Quad [1] mapsto x, Quad [5] mapsto x^5, Quad [10] mapsto x^{10}, [25] mapsto x^{25} , [100] mapsto x^{100} $$ Коэффициент $ x^v $ в $ s (c) $ - это количество способов дать $ V $ центы в изменениях.

Более сложный пример: предположим, что вы хотите изучить все способы плитки прямоугольников с домино 2 × 1. Например, есть два способа плитки прямоугольника 2 × 2, либо с двумя горизонтальными домино, либо с двумя вертикальными домино. Подсчет количества способов плитки $ 2 Times N $ прямоугольник довольно прост, но случай $ 3 Times n $ быстро становится неочевидным. Мы можем перечислить все возможные уклоны горизонтальной полосы высоты 3, скрепив домино вместе, которые быстро дают повторяющиеся шаблоны: $$ begin {case} u = mathsf {o} + mathsf {l} v + mathsf { Gamma} lambda + mathord { aquiv} u v = supack { mathsf {i} strut} u + supack {= :-} V lambda = supac { strut mathsf {i}} u + supack {:- =} lambda end {case} $$, где смешные формы представляют элементарные домино не домино, $ mathsf {l} $ является вертикальным домино в верхней части левой части горизонтального домино, $ sub полоса высоты 3, $ supack {:- =} $-горизонтальный домино, выровненный с верхней частью полосы, плюс два горизонтальных домино под ним и один шаг вправо и т. Д. Здесь умножение представляет горизонтальное объединение и не является коммутативным, но есть уравнения между элементарными шаблонами, которые формируют переменные в этой серии мощности. Как и прежде с монетами, мы можем заменить $ x $ на каждый домино и получить серию генерирующей серии для количества пьес $ 3 times (2n/3) $ прямоугольник (то есть коэффициент $ x^{3k} $ Количество способов плитки прямоугольника площади $ 6k $, которая содержит 3K $ Dominoes и имеет ширину $ 2K $). Серия также может использоваться более универсальными способами; Например, путем различения вертикальных и горизонтальных домино мы можем подсчитать перевязки с помощью заданного количества вертикальных и горизонтальных домино.

Опять читайте Бетонная математика Для менее спешной презентации.

¹ Я знаю, что мой список неполный; Предположим, упростили нас, подходящие для математических примеров. Одни.
² Кроме того, если он появится, предположим, что сферические монеты.
³ И лучшая набора.

Другие советы

Я помню проблему, которую я должен был решить во время конкурса студенческого программирования в 2001 году. Проблема была этой:

Учитывая массы 1, 7, 13, ... (я не помню, какие массы, но был конечный, определенный набор масс), спроектируйте функцию, которая определяет, можно ли взвешивать заданный вес на масштабе с этим набор масс.

Я начал с вложенных петель, но быстро ударил по стене. Затем я понял, что должен был начать с перечисления того, что можно сделать с более легкими массами, прежде чем продолжить более тяжелые. Я мог бы решить проблему с большим количеством незамеченных петель.

Разве я не был молодым высокомерным и самодостаточным в то время (и если бы я знал о создании функций и практиковал), я мог бы определить проблему с созданием функций как таковых:

Определите $ f (x) $ как OGF для количества способов, которыми веса $ n $ может быть взвешен, учитывая набор масс.

Какой вес на правой кастрюле я могу весить, учитывая одну массу 1?

Три возможности:

  • Если я положу массу на левую кастрюлю, я могу весить 1.
  • Если я положу массу на правую кастрюлю, я могу весить -1.
  • Если я не использую массу, я могу весить 0.

Таким образом, есть один из способов весить $ -1 $, один из способов весить 0 $, и один из способов весить 1 доллар. Функция генерирования для этой массы-это примерно $ x^{-1} + 1 + x $, что соответствует:

$$ frac {1 - x^3} {x (1 -x)} $$

Функция генерирования для одной массы $ M $ равно $ x^{-m} + 1 + x^m $, что:

$$ frac {1 - x^{3m}} {x^m (1 -x^m)} $$

Учитывая мультисетские $ m $ масс, $ f $ выражается в качестве продукта функций единого массового генерирования:

$$ f (x) = frac { prod_ {m in m} (1 - x^{3m})} {x^{ sum_ {m in m} m} prod_ {m in m} (1 - x^{m})} $$

Теперь, учитывая пакет, который может выполнять операции на полиномах, вам просто нужно:

  • Рассчитайте оба продукта.
  • Выполните разделение этих продуктов, начиная с самой низкой степени. (который завершается)
  • Сдвиньте полиномиальное (евклидовое подразделение на $ x^k $, сохраняя коэффициент и сбрасывая оставшуюся часть)

И вы сделали. Теперь у вашего многочлена есть количество способов взвесить $ w ge 0 $ по индексу $ w $. Единственный вход - это мультисет масс $ m $.

Я разработал алгоритм, используя математические звуковые компоненты. Основная часть алгоритма, которая является полиномиальным делением с самой низкой степенью, является линейной и может быть реализована с помощью готового пакета. Это может быть не оптимальным, но, безусловно, работает лучше, чем то, что я делал на конкурсе, и менее подверженным ошибкам.

Если вы внимательно посмотрите на процесс дивизии, вы быстро увидите, что оставшаяся часть может рассматриваться как «текущее скрытое состояние» в каждом состоянии процесса, а также коэффициент в качестве результата. Процесс заканчивается, когда «текущее скрытое состояние» везде достигает нуля.

Вы можете реализовать полиномы в качестве массивов или, если они действительно очень скудны, в качестве списков упорядоченного индексного коэффициента, и это не изменит алгоритм.

При разработке алгоритм Для максимизации монотонного подмодуля над матроидом мы должны были решить рецидив $$ ell gamma^{(m)} _ { ell+1} = (2 ell-m) gamma^{(m)} _ ell + (m - ell + 1) gamma^{(m)} _ { ell -1}, Quad gamma^{(m)} _ 0 = 1, Quad gamma^{(m) } _ {m+1} = e. $$ после того, как заметил, что $ gamma^{(m)} _ elll = m ( gamma^{(m-1)} _ ell- gamma^{(m-1)} _ { elll-1 }) $, мы уменьшили проблему для вычисления какой -либо универсальной последовательности $ gamma^{(0)} $. Последний был выполнен с использованием генерирующих функций, и оттуда мы получили явную формулу для $ gamma^{(m)} $, опять же, используя генерирующие функции. Вы можете найти решение в бумаге, если вам любопытно, хотя мы никогда не удосужились включить этот вывод.

Возможно, обширное исследование QuickSort и его многочисленных вариантов является самым ярким примером. Там комбинаторные соображения определяли рассмотрение альтернатив, и анализ решений довольно сложных уравнений показывает преимущества эффективности (или нет) из них.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с cs.stackexchange
scroll top