Примеры сложных рекурсивных алгоритмов

14

Я объяснял известный детерминистический алгоритм линейного выбора времени ( алгоритм медианы медиан) другу.

Рекурсия в этом алгоритме (хотя и очень проста) довольно сложна. Есть два рекурсивных вызова, каждый с разными параметрами.

Я пытался найти другие примеры таких интересных рекурсивных алгоритмов, но не смог найти ни одного. Все рекурсивные алгоритмы, которые я мог придумать, являются либо простыми хвостовыми рекурсиями, либо простыми «разделяй и властвуй» (где два вызова «одинаковы»).

Можете ли вы привести несколько примеров сложной рекурсии?

elektronaj
источник
Обход лабиринта или, в более общем смысле, графика с поиском в ширину - простой пример интересной рекурсии.
Я думаю, что BFS не подходит для моего вопроса, так как он может быть легко и естественно реализован с использованием очереди и цикла while.
электронай
Как насчет возврата в решении головоломок и разбора? А алгоритмы ранжирования и отмены рейтинга также имеют нестандартные рекурсии.
Uli
Алгоритмы мемоизации ?
Каве
2
@vzn: очередь не может заменить стек. BFS это особый случай.
Рафаэль

Ответы:

15

Мое любимое повторение проявляется в чувствительных к выходу алгоритмах для вычисления выпуклых оболочек, сначала Киркпатрика и Зайделя , но позже повторенных другими. Обозначим через время вычисления выпуклой оболочки из n точек на плоскости, когда выпуклая оболочка имеет h вершин. (Значение h заранее неизвестно, кроме тривиальной границы h n .) Алгоритм Киркпатрика и Зайделя дает рекуррентность T ( n , h ) = { O ( n ), если T(n,h)nhhhn гдеn1,n23n/4иn1+n2=nиh1+h2=h.

T(n,h)={O(n)if n3 or h3T(n1,h1)+T(n2,h2)+O(n)otherwise
n1,n23n/4n1+n2=nh1+h2=h

Решение . Это немного удивительно, поскольку h не является параметром, делимым равномерно. Но на самом деле, наихудший случай рецидива случается, когда h 1 и h 2 равны h / 2 ; если каким-то волшебным образом h 1 всегда постоянен, решение будет T ( n , h ) = O ( n ) .T(n,h)=O(nlogh)hh1h2h/2h1T(n,h)=O(n)

Я использовал вариант этого повторения в одной из моих первых работ по вычислительной топологии : где

T(N,грамм)знак равно{О(N)если N3 или граммзнак равно0T(N1,грамм1)+T(N2,грамм2)+О(мин{N1,N2})в противном случае
и g 1 + g 2 = g . Опять же, решением является O ( n log g ) , инаихудшийслучай возникает, когда n и g всегда делятся равномерно.n1+n2=ng1+g2=gO(nlogg)ng
JeffE
источник
У меня проблемы с условием "если или h = O ( 1 ) "; что О здесь означает? Существуют ли глобально ограничивающие константы, которые n и h должны быть подрезаны, чтобы в конечном итоге попасть в один (и авторы не удосуживаются дать их). Потому что, если я читаю это буквально (то есть интерпретирую оба O ( 1 ) так же, как O ( n ) в одной строке), случай два никогда не случается или не происходит всегда (я даже не уверен). Злоупотребление обозначениями зашло слишком далеко, imho. n=O(1)h=O(1)OnhO(1)O(n)
Рафаэль
1
Извините, я отредактировал свой ответ, чтобы уточнить. означало «ваша любимая константа». Я использовал 3 в моей ревизии, но 10 10 100 ! работал бы так же хорошо. O(1)31010100!
Джефф
Как вы нарисовали эти диаграммы в работах по вычислительной топологии?
user119264
12

Рекурсия, которую я использовал в своей статье «Алгоритм линейного времени для вычисления диаграммы Вороного выпуклого многоугольника» Аггарвала и др. , Также довольно сложна.

Вот описание алгоритма из нашей статьи. В случае, если из описания не ясно, на шаге 3 красные точки делятся на алые и гранатовые. Шаги 1, 3 и 6 - все линейное время. Мы также знаем, что если - общее количество точек, | Б | α n , | R | β n и | C | γ n для некоторого α , β , γ > 0 .n|B|αn|R|βn|C|γnα,β,γ>0

Я дам вам понять, почему весь алгоритм занимает линейное время.

  1. Разбейте исходные точки на синие и красные множества B и R.
  2. Рекурсивно вычислить выпуклую оболочку синих точек.
  3. Используя структуру синего корпуса, выберите малиновые точки C.
  4. Добавляйте багровые точки в синий корпус по одному.
  5. Рекурсивно вычисляют выпуклую оболочку гранатовых точек G.
  6. Объедините этот гранатовый корпус с расширенным синим корпусом шага 4.

Что делает алгоритм линейным, так это возможность добавлять фиксированную долю красных точек к синему корпусу при постоянных затратах на точку. Добавленные очки - это багровые очки.

T(n)=T(|B|)+T(|G|)+O(n)
|B||G||B|+|G|(1γ)n
Питер Шор
источник
7

Существует изменение в повторении медианного нахождения, которое исходит от поиска дальности с полуплоскостями. Само повторение имеет форму

что похоже на повторение по медиане. Подробнее об этом, см наконспектах Джеффа Эриксонаив частности Раздела 4.

T(n)=T(n/2)+T(n/4)+cn
Суреш
источник
1
Мой ответ здесь ( cs.stackexchange.com/questions/332/… ), оказывается, имеет то же самое повторение для его времени выполнения :)
Алекс тен Бринк
6

Существует множество классных рекурсивных алгоритмов [1], [2], используемых при прогнозировании вторичной структуры РНК. Оставленный на свое усмотрение, нить РНК будет образовывать пары оснований с самим собой; один сравнительно простой пример из [3] вычисляет максимальное количество вложенных парных баз, с которыми будет образовываться строка РНК:

M(i,j)=maxik<jLmin{M(i,k1)+M(k+1,j1)+1M(i,j1)


  1. Оптимальное компьютерное свертывание больших последовательностей РНК с использованием термодинамики и вспомогательной информации М. Цукера, П. Штиглера (1981)

  2. Алгоритм динамического программирования для прогнозирования структуры РНК, включающей псевдоузлы , Э. Ривас, С.Р. Эдди (1999)

  3. Быстрый алгоритм для предсказания вторичной структуры одноцепочечной РНК Р. Нусинов, А. Б. Якобсон (1980)

rphv
источник
Предложенный здесь связанный довольно сложный процесс, поскольку он содержит три взаимозависимых рекурсии (динамическое программирование).
Рафаэль
4

Я до сих пор не совсем понимаю, что вы имеете в виду под «сложной рекурсией». Например, шаг рекурсии в алгоритме FFT является сложным!

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

Dai
источник
Что ж, рекурсия в БПФ (простейшая форма Кули-Тьюки) - это «стандартная» разделяй и властвуй. Это очевидно из его сложности O (nlogn). 2 рекурсивных вызова (1 для четного, 1 для шансов) несколько «одинаковы».
электронай